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