1// Copyright 2015 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_S390
6
7#include "src/interface-descriptors.h"
8
9namespace v8 {
10namespace internal {
11
12const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
13
14void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
15    CallInterfaceDescriptorData* data, int register_parameter_count) {
16  const Register default_stub_registers[] = {r2, r3, r4, r5, r6};
17  CHECK_LE(static_cast<size_t>(register_parameter_count),
18           arraysize(default_stub_registers));
19  data->InitializePlatformSpecific(register_parameter_count,
20                                   default_stub_registers);
21}
22
23const Register LoadDescriptor::ReceiverRegister() { return r3; }
24const Register LoadDescriptor::NameRegister() { return r4; }
25const Register LoadDescriptor::SlotRegister() { return r2; }
26
27const Register LoadWithVectorDescriptor::VectorRegister() { return r5; }
28
29const Register StoreDescriptor::ReceiverRegister() { return r3; }
30const Register StoreDescriptor::NameRegister() { return r4; }
31const Register StoreDescriptor::ValueRegister() { return r2; }
32
33const Register VectorStoreICTrampolineDescriptor::SlotRegister() { return r6; }
34
35const Register VectorStoreICDescriptor::VectorRegister() { return r5; }
36
37const Register VectorStoreTransitionDescriptor::SlotRegister() { return r6; }
38const Register VectorStoreTransitionDescriptor::VectorRegister() { return r5; }
39const Register VectorStoreTransitionDescriptor::MapRegister() { return r7; }
40
41const Register StoreTransitionDescriptor::MapRegister() { return r5; }
42
43const Register StoreGlobalViaContextDescriptor::SlotRegister() { return r4; }
44const Register StoreGlobalViaContextDescriptor::ValueRegister() { return r2; }
45
46const Register StringCompareDescriptor::LeftRegister() { return r3; }
47const Register StringCompareDescriptor::RightRegister() { return r2; }
48
49const Register ApiGetterDescriptor::HolderRegister() { return r2; }
50const Register ApiGetterDescriptor::CallbackRegister() { return r5; }
51
52const Register MathPowTaggedDescriptor::exponent() { return r4; }
53
54const Register MathPowIntegerDescriptor::exponent() {
55  return MathPowTaggedDescriptor::exponent();
56}
57
58const Register GrowArrayElementsDescriptor::ObjectRegister() { return r2; }
59const Register GrowArrayElementsDescriptor::KeyRegister() { return r5; }
60
61void FastNewClosureDescriptor::InitializePlatformSpecific(
62    CallInterfaceDescriptorData* data) {
63  Register registers[] = {r4};
64  data->InitializePlatformSpecific(arraysize(registers), registers);
65}
66
67void FastNewContextDescriptor::InitializePlatformSpecific(
68    CallInterfaceDescriptorData* data) {
69  Register registers[] = {r3};
70  data->InitializePlatformSpecific(arraysize(registers), registers);
71}
72
73void FastNewObjectDescriptor::InitializePlatformSpecific(
74    CallInterfaceDescriptorData* data) {
75  Register registers[] = {r3, r5};
76  data->InitializePlatformSpecific(arraysize(registers), registers);
77}
78
79void FastNewRestParameterDescriptor::InitializePlatformSpecific(
80    CallInterfaceDescriptorData* data) {
81  Register registers[] = {r3};
82  data->InitializePlatformSpecific(arraysize(registers), registers);
83}
84
85void FastNewSloppyArgumentsDescriptor::InitializePlatformSpecific(
86    CallInterfaceDescriptorData* data) {
87  Register registers[] = {r3};
88  data->InitializePlatformSpecific(arraysize(registers), registers);
89}
90
91void FastNewStrictArgumentsDescriptor::InitializePlatformSpecific(
92    CallInterfaceDescriptorData* data) {
93  Register registers[] = {r3};
94  data->InitializePlatformSpecific(arraysize(registers), registers);
95}
96
97// static
98const Register TypeConversionDescriptor::ArgumentRegister() { return r2; }
99
100void TypeofDescriptor::InitializePlatformSpecific(
101    CallInterfaceDescriptorData* data) {
102  Register registers[] = {r5};
103  data->InitializePlatformSpecific(arraysize(registers), registers);
104}
105
106void FastCloneRegExpDescriptor::InitializePlatformSpecific(
107    CallInterfaceDescriptorData* data) {
108  Register registers[] = {r5, r4, r3, r2};
109  data->InitializePlatformSpecific(arraysize(registers), registers);
110}
111
112void FastCloneShallowArrayDescriptor::InitializePlatformSpecific(
113    CallInterfaceDescriptorData* data) {
114  Register registers[] = {r5, r4, r3};
115  data->InitializePlatformSpecific(arraysize(registers), registers);
116}
117
118void FastCloneShallowObjectDescriptor::InitializePlatformSpecific(
119    CallInterfaceDescriptorData* data) {
120  Register registers[] = {r5, r4, r3, r2};
121  data->InitializePlatformSpecific(arraysize(registers), registers);
122}
123
124void CreateAllocationSiteDescriptor::InitializePlatformSpecific(
125    CallInterfaceDescriptorData* data) {
126  Register registers[] = {r4, r5};
127  data->InitializePlatformSpecific(arraysize(registers), registers);
128}
129
130void CreateWeakCellDescriptor::InitializePlatformSpecific(
131    CallInterfaceDescriptorData* data) {
132  Register registers[] = {r4, r5, r3};
133  data->InitializePlatformSpecific(arraysize(registers), registers);
134}
135
136void CallFunctionDescriptor::InitializePlatformSpecific(
137    CallInterfaceDescriptorData* data) {
138  Register registers[] = {r3};
139  data->InitializePlatformSpecific(arraysize(registers), registers);
140}
141
142void CallFunctionWithFeedbackDescriptor::InitializePlatformSpecific(
143    CallInterfaceDescriptorData* data) {
144  Register registers[] = {r3, r5};
145  data->InitializePlatformSpecific(arraysize(registers), registers);
146}
147
148void CallFunctionWithFeedbackAndVectorDescriptor::InitializePlatformSpecific(
149    CallInterfaceDescriptorData* data) {
150  Register registers[] = {r3, r5, r4};
151  data->InitializePlatformSpecific(arraysize(registers), registers);
152}
153
154void CallConstructDescriptor::InitializePlatformSpecific(
155    CallInterfaceDescriptorData* data) {
156  // r2 : number of arguments
157  // r3 : the function to call
158  // r4 : feedback vector
159  // r5 : slot in feedback vector (Smi, for RecordCallTarget)
160  // r6 : new target (for IsSuperConstructorCall)
161  // TODO(turbofan): So far we don't gather type feedback and hence skip the
162  // slot parameter, but ArrayConstructStub needs the vector to be undefined.
163  Register registers[] = {r2, r3, r6, r4};
164  data->InitializePlatformSpecific(arraysize(registers), registers);
165}
166
167void CallTrampolineDescriptor::InitializePlatformSpecific(
168    CallInterfaceDescriptorData* data) {
169  // r2 : number of arguments
170  // r3 : the target to call
171  Register registers[] = {r3, r2};
172  data->InitializePlatformSpecific(arraysize(registers), registers);
173}
174
175void ConstructStubDescriptor::InitializePlatformSpecific(
176    CallInterfaceDescriptorData* data) {
177  // r2 : number of arguments
178  // r3 : the target to call
179  // r5 : the new target
180  // r4 : allocation site or undefined
181  Register registers[] = {r3, r5, r2, r4};
182  data->InitializePlatformSpecific(arraysize(registers), registers);
183}
184
185void ConstructTrampolineDescriptor::InitializePlatformSpecific(
186    CallInterfaceDescriptorData* data) {
187  // r2 : number of arguments
188  // r3 : the target to call
189  // r5 : the new target
190  Register registers[] = {r3, r5, r2};
191  data->InitializePlatformSpecific(arraysize(registers), registers);
192}
193
194void RegExpConstructResultDescriptor::InitializePlatformSpecific(
195    CallInterfaceDescriptorData* data) {
196  Register registers[] = {r4, r3, r2};
197  data->InitializePlatformSpecific(arraysize(registers), registers);
198}
199
200void TransitionElementsKindDescriptor::InitializePlatformSpecific(
201    CallInterfaceDescriptorData* data) {
202  Register registers[] = {r2, r3};
203  data->InitializePlatformSpecific(arraysize(registers), registers);
204}
205
206void AllocateHeapNumberDescriptor::InitializePlatformSpecific(
207    CallInterfaceDescriptorData* data) {
208  data->InitializePlatformSpecific(0, nullptr, nullptr);
209}
210
211#define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \
212  void Allocate##Type##Descriptor::InitializePlatformSpecific(      \
213      CallInterfaceDescriptorData* data) {                          \
214    data->InitializePlatformSpecific(0, nullptr, nullptr);          \
215  }
216SIMD128_TYPES(SIMD128_ALLOC_DESC)
217#undef SIMD128_ALLOC_DESC
218
219void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
220    CallInterfaceDescriptorData* data) {
221  // register state
222  // r2 -- number of arguments
223  // r3 -- function
224  // r4 -- allocation site with elements kind
225  Register registers[] = {r3, r4, r2};
226  data->InitializePlatformSpecific(arraysize(registers), registers);
227}
228
229void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
230    CallInterfaceDescriptorData* data) {
231  // register state
232  // r2 -- number of arguments
233  // r3 -- function
234  // r4 -- allocation site with elements kind
235  Register registers[] = {r3, r4, r2};
236  data->InitializePlatformSpecific(arraysize(registers), registers, NULL);
237}
238
239void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
240    CallInterfaceDescriptorData* data) {
241  // stack param count needs (constructor pointer, and single argument)
242  Register registers[] = {r3, r4, r2};
243  data->InitializePlatformSpecific(arraysize(registers), registers);
244}
245
246void VarArgFunctionDescriptor::InitializePlatformSpecific(
247    CallInterfaceDescriptorData* data) {
248  // stack param count needs (arg count)
249  Register registers[] = {r2};
250  data->InitializePlatformSpecific(arraysize(registers), registers);
251}
252
253void CompareDescriptor::InitializePlatformSpecific(
254    CallInterfaceDescriptorData* data) {
255  Register registers[] = {r3, r2};
256  data->InitializePlatformSpecific(arraysize(registers), registers);
257}
258
259void BinaryOpDescriptor::InitializePlatformSpecific(
260    CallInterfaceDescriptorData* data) {
261  Register registers[] = {r3, r2};
262  data->InitializePlatformSpecific(arraysize(registers), registers);
263}
264
265void BinaryOpWithAllocationSiteDescriptor::InitializePlatformSpecific(
266    CallInterfaceDescriptorData* data) {
267  Register registers[] = {r4, r3, r2};
268  data->InitializePlatformSpecific(arraysize(registers), registers);
269}
270
271void CountOpDescriptor::InitializePlatformSpecific(
272    CallInterfaceDescriptorData* data) {
273  Register registers[] = {r4};
274  data->InitializePlatformSpecific(arraysize(registers), registers);
275}
276
277void StringAddDescriptor::InitializePlatformSpecific(
278    CallInterfaceDescriptorData* data) {
279  Register registers[] = {r3, r2};
280  data->InitializePlatformSpecific(arraysize(registers), registers);
281}
282
283void KeyedDescriptor::InitializePlatformSpecific(
284    CallInterfaceDescriptorData* data) {
285  Register registers[] = {
286      r4,  // key
287  };
288  data->InitializePlatformSpecific(arraysize(registers), registers);
289}
290
291void NamedDescriptor::InitializePlatformSpecific(
292    CallInterfaceDescriptorData* data) {
293  Register registers[] = {
294      r4,  // name
295  };
296  data->InitializePlatformSpecific(arraysize(registers), registers);
297}
298
299void CallHandlerDescriptor::InitializePlatformSpecific(
300    CallInterfaceDescriptorData* data) {
301  Register registers[] = {
302      r2,  // receiver
303  };
304  data->InitializePlatformSpecific(arraysize(registers), registers);
305}
306
307void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
308    CallInterfaceDescriptorData* data) {
309  Register registers[] = {
310      r3,  // JSFunction
311      r5,  // the new target
312      r2,  // actual number of arguments
313      r4,  // expected number of arguments
314  };
315  data->InitializePlatformSpecific(arraysize(registers), registers);
316}
317
318void ApiCallbackDescriptorBase::InitializePlatformSpecific(
319    CallInterfaceDescriptorData* data) {
320  Register registers[] = {
321      r2,  // callee
322      r6,  // call_data
323      r4,  // holder
324      r3,  // api_function_address
325  };
326  data->InitializePlatformSpecific(arraysize(registers), registers);
327}
328
329void InterpreterDispatchDescriptor::InitializePlatformSpecific(
330    CallInterfaceDescriptorData* data) {
331  Register registers[] = {
332      kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
333      kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
334  data->InitializePlatformSpecific(arraysize(registers), registers);
335}
336
337void InterpreterPushArgsAndCallDescriptor::InitializePlatformSpecific(
338    CallInterfaceDescriptorData* data) {
339  Register registers[] = {
340      r2,  // argument count (not including receiver)
341      r4,  // address of first argument
342      r3   // the target callable to be call
343  };
344  data->InitializePlatformSpecific(arraysize(registers), registers);
345}
346
347void InterpreterPushArgsAndConstructDescriptor::InitializePlatformSpecific(
348    CallInterfaceDescriptorData* data) {
349  Register registers[] = {
350      r2,  // argument count (not including receiver)
351      r5,  // new target
352      r3,  // constructor to call
353      r4   // address of the first argument
354  };
355  data->InitializePlatformSpecific(arraysize(registers), registers);
356}
357
358void InterpreterCEntryDescriptor::InitializePlatformSpecific(
359    CallInterfaceDescriptorData* data) {
360  Register registers[] = {
361      r2,  // argument count (argc)
362      r4,  // address of first argument (argv)
363      r3   // the runtime function to call
364  };
365  data->InitializePlatformSpecific(arraysize(registers), registers);
366}
367
368void ResumeGeneratorDescriptor::InitializePlatformSpecific(
369    CallInterfaceDescriptorData* data) {
370  Register registers[] = {
371      r2,  // the value to pass to the generator
372      r3,  // the JSGeneratorObject to resume
373      r4   // the resume mode (tagged)
374  };
375  data->InitializePlatformSpecific(arraysize(registers), registers);
376}
377
378}  // namespace internal
379}  // namespace v8
380
381#endif  // V8_TARGET_ARCH_S390
382