interface-descriptors-x64.cc 13.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#if V8_TARGET_ARCH_X64

#include "src/interface-descriptors.h"

namespace v8 {
namespace internal {

12
const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
13 14


15 16
const Register LoadDescriptor::ReceiverRegister() { return rdx; }
const Register LoadDescriptor::NameRegister() { return rcx; }
17
const Register LoadDescriptor::SlotRegister() { return rax; }
18 19


20
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
21 22 23 24 25 26 27


const Register StoreDescriptor::ReceiverRegister() { return rdx; }
const Register StoreDescriptor::NameRegister() { return rcx; }
const Register StoreDescriptor::ValueRegister() { return rax; }


28 29 30 31 32 33
const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return rdi; }


const Register VectorStoreICDescriptor::VectorRegister() { return rbx; }


34 35 36 37 38
const Register VectorStoreTransitionDescriptor::SlotRegister() { return rdi; }
const Register VectorStoreTransitionDescriptor::VectorRegister() { return rbx; }
const Register VectorStoreTransitionDescriptor::MapRegister() { return r11; }


39
const Register StoreTransitionDescriptor::MapRegister() { return rbx; }
40 41


42 43 44 45 46 47 48
const Register LoadGlobalViaContextDescriptor::SlotRegister() { return rbx; }


const Register StoreGlobalViaContextDescriptor::SlotRegister() { return rbx; }
const Register StoreGlobalViaContextDescriptor::ValueRegister() { return rax; }


49 50
const Register InstanceOfDescriptor::LeftRegister() { return rdx; }
const Register InstanceOfDescriptor::RightRegister() { return rax; }
51 52


53 54 55 56
const Register StringCompareDescriptor::LeftRegister() { return rdx; }
const Register StringCompareDescriptor::RightRegister() { return rax; }


57
const Register ApiGetterDescriptor::function_address() { return r8; }
58 59


60 61 62 63 64 65
const Register MathPowTaggedDescriptor::exponent() { return rdx; }


const Register MathPowIntegerDescriptor::exponent() {
  return MathPowTaggedDescriptor::exponent();
}
66 67


68 69 70 71
const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }


72 73
void FastNewClosureDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
74
  Register registers[] = {rbx};
75
  data->InitializePlatformSpecific(arraysize(registers), registers);
76 77 78
}


79 80
void FastNewContextDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
81
  Register registers[] = {rdi};
82
  data->InitializePlatformSpecific(arraysize(registers), registers);
83 84
}

85 86 87 88 89
void FastNewObjectDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi, rdx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
90

91 92 93 94 95 96
void FastNewRestParameterDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

97 98 99 100 101 102
void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

103 104 105 106 107 108
void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

109

110 111
void TypeofDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
112
  Register registers[] = {rbx};
113
  data->InitializePlatformSpecific(arraysize(registers), registers);
114 115 116
}


117 118
void ToNumberDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
119
  // ToNumberStub invokes a function, and therefore needs a context.
120
  Register registers[] = {rax};
121
  data->InitializePlatformSpecific(arraysize(registers), registers);
122 123 124
}


125 126 127 128
// static
const Register ToLengthDescriptor::ReceiverRegister() { return rax; }


129 130 131 132
// static
const Register ToStringDescriptor::ReceiverRegister() { return rax; }


133 134 135 136
// static
const Register ToNameDescriptor::ReceiverRegister() { return rax; }


137 138 139 140
// static
const Register ToObjectDescriptor::ReceiverRegister() { return rax; }


141 142
void NumberToStringDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
143
  Register registers[] = {rax};
144
  data->InitializePlatformSpecific(arraysize(registers), registers);
145 146 147
}


148 149 150 151 152 153 154
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi, rax, rcx, rdx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


155
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
156
    CallInterfaceDescriptorData* data) {
157
  Register registers[] = {rax, rbx, rcx};
158
  data->InitializePlatformSpecific(arraysize(registers), registers);
159 160 161
}


162
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
163
    CallInterfaceDescriptorData* data) {
164
  Register registers[] = {rax, rbx, rcx, rdx};
165
  data->InitializePlatformSpecific(arraysize(registers), registers);
166 167 168
}


169
void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
170
    CallInterfaceDescriptorData* data) {
171
  Register registers[] = {rbx, rdx};
172
  data->InitializePlatformSpecific(arraysize(registers), registers);
173 174 175
}


176 177
void CreateWeakCellDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
178
  Register registers[] = {rbx, rdx, rdi};
179
  data->InitializePlatformSpecific(arraysize(registers), registers);
180 181 182
}


183 184
void CallFunctionDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
185
  Register registers[] = {rdi};
186
  data->InitializePlatformSpecific(arraysize(registers), registers);
187 188 189
}


190
void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
191
    CallInterfaceDescriptorData* data) {
192
  Register registers[] = {rdi, rdx};
193
  data->InitializePlatformSpecific(arraysize(registers), registers);
194 195 196
}


197
void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
198
    CallInterfaceDescriptorData* data) {
199
  Register registers[] = {rdi, rdx, rbx};
200
  data->InitializePlatformSpecific(arraysize(registers), registers);
201 202 203
}


204
void CallConstructDescriptor::InitializePlatformSpecific(
205
    CallInterfaceDescriptorData* data) {
206 207
  // rax : number of arguments
  // rbx : feedback vector
208
  // rdx : slot in feedback vector (Smi, for RecordCallTarget)
209 210 211
  // rdi : constructor function
  // TODO(turbofan): So far we don't gather type feedback and hence skip the
  // slot parameter, but ArrayConstructStub needs the vector to be undefined.
212
  Register registers[] = {rax, rdi, rbx};
213
  data->InitializePlatformSpecific(arraysize(registers), registers);
214 215 216
}


217 218 219 220 221 222 223 224 225
void CallTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // rax : number of arguments
  // rdi : the target to call
  Register registers[] = {rdi, rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


226 227 228 229 230 231 232 233 234 235 236
void ConstructStubDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // rax : number of arguments
  // rdx : the new target
  // rdi : the target to call
  // rbx : allocation site or undefined
  Register registers[] = {rdi, rdx, rax, rbx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


237 238 239 240 241 242 243 244 245 246
void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // rax : number of arguments
  // rdx : the new target
  // rdi : the target to call
  Register registers[] = {rdi, rdx, rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


247
void RegExpConstructResultDescriptor::InitializePlatformSpecific(
248
    CallInterfaceDescriptorData* data) {
249
  Register registers[] = {rcx, rbx, rax};
250
  data->InitializePlatformSpecific(arraysize(registers), registers);
251 252 253
}


254
void TransitionElementsKindDescriptor::InitializePlatformSpecific(
255
    CallInterfaceDescriptorData* data) {
256
  Register registers[] = {rax, rbx};
257
  data->InitializePlatformSpecific(arraysize(registers), registers);
258 259 260
}


261
void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
262
    CallInterfaceDescriptorData* data) {
263
  data->InitializePlatformSpecific(0, nullptr, nullptr);
264 265 266
}


267 268 269 270 271 272 273
void AllocateInNewSpaceDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


274
void ArrayConstructorConstantArgCountDescriptor::InitializePlatformSpecific(
275
    CallInterfaceDescriptorData* data) {
276 277 278 279
  // register state
  // rax -- number of arguments
  // rdi -- function
  // rbx -- allocation site with elements kind
280
  Register registers[] = {rdi, rbx};
281
  data->InitializePlatformSpecific(arraysize(registers), registers);
282 283 284
}


285 286
void ArrayConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
287
  // stack param count needs (constructor pointer, and single argument)
288
  Register registers[] = {rdi, rbx, rax};
289
  data->InitializePlatformSpecific(arraysize(registers), registers);
290 291 292
}


293 294
void InternalArrayConstructorConstantArgCountDescriptor::
    InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
295 296 297
  // register state
  // rax -- number of arguments
  // rdi -- constructor function
298
  Register registers[] = {rdi};
299
  data->InitializePlatformSpecific(arraysize(registers), registers);
300 301 302
}


303
void InternalArrayConstructorDescriptor::InitializePlatformSpecific(
304
    CallInterfaceDescriptorData* data) {
305
  // stack param count needs (constructor pointer, and single argument)
306
  Register registers[] = {rdi, rax};
307
  data->InitializePlatformSpecific(arraysize(registers), registers);
308 309 310
}


311 312
void CompareDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
313
  Register registers[] = {rdx, rax};
314
  data->InitializePlatformSpecific(arraysize(registers), registers);
315 316 317
}


318 319
void ToBooleanDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
320
  Register registers[] = {rax};
321
  data->InitializePlatformSpecific(arraysize(registers), registers);
322 323 324
}


325 326
void BinaryOpDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
327
  Register registers[] = {rdx, rax};
328
  data->InitializePlatformSpecific(arraysize(registers), registers);
329 330 331
}


332
void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
333
    CallInterfaceDescriptorData* data) {
334
  Register registers[] = {rcx, rdx, rax};
335
  data->InitializePlatformSpecific(arraysize(registers), registers);
336 337 338
}


339 340
void StringAddDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
341
  Register registers[] = {rdx, rax};
342
  data->InitializePlatformSpecific(arraysize(registers), registers);
343 344 345
}


346 347
void KeyedDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
348 349 350
  Register registers[] = {
      rcx,  // key
  };
351
  data->InitializePlatformSpecific(arraysize(registers), registers);
352 353 354
}


355 356
void NamedDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
357 358 359
  Register registers[] = {
      rcx,  // name
  };
360
  data->InitializePlatformSpecific(arraysize(registers), registers);
361 362 363
}


364 365
void CallHandlerDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
366 367 368
  Register registers[] = {
      rdx,  // receiver
  };
369
  data->InitializePlatformSpecific(arraysize(registers), registers);
370 371 372
}


373 374
void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
375 376
  Register registers[] = {
      rdi,  // JSFunction
377
      rdx,  // the new target
378 379 380
      rax,  // actual number of arguments
      rbx,  // expected number of arguments
  };
381
  data->InitializePlatformSpecific(arraysize(registers), registers);
382 383
}

vogelheim's avatar
vogelheim committed
384
void ApiCallbackDescriptorBase::InitializePlatformSpecific(
385
    CallInterfaceDescriptorData* data) {
386
  Register registers[] = {
387
      rdi,  // callee
388 389 390 391
      rbx,  // call_data
      rcx,  // holder
      rdx,  // api_function_address
  };
392
  data->InitializePlatformSpecific(arraysize(registers), registers);
393
}
394

395 396 397 398 399 400 401 402
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      kInterpreterAccumulatorRegister, kInterpreterRegisterFileRegister,
      kInterpreterBytecodeOffsetRegister, kInterpreterBytecodeArrayRegister,
      kInterpreterDispatchTableRegister};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
403

404
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
405 406
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
407
      rax,  // argument count (not including receiver)
408 409 410 411 412 413
      rbx,  // address of first argument
      rdi   // the target callable to be call
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

414 415 416 417
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rax,  // argument count (not including receiver)
418
      rdx,  // new target
419 420 421 422 423 424
      rdi,  // constructor
      rbx,  // address of first argument
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

425 426 427 428 429 430 431 432 433 434
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rax,  // argument count (argc)
      r15,  // address of first argument (argv)
      rbx   // the runtime function to call
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

435 436
}  // namespace internal
}  // namespace v8
437 438

#endif  // V8_TARGET_ARCH_X64