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