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 #include "src/v8.h"
6 
7 #if V8_TARGET_ARCH_X64
8 
9 #include "src/interface-descriptors.h"
10 
11 namespace v8 {
12 namespace internal {
13 
ContextRegister()14 const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
15 
16 
ReceiverRegister()17 const Register LoadDescriptor::ReceiverRegister() { return rdx; }
NameRegister()18 const Register LoadDescriptor::NameRegister() { return rcx; }
19 
20 
SlotRegister()21 const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return rax; }
22 
23 
VectorRegister()24 const Register VectorLoadICDescriptor::VectorRegister() { return rbx; }
25 
26 
ReceiverRegister()27 const Register StoreDescriptor::ReceiverRegister() { return rdx; }
NameRegister()28 const Register StoreDescriptor::NameRegister() { return rcx; }
ValueRegister()29 const Register StoreDescriptor::ValueRegister() { return rax; }
30 
31 
MapRegister()32 const Register ElementTransitionAndStoreDescriptor::MapRegister() {
33   return rbx;
34 }
35 
36 
left()37 const Register InstanceofDescriptor::left() { return rax; }
right()38 const Register InstanceofDescriptor::right() { return rdx; }
39 
40 
index()41 const Register ArgumentsAccessReadDescriptor::index() { return rdx; }
parameter_count()42 const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; }
43 
44 
function_address()45 const Register ApiGetterDescriptor::function_address() { return r8; }
46 
47 
exponent()48 const Register MathPowTaggedDescriptor::exponent() { return rdx; }
49 
50 
exponent()51 const Register MathPowIntegerDescriptor::exponent() {
52   return MathPowTaggedDescriptor::exponent();
53 }
54 
55 
Initialize(CallInterfaceDescriptorData * data)56 void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
57   Register registers[] = {rsi, rbx};
58   data->Initialize(arraysize(registers), registers, NULL);
59 }
60 
61 
Initialize(CallInterfaceDescriptorData * data)62 void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
63   Register registers[] = {rsi, rdi};
64   data->Initialize(arraysize(registers), registers, NULL);
65 }
66 
67 
Initialize(CallInterfaceDescriptorData * data)68 void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
69   // ToNumberStub invokes a function, and therefore needs a context.
70   Register registers[] = {rsi, rax};
71   data->Initialize(arraysize(registers), registers, NULL);
72 }
73 
74 
Initialize(CallInterfaceDescriptorData * data)75 void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
76   Register registers[] = {rsi, rax};
77   data->Initialize(arraysize(registers), registers, NULL);
78 }
79 
80 
Initialize(CallInterfaceDescriptorData * data)81 void FastCloneShallowArrayDescriptor::Initialize(
82     CallInterfaceDescriptorData* data) {
83   Register registers[] = {rsi, rax, rbx, rcx};
84   Representation representations[] = {
85       Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
86       Representation::Tagged()};
87   data->Initialize(arraysize(registers), registers, representations);
88 }
89 
90 
Initialize(CallInterfaceDescriptorData * data)91 void FastCloneShallowObjectDescriptor::Initialize(
92     CallInterfaceDescriptorData* data) {
93   Register registers[] = {rsi, rax, rbx, rcx, rdx};
94   data->Initialize(arraysize(registers), registers, NULL);
95 }
96 
97 
Initialize(CallInterfaceDescriptorData * data)98 void CreateAllocationSiteDescriptor::Initialize(
99     CallInterfaceDescriptorData* data) {
100   Register registers[] = {rsi, rbx, rdx};
101   data->Initialize(arraysize(registers), registers, NULL);
102 }
103 
104 
Initialize(CallInterfaceDescriptorData * data)105 void StoreArrayLiteralElementDescriptor::Initialize(
106     CallInterfaceDescriptorData* data) {
107   Register registers[] = {rsi, rcx, rax};
108   data->Initialize(arraysize(registers), registers, NULL);
109 }
110 
111 
Initialize(CallInterfaceDescriptorData * data)112 void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
113   Register registers[] = {rsi, rdi};
114   data->Initialize(arraysize(registers), registers, NULL);
115 }
116 
117 
Initialize(CallInterfaceDescriptorData * data)118 void CallFunctionWithFeedbackDescriptor::Initialize(
119     CallInterfaceDescriptorData* data) {
120   Register registers[] = {rsi, rdi, rdx};
121   Representation representations[] = {Representation::Tagged(),
122                                       Representation::Tagged(),
123                                       Representation::Smi()};
124   data->Initialize(arraysize(registers), registers, representations);
125 }
126 
127 
Initialize(CallInterfaceDescriptorData * data)128 void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
129   // rax : number of arguments
130   // rbx : feedback vector
131   // rdx : (only if rbx is not the megamorphic symbol) slot in feedback
132   //       vector (Smi)
133   // rdi : constructor function
134   // TODO(turbofan): So far we don't gather type feedback and hence skip the
135   // slot parameter, but ArrayConstructStub needs the vector to be undefined.
136   Register registers[] = {rsi, rax, rdi, rbx};
137   data->Initialize(arraysize(registers), registers, NULL);
138 }
139 
140 
Initialize(CallInterfaceDescriptorData * data)141 void RegExpConstructResultDescriptor::Initialize(
142     CallInterfaceDescriptorData* data) {
143   Register registers[] = {rsi, rcx, rbx, rax};
144   data->Initialize(arraysize(registers), registers, NULL);
145 }
146 
147 
Initialize(CallInterfaceDescriptorData * data)148 void TransitionElementsKindDescriptor::Initialize(
149     CallInterfaceDescriptorData* data) {
150   Register registers[] = {rsi, rax, rbx};
151   data->Initialize(arraysize(registers), registers, NULL);
152 }
153 
154 
Initialize(CallInterfaceDescriptorData * data)155 void ArrayConstructorConstantArgCountDescriptor::Initialize(
156     CallInterfaceDescriptorData* data) {
157   // register state
158   // rax -- number of arguments
159   // rdi -- function
160   // rbx -- allocation site with elements kind
161   Register registers[] = {rsi, rdi, rbx};
162   data->Initialize(arraysize(registers), registers, NULL);
163 }
164 
165 
Initialize(CallInterfaceDescriptorData * data)166 void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
167   // stack param count needs (constructor pointer, and single argument)
168   Register registers[] = {rsi, rdi, rbx, rax};
169   Representation representations[] = {
170       Representation::Tagged(), Representation::Tagged(),
171       Representation::Tagged(), Representation::Integer32()};
172   data->Initialize(arraysize(registers), registers, representations);
173 }
174 
175 
Initialize(CallInterfaceDescriptorData * data)176 void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
177     CallInterfaceDescriptorData* data) {
178   // register state
179   // rsi -- context
180   // rax -- number of arguments
181   // rdi -- constructor function
182   Register registers[] = {rsi, rdi};
183   data->Initialize(arraysize(registers), registers, NULL);
184 }
185 
186 
Initialize(CallInterfaceDescriptorData * data)187 void InternalArrayConstructorDescriptor::Initialize(
188     CallInterfaceDescriptorData* data) {
189   // stack param count needs (constructor pointer, and single argument)
190   Register registers[] = {rsi, rdi, rax};
191   Representation representations[] = {Representation::Tagged(),
192                                       Representation::Tagged(),
193                                       Representation::Integer32()};
194   data->Initialize(arraysize(registers), registers, representations);
195 }
196 
197 
Initialize(CallInterfaceDescriptorData * data)198 void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
199   Register registers[] = {rsi, rax};
200   data->Initialize(arraysize(registers), registers, NULL);
201 }
202 
203 
Initialize(CallInterfaceDescriptorData * data)204 void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
205   Register registers[] = {rsi, rax};
206   data->Initialize(arraysize(registers), registers, NULL);
207 }
208 
209 
Initialize(CallInterfaceDescriptorData * data)210 void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
211   Register registers[] = {rsi, rdx, rax};
212   data->Initialize(arraysize(registers), registers, NULL);
213 }
214 
215 
Initialize(CallInterfaceDescriptorData * data)216 void BinaryOpWithAllocationSiteDescriptor::Initialize(
217     CallInterfaceDescriptorData* data) {
218   Register registers[] = {rsi, rcx, rdx, rax};
219   data->Initialize(arraysize(registers), registers, NULL);
220 }
221 
222 
Initialize(CallInterfaceDescriptorData * data)223 void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
224   Register registers[] = {rsi, rdx, rax};
225   data->Initialize(arraysize(registers), registers, NULL);
226 }
227 
228 
Initialize(CallInterfaceDescriptorData * data)229 void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
230   Register registers[] = {
231       rsi,  // context
232       rcx,  // key
233   };
234   Representation representations[] = {
235       Representation::Tagged(),  // context
236       Representation::Tagged(),  // key
237   };
238   data->Initialize(arraysize(registers), registers, representations);
239 }
240 
241 
Initialize(CallInterfaceDescriptorData * data)242 void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
243   Register registers[] = {
244       rsi,  // context
245       rcx,  // name
246   };
247   Representation representations[] = {
248       Representation::Tagged(),  // context
249       Representation::Tagged(),  // name
250   };
251   data->Initialize(arraysize(registers), registers, representations);
252 }
253 
254 
Initialize(CallInterfaceDescriptorData * data)255 void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
256   Register registers[] = {
257       rsi,  // context
258       rdx,  // receiver
259   };
260   Representation representations[] = {
261       Representation::Tagged(),  // context
262       Representation::Tagged(),  // receiver
263   };
264   data->Initialize(arraysize(registers), registers, representations);
265 }
266 
267 
Initialize(CallInterfaceDescriptorData * data)268 void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
269   Register registers[] = {
270       rsi,  // context
271       rdi,  // JSFunction
272       rax,  // actual number of arguments
273       rbx,  // expected number of arguments
274   };
275   Representation representations[] = {
276       Representation::Tagged(),     // context
277       Representation::Tagged(),     // JSFunction
278       Representation::Integer32(),  // actual number of arguments
279       Representation::Integer32(),  // expected number of arguments
280   };
281   data->Initialize(arraysize(registers), registers, representations);
282 }
283 
284 
Initialize(CallInterfaceDescriptorData * data)285 void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
286   Register registers[] = {
287       rsi,  // context
288       rax,  // callee
289       rbx,  // call_data
290       rcx,  // holder
291       rdx,  // api_function_address
292   };
293   Representation representations[] = {
294       Representation::Tagged(),    // context
295       Representation::Tagged(),    // callee
296       Representation::Tagged(),    // call_data
297       Representation::Tagged(),    // holder
298       Representation::External(),  // api_function_address
299   };
300   data->Initialize(arraysize(registers), registers, representations);
301 }
302 }
303 }  // namespace v8::internal
304 
305 #endif  // V8_TARGET_ARCH_X64
306