Line data Source code
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 : #include "src/frames.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 54208 : const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
15 :
16 11358522 : void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
17 : CallInterfaceDescriptorData* data, int register_parameter_count) {
18 11358522 : const Register default_stub_registers[] = {rax, rbx, rcx, rdx, rdi};
19 11358522 : CHECK_LE(static_cast<size_t>(register_parameter_count),
20 : arraysize(default_stub_registers));
21 : data->InitializePlatformSpecific(register_parameter_count,
22 11358522 : default_stub_registers);
23 11358522 : }
24 :
25 60098 : void RecordWriteDescriptor::InitializePlatformSpecific(
26 : CallInterfaceDescriptorData* data) {
27 : const Register default_stub_registers[] = {arg_reg_1, arg_reg_2, arg_reg_3,
28 60098 : arg_reg_4, kReturnRegister0};
29 :
30 : data->RestrictAllocatableRegisters(default_stub_registers,
31 : arraysize(default_stub_registers));
32 :
33 : CHECK_LE(static_cast<size_t>(kParameterCount),
34 : arraysize(default_stub_registers));
35 60098 : data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
36 60098 : }
37 :
38 60098 : const Register FastNewFunctionContextDescriptor::ScopeInfoRegister() {
39 60098 : return rdi;
40 : }
41 60098 : const Register FastNewFunctionContextDescriptor::SlotsRegister() { return rax; }
42 :
43 180350 : const Register LoadDescriptor::ReceiverRegister() { return rdx; }
44 240392 : const Register LoadDescriptor::NameRegister() { return rcx; }
45 240392 : const Register LoadDescriptor::SlotRegister() { return rax; }
46 :
47 120196 : const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
48 :
49 180294 : const Register StoreDescriptor::ReceiverRegister() { return rdx; }
50 300490 : const Register StoreDescriptor::NameRegister() { return rcx; }
51 300490 : const Register StoreDescriptor::ValueRegister() { return rax; }
52 240392 : const Register StoreDescriptor::SlotRegister() { return rdi; }
53 :
54 120196 : const Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
55 :
56 60098 : const Register StoreTransitionDescriptor::SlotRegister() { return rdi; }
57 60098 : const Register StoreTransitionDescriptor::VectorRegister() { return rbx; }
58 60098 : const Register StoreTransitionDescriptor::MapRegister() { return r11; }
59 :
60 60154 : const Register ApiGetterDescriptor::HolderRegister() { return rcx; }
61 60154 : const Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
62 :
63 60098 : const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
64 60098 : const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
65 :
66 :
67 60098 : void TypeofDescriptor::InitializePlatformSpecific(
68 : CallInterfaceDescriptorData* data) {
69 60098 : Register registers[] = {rbx};
70 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
71 60098 : }
72 :
73 :
74 : // static
75 60098 : const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
76 :
77 60098 : void CallTrampolineDescriptor::InitializePlatformSpecific(
78 : CallInterfaceDescriptorData* data) {
79 : // rax : number of arguments
80 : // rdi : the target to call
81 60098 : Register registers[] = {rdi, rax};
82 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
83 60098 : }
84 :
85 60098 : void CallVarargsDescriptor::InitializePlatformSpecific(
86 : CallInterfaceDescriptorData* data) {
87 : // rax : number of arguments (on the stack, not including receiver)
88 : // rdi : the target to call
89 : // rcx : arguments list length (untagged)
90 : // rbx : arguments list (FixedArray)
91 60098 : Register registers[] = {rdi, rax, rcx, rbx};
92 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
93 60098 : }
94 :
95 60098 : void CallForwardVarargsDescriptor::InitializePlatformSpecific(
96 : CallInterfaceDescriptorData* data) {
97 : // rax : number of arguments
98 : // rcx : start index (to support rest parameters)
99 : // rdi : the target to call
100 60098 : Register registers[] = {rdi, rax, rcx};
101 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
102 60098 : }
103 :
104 60098 : void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
105 : CallInterfaceDescriptorData* data) {
106 : // rdx: the function template info
107 : // rcx: number of arguments (on the stack, not including receiver)
108 60098 : Register registers[] = {rdx, rcx};
109 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
110 60098 : }
111 :
112 60098 : void CallWithSpreadDescriptor::InitializePlatformSpecific(
113 : CallInterfaceDescriptorData* data) {
114 : // rax : number of arguments (on the stack, not including receiver)
115 : // rdi : the target to call
116 : // rbx : the object to spread
117 60098 : Register registers[] = {rdi, rax, rbx};
118 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
119 60098 : }
120 :
121 60098 : void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
122 : CallInterfaceDescriptorData* data) {
123 : // rdi : the target to call
124 : // rbx : the arguments list
125 60098 : Register registers[] = {rdi, rbx};
126 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
127 60098 : }
128 :
129 60098 : void ConstructVarargsDescriptor::InitializePlatformSpecific(
130 : CallInterfaceDescriptorData* data) {
131 : // rax : number of arguments (on the stack, not including receiver)
132 : // rdi : the target to call
133 : // rdx : the new target
134 : // rcx : arguments list length (untagged)
135 : // rbx : arguments list (FixedArray)
136 60098 : Register registers[] = {rdi, rdx, rax, rcx, rbx};
137 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
138 60098 : }
139 :
140 60098 : void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
141 : CallInterfaceDescriptorData* data) {
142 : // rax : number of arguments
143 : // rdx : the new target
144 : // rcx : start index (to support rest parameters)
145 : // rdi : the target to call
146 60098 : Register registers[] = {rdi, rdx, rax, rcx};
147 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
148 60098 : }
149 :
150 60098 : void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
151 : CallInterfaceDescriptorData* data) {
152 : // rax : number of arguments (on the stack, not including receiver)
153 : // rdi : the target to call
154 : // rdx : the new target
155 : // rbx : the object to spread
156 60098 : Register registers[] = {rdi, rdx, rax, rbx};
157 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
158 60098 : }
159 :
160 60098 : void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
161 : CallInterfaceDescriptorData* data) {
162 : // rdi : the target to call
163 : // rdx : the new target
164 : // rbx : the arguments list
165 60098 : Register registers[] = {rdi, rdx, rbx};
166 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
167 60098 : }
168 :
169 60098 : void ConstructStubDescriptor::InitializePlatformSpecific(
170 : CallInterfaceDescriptorData* data) {
171 : // rax : number of arguments
172 : // rdx : the new target
173 : // rdi : the target to call
174 : // rbx : allocation site or undefined
175 60098 : Register registers[] = {rdi, rdx, rax, rbx};
176 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
177 60098 : }
178 :
179 60098 : void AbortDescriptor::InitializePlatformSpecific(
180 : CallInterfaceDescriptorData* data) {
181 60098 : Register registers[] = {rdx};
182 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
183 60098 : }
184 :
185 60098 : void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
186 : CallInterfaceDescriptorData* data) {
187 60098 : data->InitializePlatformSpecific(0, nullptr);
188 60098 : }
189 :
190 60098 : void CompareDescriptor::InitializePlatformSpecific(
191 : CallInterfaceDescriptorData* data) {
192 60098 : Register registers[] = {rdx, rax};
193 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
194 60098 : }
195 :
196 60098 : void BinaryOpDescriptor::InitializePlatformSpecific(
197 : CallInterfaceDescriptorData* data) {
198 60098 : Register registers[] = {rdx, rax};
199 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
200 60098 : }
201 :
202 60098 : void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
203 : CallInterfaceDescriptorData* data) {
204 : Register registers[] = {
205 : rdi, // JSFunction
206 : rdx, // the new target
207 : rax, // actual number of arguments
208 : rbx, // expected number of arguments
209 60098 : };
210 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
211 60098 : }
212 :
213 60098 : void ApiCallbackDescriptor::InitializePlatformSpecific(
214 : CallInterfaceDescriptorData* data) {
215 : Register registers[] = {
216 : rdx, // api function address
217 : rcx, // argument count (not including receiver)
218 : rbx, // call data
219 : rdi, // holder
220 60098 : };
221 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
222 60098 : }
223 :
224 60098 : void InterpreterDispatchDescriptor::InitializePlatformSpecific(
225 : CallInterfaceDescriptorData* data) {
226 : Register registers[] = {
227 : kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
228 60098 : kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
229 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
230 60098 : }
231 :
232 60098 : void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
233 : CallInterfaceDescriptorData* data) {
234 : Register registers[] = {
235 : rax, // argument count (not including receiver)
236 : rbx, // address of first argument
237 : rdi // the target callable to be call
238 60098 : };
239 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
240 60098 : }
241 :
242 60098 : void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
243 : CallInterfaceDescriptorData* data) {
244 : Register registers[] = {
245 : rax, // argument count (not including receiver)
246 : rcx, // address of first argument
247 : rdi, // constructor to call
248 : rdx, // new target
249 : rbx, // allocation site feedback if available, undefined otherwise
250 60098 : };
251 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
252 60098 : }
253 :
254 60098 : void ResumeGeneratorDescriptor::InitializePlatformSpecific(
255 : CallInterfaceDescriptorData* data) {
256 : Register registers[] = {
257 : rax, // the value to pass to the generator
258 : rdx // the JSGeneratorObject / JSAsyncGeneratorObject to resume
259 60098 : };
260 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
261 60098 : }
262 :
263 60098 : void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
264 : CallInterfaceDescriptorData* data) {
265 : Register registers[] = {
266 : rbx, // loaded new FP
267 60098 : };
268 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
269 60098 : }
270 :
271 60098 : void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
272 : CallInterfaceDescriptorData* data) {
273 60098 : Register registers[] = {arg_reg_1, arg_reg_2};
274 60098 : data->InitializePlatformSpecific(arraysize(registers), registers);
275 60098 : }
276 :
277 : } // namespace internal
278 120216 : } // namespace v8
279 :
280 : #endif // V8_TARGET_ARCH_X64
|