interface-descriptors-arm.cc 12.5 KB
Newer Older
1 2 3 4
// 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.

5 6
#include "src/arm/interface-descriptors-arm.h"

7 8 9 10 11 12 13
#if V8_TARGET_ARCH_ARM

#include "src/interface-descriptors.h"

namespace v8 {
namespace internal {

14
const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
15

16 17 18 19 20 21 22 23
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
    CallInterfaceDescriptorData* data, int register_parameter_count) {
  const Register default_stub_registers[] = {r0, r1, r2, r3, r4};
  CHECK_LE(static_cast<size_t>(register_parameter_count),
           arraysize(default_stub_registers));
  data->InitializePlatformSpecific(register_parameter_count,
                                   default_stub_registers);
}
24

25 26
void RecordWriteDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
27 28 29 30 31 32 33 34
  const Register default_stub_registers[] = {r0, r1, r2, r3, r4};

  data->RestrictAllocatableRegisters(default_stub_registers,
                                     arraysize(default_stub_registers));

  CHECK_LE(static_cast<size_t>(kParameterCount),
           arraysize(default_stub_registers));
  data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
35 36
}

37 38 39 40 41
const Register FastNewFunctionContextDescriptor::FunctionRegister() {
  return r1;
}
const Register FastNewFunctionContextDescriptor::SlotsRegister() { return r0; }

42 43
const Register LoadDescriptor::ReceiverRegister() { return r1; }
const Register LoadDescriptor::NameRegister() { return r2; }
44
const Register LoadDescriptor::SlotRegister() { return r0; }
45

46
const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
47

48
const Register LoadICProtoArrayDescriptor::HandlerRegister() { return r4; }
49 50 51 52

const Register StoreDescriptor::ReceiverRegister() { return r1; }
const Register StoreDescriptor::NameRegister() { return r2; }
const Register StoreDescriptor::ValueRegister() { return r0; }
53
const Register StoreDescriptor::SlotRegister() { return r4; }
54

55
const Register StoreWithVectorDescriptor::VectorRegister() { return r3; }
56

57 58 59
const Register StoreTransitionDescriptor::SlotRegister() { return r4; }
const Register StoreTransitionDescriptor::VectorRegister() { return r3; }
const Register StoreTransitionDescriptor::MapRegister() { return r5; }
60

61 62 63
const Register StringCompareDescriptor::LeftRegister() { return r1; }
const Register StringCompareDescriptor::RightRegister() { return r0; }

64 65
const Register ApiGetterDescriptor::HolderRegister() { return r0; }
const Register ApiGetterDescriptor::CallbackRegister() { return r3; }
66

67 68 69 70 71
const Register MathPowTaggedDescriptor::exponent() { return r2; }

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


74 75 76 77
const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }


78 79
void FastNewClosureDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
80
  Register registers[] = {r1, r2, r3};
81
  data->InitializePlatformSpecific(arraysize(registers), registers);
82 83
}

84
// static
85
const Register TypeConversionDescriptor::ArgumentRegister() { return r0; }
86

87 88
void TypeofDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
89
  Register registers[] = {r3};
90
  data->InitializePlatformSpecific(arraysize(registers), registers);
91 92
}

93 94
void CallFunctionDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
95
  Register registers[] = {r1};
96
  data->InitializePlatformSpecific(arraysize(registers), registers);
97 98
}

99 100 101 102 103 104 105 106
void CallTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments
  // r1 : the target to call
  Register registers[] = {r1, r0};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

107 108 109 110 111 112 113 114 115 116
void CallVarargsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments (on the stack, not including receiver)
  // r1 : the target to call
  // r2 : arguments list (FixedArray)
  // r4 : arguments list length (untagged)
  Register registers[] = {r1, r0, r2, r4};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

117 118
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
119 120 121 122 123 124 125
  // r0 : number of arguments
  // r2 : start index (to support rest parameters)
  // r1 : the target to call
  Register registers[] = {r1, r0, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

126 127 128 129 130 131 132 133 134
void CallWithSpreadDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments (on the stack, not including receiver)
  // r1 : the target to call
  // r2 : the object to spread
  Register registers[] = {r1, r0, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r1 : the target to call
  // r2 : the arguments list
  Register registers[] = {r1, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

void ConstructVarargsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments (on the stack, not including receiver)
  // r1 : the target to call
  // r3 : the new target
  // r2 : arguments list (FixedArray)
  // r4 : arguments list length (untagged)
  Register registers[] = {r1, r3, r0, r2, r4};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

154 155 156 157
void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments
  // r3 : the new target
158 159
  // r2 : start index (to support rest parameters)
  // r1 : the target to call
160
  Register registers[] = {r1, r3, r0, r2};
161 162
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
163

164 165 166 167 168 169 170 171 172 173
void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments (on the stack, not including receiver)
  // r1 : the target to call
  // r3 : the new target
  // r2 : the object to spread
  Register registers[] = {r1, r3, r0, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

174 175 176 177 178 179 180 181 182
void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r1 : the target to call
  // r3 : the new target
  // r2 : the arguments list
  Register registers[] = {r1, r3, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

183 184 185 186 187 188 189 190 191 192 193
void ConstructStubDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments
  // r1 : the target to call
  // r3 : the new target
  // r2 : allocation site or undefined
  Register registers[] = {r1, r3, r0, r2};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


194 195 196 197 198 199 200 201 202 203
void ConstructTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // r0 : number of arguments
  // r1 : the target to call
  // r3 : the new target
  Register registers[] = {r1, r3, r0};
  data->InitializePlatformSpecific(arraysize(registers), registers);
}


204
void TransitionElementsKindDescriptor::InitializePlatformSpecific(
205
    CallInterfaceDescriptorData* data) {
206
  Register registers[] = {r0, r1};
207
  data->InitializePlatformSpecific(arraysize(registers), registers);
208 209 210
}


211
void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
212
    CallInterfaceDescriptorData* data) {
213
  data->InitializePlatformSpecific(0, nullptr, nullptr);
214 215
}

216 217 218 219
void ArrayConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // kTarget, kNewTarget, kActualArgumentsCount, kAllocationSite
  Register registers[] = {r1, r3, r0, r2};
220
  data->InitializePlatformSpecific(arraysize(registers), registers, nullptr);
221 222
}

223 224 225 226 227 228 229
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  // register state
  // r0 -- number of arguments
  // r1 -- function
  // r2 -- allocation site with elements kind
  Register registers[] = {r1, r2, r0};
230
  data->InitializePlatformSpecific(arraysize(registers), registers, nullptr);
231 232
}

233
void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
234
    CallInterfaceDescriptorData* data) {
235 236 237 238
  // register state
  // r0 -- number of arguments
  // r1 -- function
  // r2 -- allocation site with elements kind
239
  Register registers[] = {r1, r2, r0};
240
  data->InitializePlatformSpecific(arraysize(registers), registers, nullptr);
241 242
}

243
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
244
    CallInterfaceDescriptorData* data) {
245
  // stack param count needs (constructor pointer, and single argument)
246
  Register registers[] = {r1, r2, r0};
247
  data->InitializePlatformSpecific(arraysize(registers), registers);
248 249
}

250 251
void CompareDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
252
  Register registers[] = {r1, r0};
253
  data->InitializePlatformSpecific(arraysize(registers), registers);
254 255 256
}


257 258
void BinaryOpDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
259
  Register registers[] = {r1, r0};
260
  data->InitializePlatformSpecific(arraysize(registers), registers);
261 262
}

263 264
void StringAddDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
265
  Register registers[] = {r1, r0};
266
  data->InitializePlatformSpecific(arraysize(registers), registers);
267 268
}

269 270
void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
271 272 273 274 275
  static PlatformInterfaceDescriptor default_descriptor =
      PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);

  Register registers[] = {
      r1,  // JSFunction
276
      r3,  // the new target
277 278 279
      r0,  // actual number of arguments
      r2,  // expected number of arguments
  };
280 281
  data->InitializePlatformSpecific(arraysize(registers), registers,
                                   &default_descriptor);
282 283
}

284
void ApiCallbackDescriptor::InitializePlatformSpecific(
285
    CallInterfaceDescriptorData* data) {
286 287 288
  static PlatformInterfaceDescriptor default_descriptor =
      PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);

289 290 291 292 293 294
  Register registers[] = {
      r0,  // callee
      r4,  // call_data
      r2,  // holder
      r1,  // api_function_address
  };
295 296
  data->InitializePlatformSpecific(arraysize(registers), registers,
                                   &default_descriptor);
297
}
298

299 300 301
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
302 303
      kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
      kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
304 305
  data->InitializePlatformSpecific(arraysize(registers), registers);
}
306

307
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
308 309
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
310
      r0,  // argument count (not including receiver)
311 312 313 314 315 316
      r2,  // address of first argument
      r1   // the target callable to be call
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

317
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
318 319 320
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      r0,  // argument count (not including receiver)
321
      r3,  // new target
322
      r1,  // constructor to call
323 324
      r2,  // allocation site feedback if available, undefined otherwise
      r4   // address of the first argument
325 326
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
327 328
}

329 330 331 332 333 334 335 336 337 338
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      r0,  // argument count (argc)
      r2,  // address of first argument (argv)
      r1   // the runtime function to call
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

339 340 341 342 343
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      r0,  // the value to pass to the generator
      r1,  // the JSGeneratorObject to resume
344
      r2   // the resume mode (tagged)
345 346 347 348
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

349 350 351 352 353 354 355 356
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
    CallInterfaceDescriptorData* data) {
  Register registers[] = {
      r1,  // loaded new FP
  };
  data->InitializePlatformSpecific(arraysize(registers), registers);
}

357 358
}  // namespace internal
}  // namespace v8
359 360

#endif  // V8_TARGET_ARCH_ARM