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
11namespace v8 {
12namespace internal {
13
14const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
15
16
17const Register LoadDescriptor::ReceiverRegister() { return rdx; }
18const Register LoadDescriptor::NameRegister() { return rcx; }
19
20
21const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return rax; }
22
23
24const Register VectorLoadICDescriptor::VectorRegister() { return rbx; }
25
26
27const Register StoreDescriptor::ReceiverRegister() { return rdx; }
28const Register StoreDescriptor::NameRegister() { return rcx; }
29const Register StoreDescriptor::ValueRegister() { return rax; }
30
31
32const Register ElementTransitionAndStoreDescriptor::MapRegister() {
33  return rbx;
34}
35
36
37const Register InstanceofDescriptor::left() { return rax; }
38const Register InstanceofDescriptor::right() { return rdx; }
39
40
41const Register ArgumentsAccessReadDescriptor::index() { return rdx; }
42const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; }
43
44
45const Register ApiGetterDescriptor::function_address() { return r8; }
46
47
48const Register MathPowTaggedDescriptor::exponent() { return rdx; }
49
50
51const Register MathPowIntegerDescriptor::exponent() {
52  return MathPowTaggedDescriptor::exponent();
53}
54
55
56void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
57  Register registers[] = {rsi, rbx};
58  data->Initialize(arraysize(registers), registers, NULL);
59}
60
61
62void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
63  Register registers[] = {rsi, rdi};
64  data->Initialize(arraysize(registers), registers, NULL);
65}
66
67
68void 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
75void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
76  Register registers[] = {rsi, rax};
77  data->Initialize(arraysize(registers), registers, NULL);
78}
79
80
81void 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
91void FastCloneShallowObjectDescriptor::Initialize(
92    CallInterfaceDescriptorData* data) {
93  Register registers[] = {rsi, rax, rbx, rcx, rdx};
94  data->Initialize(arraysize(registers), registers, NULL);
95}
96
97
98void CreateAllocationSiteDescriptor::Initialize(
99    CallInterfaceDescriptorData* data) {
100  Register registers[] = {rsi, rbx, rdx};
101  data->Initialize(arraysize(registers), registers, NULL);
102}
103
104
105void StoreArrayLiteralElementDescriptor::Initialize(
106    CallInterfaceDescriptorData* data) {
107  Register registers[] = {rsi, rcx, rax};
108  data->Initialize(arraysize(registers), registers, NULL);
109}
110
111
112void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
113  Register registers[] = {rsi, rdi};
114  data->Initialize(arraysize(registers), registers, NULL);
115}
116
117
118void 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
128void 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
141void RegExpConstructResultDescriptor::Initialize(
142    CallInterfaceDescriptorData* data) {
143  Register registers[] = {rsi, rcx, rbx, rax};
144  data->Initialize(arraysize(registers), registers, NULL);
145}
146
147
148void TransitionElementsKindDescriptor::Initialize(
149    CallInterfaceDescriptorData* data) {
150  Register registers[] = {rsi, rax, rbx};
151  data->Initialize(arraysize(registers), registers, NULL);
152}
153
154
155void 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
166void 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
176void 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
187void 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
198void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
199  Register registers[] = {rsi, rax};
200  data->Initialize(arraysize(registers), registers, NULL);
201}
202
203
204void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
205  Register registers[] = {rsi, rax};
206  data->Initialize(arraysize(registers), registers, NULL);
207}
208
209
210void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
211  Register registers[] = {rsi, rdx, rax};
212  data->Initialize(arraysize(registers), registers, NULL);
213}
214
215
216void BinaryOpWithAllocationSiteDescriptor::Initialize(
217    CallInterfaceDescriptorData* data) {
218  Register registers[] = {rsi, rcx, rdx, rax};
219  data->Initialize(arraysize(registers), registers, NULL);
220}
221
222
223void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
224  Register registers[] = {rsi, rdx, rax};
225  data->Initialize(arraysize(registers), registers, NULL);
226}
227
228
229void 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
242void 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
255void 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
268void 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
285void 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