• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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 #ifndef V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
6 #define V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
7 
8 #if V8_TARGET_ARCH_X64
9 
10 #include "src/codegen/interface-descriptors.h"
11 
12 namespace v8 {
13 namespace internal {
14 
DefaultRegisterArray()15 constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
16   auto registers = RegisterArray(rax, rbx, rcx, rdx, rdi);
17   STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
18   return registers;
19 }
20 
21 #if DEBUG
22 template <typename DerivedDescriptor>
23 void StaticCallInterfaceDescriptor<DerivedDescriptor>::
VerifyArgumentRegisterCount(CallInterfaceDescriptorData * data,int nof_expected_args)24     VerifyArgumentRegisterCount(CallInterfaceDescriptorData* data,
25                                 int nof_expected_args) {
26   RegList allocatable_regs = data->allocatable_registers();
27   if (nof_expected_args >= 1) DCHECK(allocatable_regs.has(arg_reg_1));
28   if (nof_expected_args >= 2) DCHECK(allocatable_regs.has(arg_reg_2));
29   if (nof_expected_args >= 3) DCHECK(allocatable_regs.has(arg_reg_3));
30   if (nof_expected_args >= 4) DCHECK(allocatable_regs.has(arg_reg_4));
31   // Additional arguments are passed on the stack.
32 }
33 #endif  // DEBUG
34 
35 // static
registers()36 constexpr auto WriteBarrierDescriptor::registers() {
37 #if V8_TARGET_OS_WIN
38   return RegisterArray(rdi, r8, rcx, rax, r9, rdx, rsi);
39 #else
40   return RegisterArray(rdi, rbx, rdx, rcx, rax, rsi);
41 #endif  // V8_TARGET_OS_WIN
42 }
43 
44 #ifdef V8_IS_TSAN
45 // static
registers()46 constexpr auto TSANStoreDescriptor::registers() {
47   return RegisterArray(arg_reg_1, arg_reg_2, kReturnRegister0);
48 }
49 
50 // static
registers()51 constexpr auto TSANLoadDescriptor::registers() {
52   return RegisterArray(arg_reg_1, kReturnRegister0);
53 }
54 #endif  // V8_IS_TSAN
55 
56 // static
ReceiverRegister()57 constexpr Register LoadDescriptor::ReceiverRegister() { return rdx; }
58 // static
NameRegister()59 constexpr Register LoadDescriptor::NameRegister() { return rcx; }
60 // static
SlotRegister()61 constexpr Register LoadDescriptor::SlotRegister() { return rax; }
62 
63 // static
VectorRegister()64 constexpr Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
65 
66 // static
ReceiverRegister()67 constexpr Register KeyedLoadBaselineDescriptor::ReceiverRegister() {
68   return rdx;
69 }
70 // static
NameRegister()71 constexpr Register KeyedLoadBaselineDescriptor::NameRegister() {
72   return kInterpreterAccumulatorRegister;
73 }
74 // static
SlotRegister()75 constexpr Register KeyedLoadBaselineDescriptor::SlotRegister() { return rcx; }
76 
77 // static
VectorRegister()78 constexpr Register KeyedLoadWithVectorDescriptor::VectorRegister() {
79   return rbx;
80 }
81 
82 // static
ReceiverRegister()83 constexpr Register KeyedHasICBaselineDescriptor::ReceiverRegister() {
84   return kInterpreterAccumulatorRegister;
85 }
86 // static
NameRegister()87 constexpr Register KeyedHasICBaselineDescriptor::NameRegister() { return rdx; }
88 // static
SlotRegister()89 constexpr Register KeyedHasICBaselineDescriptor::SlotRegister() { return rcx; }
90 
91 // static
VectorRegister()92 constexpr Register KeyedHasICWithVectorDescriptor::VectorRegister() {
93   return rbx;
94 }
95 
96 // static
97 constexpr Register
LookupStartObjectRegister()98 LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
99   return rdi;
100 }
101 
102 // static
ReceiverRegister()103 constexpr Register StoreDescriptor::ReceiverRegister() { return rdx; }
104 // static
NameRegister()105 constexpr Register StoreDescriptor::NameRegister() { return rcx; }
106 // static
ValueRegister()107 constexpr Register StoreDescriptor::ValueRegister() { return rax; }
108 // static
SlotRegister()109 constexpr Register StoreDescriptor::SlotRegister() { return rdi; }
110 
111 // static
VectorRegister()112 constexpr Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
113 
114 // static
MapRegister()115 constexpr Register StoreTransitionDescriptor::MapRegister() { return r11; }
116 
117 // static
HolderRegister()118 constexpr Register ApiGetterDescriptor::HolderRegister() { return rcx; }
119 // static
CallbackRegister()120 constexpr Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
121 
122 // static
ObjectRegister()123 constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
124 // static
KeyRegister()125 constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
126 
127 // static
ParamsSizeRegister()128 constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
129   return rbx;
130 }
131 // static
WeightRegister()132 constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
133   return rcx;
134 }
135 
136 // static
ArgumentRegister()137 constexpr Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
138 
139 // static
registers()140 constexpr auto TypeofDescriptor::registers() { return RegisterArray(rax); }
141 
142 // static
registers()143 constexpr auto CallTrampolineDescriptor::registers() {
144   // rax : number of arguments
145   // rdi : the target to call
146   return RegisterArray(rdi, rax);
147 }
148 // static
registers()149 constexpr auto CopyDataPropertiesWithExcludedPropertiesDescriptor::registers() {
150   // rdi : the source
151   // rax : the excluded property count
152   return RegisterArray(rdi, rax);
153 }
154 
155 // static
156 constexpr auto
registers()157 CopyDataPropertiesWithExcludedPropertiesOnStackDescriptor::registers() {
158   // rdi : the source
159   // rax : the excluded property count
160   // rcx : the excluded property base
161   return RegisterArray(rdi, rax, rcx);
162 }
163 
164 // static
registers()165 constexpr auto CallVarargsDescriptor::registers() {
166   // rax : number of arguments (on the stack)
167   // rdi : the target to call
168   // rcx : arguments list length (untagged)
169   // rbx : arguments list (FixedArray)
170   return RegisterArray(rdi, rax, rcx, rbx);
171 }
172 
173 // static
registers()174 constexpr auto CallForwardVarargsDescriptor::registers() {
175   // rax : number of arguments
176   // rcx : start index (to support rest parameters)
177   // rdi : the target to call
178   return RegisterArray(rdi, rax, rcx);
179 }
180 
181 // static
registers()182 constexpr auto CallFunctionTemplateDescriptor::registers() {
183   // rdx: the function template info
184   // rcx: number of arguments (on the stack)
185   return RegisterArray(rdx, rcx);
186 }
187 
188 // static
registers()189 constexpr auto CallWithSpreadDescriptor::registers() {
190   // rax : number of arguments (on the stack)
191   // rdi : the target to call
192   // rbx : the object to spread
193   return RegisterArray(rdi, rax, rbx);
194 }
195 
196 // static
registers()197 constexpr auto CallWithArrayLikeDescriptor::registers() {
198   // rdi : the target to call
199   // rbx : the arguments list
200   return RegisterArray(rdi, rbx);
201 }
202 
203 // static
registers()204 constexpr auto ConstructVarargsDescriptor::registers() {
205   // rax : number of arguments (on the stack)
206   // rdi : the target to call
207   // rdx : the new target
208   // rcx : arguments list length (untagged)
209   // rbx : arguments list (FixedArray)
210   return RegisterArray(rdi, rdx, rax, rcx, rbx);
211 }
212 
213 // static
registers()214 constexpr auto ConstructForwardVarargsDescriptor::registers() {
215   // rax : number of arguments
216   // rdx : the new target
217   // rcx : start index (to support rest parameters)
218   // rdi : the target to call
219   return RegisterArray(rdi, rdx, rax, rcx);
220 }
221 
222 // static
registers()223 constexpr auto ConstructWithSpreadDescriptor::registers() {
224   // rax : number of arguments (on the stack)
225   // rdi : the target to call
226   // rdx : the new target
227   // rbx : the object to spread
228   return RegisterArray(rdi, rdx, rax, rbx);
229 }
230 
231 // static
registers()232 constexpr auto ConstructWithArrayLikeDescriptor::registers() {
233   // rdi : the target to call
234   // rdx : the new target
235   // rbx : the arguments list
236   return RegisterArray(rdi, rdx, rbx);
237 }
238 
239 // static
registers()240 constexpr auto ConstructStubDescriptor::registers() {
241   // rax : number of arguments
242   // rdx : the new target
243   // rdi : the target to call
244   // rbx : allocation site or undefined
245   return RegisterArray(rdi, rdx, rax, rbx);
246 }
247 
248 // static
registers()249 constexpr auto AbortDescriptor::registers() { return RegisterArray(rdx); }
250 
251 // static
registers()252 constexpr auto CompareDescriptor::registers() {
253   return RegisterArray(rdx, rax);
254 }
255 
256 // static
registers()257 constexpr auto BinaryOpDescriptor::registers() {
258   return RegisterArray(rdx, rax);
259 }
260 
261 // static
registers()262 constexpr auto Compare_BaselineDescriptor::registers() {
263   return RegisterArray(rdx, rax, rbx);
264 }
265 
266 // static
registers()267 constexpr auto BinaryOp_BaselineDescriptor::registers() {
268   return RegisterArray(rdx, rax, rbx);
269 }
270 
271 // static
registers()272 constexpr auto BinarySmiOp_BaselineDescriptor::registers() {
273   return RegisterArray(rax, rdx, rbx);
274 }
275 
276 // static
registers()277 constexpr auto ApiCallbackDescriptor::registers() {
278   return RegisterArray(rdx,   // api function address
279                        rcx,   // argument count (not including receiver)
280                        rbx,   // call data
281                        rdi);  // holder
282 }
283 
284 // static
registers()285 constexpr auto InterpreterDispatchDescriptor::registers() {
286   return RegisterArray(
287       kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
288       kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
289 }
290 
291 // static
registers()292 constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
293   return RegisterArray(rax,   // argument count
294                        rbx,   // address of first argument
295                        rdi);  // the target callable to be call
296 }
297 
298 // static
registers()299 constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
300   return RegisterArray(
301       rax,   // argument count
302       rcx,   // address of first argument
303       rdi,   // constructor to call
304       rdx,   // new target
305       rbx);  // allocation site feedback if available, undefined otherwise
306 }
307 
308 // static
registers()309 constexpr auto ResumeGeneratorDescriptor::registers() {
310   return RegisterArray(
311       rax,   // the value to pass to the generator
312       rdx);  // the JSGeneratorObject / JSAsyncGeneratorObject to resume
313 }
314 
315 // static
registers()316 constexpr auto RunMicrotasksEntryDescriptor::registers() {
317   return RegisterArray(arg_reg_1, arg_reg_2);
318 }
319 
320 }  // namespace internal
321 }  // namespace v8
322 
323 #endif  // V8_TARGET_ARCH_X64
324 
325 #endif  // V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
326