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