interface-descriptors-x64.cc 13.7 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 17 18 19 20 21
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
    CallInterfaceDescriptorData* data, int register_parameter_count) {
  const Register default_stub_registers[] = {rax, rbx, rcx, rdx, rdi};
  CHECK_LE(static_cast<size_t>(register_parameter_count),
           arraysize(default_stub_registers));
  data->InitializePlatformSpecific(register_parameter_count,
                                   default_stub_registers);
}
22

23 24 25 26 27
const Register FastNewFunctionContextDescriptor::FunctionRegister() {
  return rdi;
}
const Register FastNewFunctionContextDescriptor::SlotsRegister() { return rax; }

28 29
const Register LoadDescriptor::ReceiverRegister() { return rdx; }
const Register LoadDescriptor::NameRegister() { return rcx; }
30
const Register LoadDescriptor::SlotRegister() { return rax; }
31

32
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
33

34
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return rdi; }
35 36 37 38

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

41
const Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
42

43 44 45
const Register StoreTransitionDescriptor::SlotRegister() { return rdi; }
const Register StoreTransitionDescriptor::VectorRegister() { return rbx; }
const Register StoreTransitionDescriptor::MapRegister() { return r11; }
46

47 48 49
const Register StringCompareDescriptor::LeftRegister() { return rdx; }
const Register StringCompareDescriptor::RightRegister() { return rax; }

50 51
const Register ApiGetterDescriptor::HolderRegister() { return rcx; }
const Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
52

53 54 55 56 57
const Register MathPowTaggedDescriptor::exponent() { return rdx; }

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

59 60 61 62 63
const Register RegExpExecDescriptor::StringRegister() { return arg_reg_1; }
const Register RegExpExecDescriptor::LastIndexRegister() { return r11; }
const Register RegExpExecDescriptor::StringStartRegister() { return arg_reg_3; }
const Register RegExpExecDescriptor::StringEndRegister() { return arg_reg_4; }
const Register RegExpExecDescriptor::CodeRegister() { return rax; }
64

65 66 67 68
const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }


69 70
void FastNewClosureDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
71 72
  // SharedFunctionInfo, vector, slot index.
  Register registers[] = {rbx, rcx, rdx};
73
  data->InitializePlatformSpecific(arraysize(registers), registers);
74 75
}

76 77
void TypeofDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
78
  Register registers[] = {rbx};
79
  data->InitializePlatformSpecific(arraysize(registers), registers);
80 81 82
}


83
// static
84
const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
85

86 87 88 89 90 91 92
void FastCloneRegExpDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rdi, rax, rcx, rdx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


93
void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
94
    CallInterfaceDescriptorData* data) {
95
  Register registers[] = {rax, rbx, rcx};
96
  data->InitializePlatformSpecific(arraysize(registers), registers);
97 98 99
}


100
void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
101
    CallInterfaceDescriptorData* data) {
102
  Register registers[] = {rax, rbx, rcx, rdx};
103
  data->InitializePlatformSpecific(arraysize(registers), registers);
104 105 106
}


107
void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
108
    CallInterfaceDescriptorData* data) {
109
  Register registers[] = {rbx, rdx};
110
  data->InitializePlatformSpecific(arraysize(registers), registers);
111 112 113
}


114 115
void CreateWeakCellDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
116
  Register registers[] = {rbx, rdx, rdi};
117
  data->InitializePlatformSpecific(arraysize(registers), registers);
118 119 120
}


121 122
void CallFunctionDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
123
  Register registers[] = {rdi};
124
  data->InitializePlatformSpecific(arraysize(registers), registers);
125 126
}

127
void CallICTrampolineDescriptor::InitializePlatformSpecific(
128
    CallInterfaceDescriptorData* data) {
129
  Register registers[] = {rdi, rax, rdx};
130
  data->InitializePlatformSpecific(arraysize(registers), registers);
131 132
}

133
void CallICDescriptor::InitializePlatformSpecific(
134
    CallInterfaceDescriptorData* data) {
135
  Register registers[] = {rdi, rax, rdx, rbx};
136
  data->InitializePlatformSpecific(arraysize(registers), registers);
137 138 139
}


140
void CallConstructDescriptor::InitializePlatformSpecific(
141
    CallInterfaceDescriptorData* data) {
142 143
  // rax : number of arguments
  // rbx : feedback vector
144
  // rdx : slot in feedback vector (Smi, for RecordCallTarget)
145 146 147
  // 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.
148
  Register registers[] = {rax, rdi, rbx};
149
  data->InitializePlatformSpecific(arraysize(registers), registers);
150 151 152
}


153 154 155 156 157 158 159 160
void CallTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // rax : number of arguments
  // rdi : the target to call
  Register registers[] = {rdi, rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

161 162 163 164 165 166 167
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // rcx : start index (to support rest parameters)
  // rdi : the target to call
  Register registers[] = {rdi, rcx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
168

169 170 171 172 173 174 175 176 177 178 179
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);
}


180 181 182 183 184 185 186 187 188 189
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);
}


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


197
void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
198
    CallInterfaceDescriptorData* data) {
199
  data->InitializePlatformSpecific(0, nullptr, nullptr);
200 201
}

202 203 204 205 206 207 208
void ArrayConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
  Register registers[] = {rdi, rdx, rax, rbx};
  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}

209 210 211 212 213 214 215 216 217 218
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // register state
  // rax -- number of arguments
  // rdi -- function
  // rbx -- allocation site with elements kind
  Register registers[] = {rdi, rbx, rax};
  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
}

219
void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
220
    CallInterfaceDescriptorData* data) {
221 222 223 224
  // register state
  // rax -- number of arguments
  // rdi -- function
  // rbx -- allocation site with elements kind
225 226
  Register registers[] = {rdi, rbx, rax};
  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
227 228
}

229
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
230
    CallInterfaceDescriptorData* data) {
231 232 233 234
  // register state
  // rax -- number of arguments
  // rdi -- function
  // rbx -- allocation site with elements kind
235
  Register registers[] = {rdi, rbx, rax};
236
  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
237 238
}

239
void VarArgFunctionDescriptor::InitializePlatformSpecific(
240 241 242 243 244
    CallInterfaceDescriptorData* data) {
  // stack param count needs (arg count)
  Register registers[] = {rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
245

246 247
void CompareDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
248
  Register registers[] = {rdx, rax};
249
  data->InitializePlatformSpecific(arraysize(registers), registers);
250 251 252
}


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


260
void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
261
    CallInterfaceDescriptorData* data) {
262
  Register registers[] = {rcx, rdx, rax};
263
  data->InitializePlatformSpecific(arraysize(registers), registers);
264 265
}

266 267 268 269 270 271 272 273 274 275 276
void BinaryOpWithVectorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // register state
  // rdx -- lhs
  // rax -- rhs
  // rdi -- slot id
  // rbx -- vector
  Register registers[] = {rdx, rax, rdi, rbx};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

277 278 279 280 281
void CountOpDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {rax};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
282

283 284
void StringAddDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
285
  Register registers[] = {rdx, rax};
286
  data->InitializePlatformSpecific(arraysize(registers), registers);
287 288 289
}


290 291
void KeyedDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
292 293 294
  Register registers[] = {
      rcx,  // key
  };
295
  data->InitializePlatformSpecific(arraysize(registers), registers);
296 297 298
}


299 300
void NamedDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
301 302 303
  Register registers[] = {
      rcx,  // name
  };
304
  data->InitializePlatformSpecific(arraysize(registers), registers);
305 306 307
}


308 309
void CallHandlerDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
310 311 312
  Register registers[] = {
      rdx,  // receiver
  };
313
  data->InitializePlatformSpecific(arraysize(registers), registers);
314 315 316
}


317 318
void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
319 320
  Register registers[] = {
      rdi,  // JSFunction
321
      rdx,  // the new target
322 323 324
      rax,  // actual number of arguments
      rbx,  // expected number of arguments
  };
325
  data->InitializePlatformSpecific(arraysize(registers), registers);
326 327
}

328
void ApiCallbackDescriptor::InitializePlatformSpecific(
329
    CallInterfaceDescriptorData* data) {
330
  Register registers[] = {
331
      rdi,  // callee
332 333 334 335
      rbx,  // call_data
      rcx,  // holder
      rdx,  // api_function_address
  };
336
  data->InitializePlatformSpecific(arraysize(registers), registers);
337
}
338

339 340 341
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
342 343
      kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
      kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
344 345
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
346

347
void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
348 349
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
350
      rax,  // argument count (not including receiver)
351 352 353 354 355 356
      rbx,  // address of first argument
      rdi   // the target callable to be call
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

357 358 359 360
void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rax,  // argument count (not including receiver)
361
      rdx,  // new target
362
      rdi,  // constructor
363 364
      rbx,  // allocation site feedback if available, undefined otherwise
      rcx,  // address of first argument
365 366 367 368
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

369 370 371 372 373 374 375 376 377 378 379
void InterpreterPushArgsAndConstructArrayDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rax,  // argument count (not including receiver)
      rdx,  // target to the call. It is checked to be Array function.
      rbx,  // allocation site feedback
      rcx,  // address of first argument
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

380 381 382 383 384 385 386 387 388 389
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);
}

390 391 392 393 394 395 396 397 398 399
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rax,  // the value to pass to the generator
      rbx,  // the JSGeneratorObject to resume
      rdx   // the resume mode (tagged)
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

400 401 402 403 404 405 406 407
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      rbx,  // loaded new FP
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

408 409
}  // namespace internal
}  // namespace v8
410 411

#endif  // V8_TARGET_ARCH_X64