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_MIPS64
6
7 #include "src/codegen/interface-descriptors.h"
8
9 #include "src/execution/frames.h"
10
11 namespace v8 {
12 namespace internal {
13
ContextRegister()14 const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
15
DefaultInitializePlatformSpecific(CallInterfaceDescriptorData * data,int register_parameter_count)16 void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
17 CallInterfaceDescriptorData* data, int register_parameter_count) {
18 const Register default_stub_registers[] = {a0, a1, a2, a3, a4};
19 CHECK_LE(static_cast<size_t>(register_parameter_count),
20 arraysize(default_stub_registers));
21 data->InitializePlatformSpecific(register_parameter_count,
22 default_stub_registers);
23 }
24
25 // On MIPS it is not allowed to use odd numbered floating point registers
26 // (e.g. f1, f3, etc.) for parameters. This can happen if we use
27 // DefaultInitializePlatformSpecific to assign float registers for parameters.
28 // E.g if fourth parameter goes to float register, f7 would be assigned for
29 // parameter (a3 casted to int is 7).
IsValidFloatParameterRegister(Register reg)30 bool CallInterfaceDescriptor::IsValidFloatParameterRegister(Register reg) {
31 return reg.code() % 2 == 0;
32 }
33
InitializePlatformSpecific(CallInterfaceDescriptorData * data)34 void WasmI32AtomicWait32Descriptor::InitializePlatformSpecific(
35 CallInterfaceDescriptorData* data) {
36 const Register default_stub_registers[] = {a0, a1, a2, a3};
37 CHECK_EQ(static_cast<size_t>(kParameterCount),
38 arraysize(default_stub_registers));
39 data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
40 }
41
InitializePlatformSpecific(CallInterfaceDescriptorData * data)42 void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
43 CallInterfaceDescriptorData* data) {
44 const Register default_stub_registers[] = {a0, a1, a2, a3, a4};
45 CHECK_EQ(static_cast<size_t>(kParameterCount - kStackArgumentsCount),
46 arraysize(default_stub_registers));
47 data->InitializePlatformSpecific(kParameterCount - kStackArgumentsCount,
48 default_stub_registers);
49 }
50
InitializePlatformSpecific(CallInterfaceDescriptorData * data)51 void RecordWriteDescriptor::InitializePlatformSpecific(
52 CallInterfaceDescriptorData* data) {
53 const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
54
55 data->RestrictAllocatableRegisters(default_stub_registers,
56 arraysize(default_stub_registers));
57
58 CHECK_LE(static_cast<size_t>(kParameterCount),
59 arraysize(default_stub_registers));
60 data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
61 }
62
InitializePlatformSpecific(CallInterfaceDescriptorData * data)63 void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
64 CallInterfaceDescriptorData* data) {
65 const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
66
67 data->RestrictAllocatableRegisters(default_stub_registers,
68 arraysize(default_stub_registers));
69
70 CHECK_LE(static_cast<size_t>(kParameterCount),
71 arraysize(default_stub_registers));
72 data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
73 }
74
ReceiverRegister()75 const Register LoadDescriptor::ReceiverRegister() { return a1; }
NameRegister()76 const Register LoadDescriptor::NameRegister() { return a2; }
SlotRegister()77 const Register LoadDescriptor::SlotRegister() { return a0; }
78
VectorRegister()79 const Register LoadWithVectorDescriptor::VectorRegister() { return a3; }
80
81 const Register
LookupStartObjectRegister()82 LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
83 return a4;
84 }
85
ReceiverRegister()86 const Register StoreDescriptor::ReceiverRegister() { return a1; }
NameRegister()87 const Register StoreDescriptor::NameRegister() { return a2; }
ValueRegister()88 const Register StoreDescriptor::ValueRegister() { return a0; }
SlotRegister()89 const Register StoreDescriptor::SlotRegister() { return a4; }
90
VectorRegister()91 const Register StoreWithVectorDescriptor::VectorRegister() { return a3; }
92
SlotRegister()93 const Register StoreTransitionDescriptor::SlotRegister() { return a4; }
VectorRegister()94 const Register StoreTransitionDescriptor::VectorRegister() { return a3; }
MapRegister()95 const Register StoreTransitionDescriptor::MapRegister() { return a5; }
96
HolderRegister()97 const Register ApiGetterDescriptor::HolderRegister() { return a0; }
CallbackRegister()98 const Register ApiGetterDescriptor::CallbackRegister() { return a3; }
99
ObjectRegister()100 const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
KeyRegister()101 const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
102
103 // static
ArgumentRegister()104 const Register TypeConversionDescriptor::ArgumentRegister() { return a0; }
105
InitializePlatformSpecific(CallInterfaceDescriptorData * data)106 void TypeofDescriptor::InitializePlatformSpecific(
107 CallInterfaceDescriptorData* data) {
108 Register registers[] = {a3};
109 data->InitializePlatformSpecific(arraysize(registers), registers);
110 }
111
InitializePlatformSpecific(CallInterfaceDescriptorData * data)112 void CallTrampolineDescriptor::InitializePlatformSpecific(
113 CallInterfaceDescriptorData* data) {
114 // a1: target
115 // a0: number of arguments
116 Register registers[] = {a1, a0};
117 data->InitializePlatformSpecific(arraysize(registers), registers);
118 }
119
InitializePlatformSpecific(CallInterfaceDescriptorData * data)120 void CallVarargsDescriptor::InitializePlatformSpecific(
121 CallInterfaceDescriptorData* data) {
122 // a0 : number of arguments (on the stack, not including receiver)
123 // a1 : the target to call
124 // a4 : arguments list length (untagged)
125 // a2 : arguments list (FixedArray)
126 Register registers[] = {a1, a0, a4, a2};
127 data->InitializePlatformSpecific(arraysize(registers), registers);
128 }
129
InitializePlatformSpecific(CallInterfaceDescriptorData * data)130 void CallForwardVarargsDescriptor::InitializePlatformSpecific(
131 CallInterfaceDescriptorData* data) {
132 // a1: the target to call
133 // a0: number of arguments
134 // a2: start index (to support rest parameters)
135 Register registers[] = {a1, a0, a2};
136 data->InitializePlatformSpecific(arraysize(registers), registers);
137 }
138
InitializePlatformSpecific(CallInterfaceDescriptorData * data)139 void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
140 CallInterfaceDescriptorData* data) {
141 // a1 : function template info
142 // a0 : number of arguments (on the stack, not including receiver)
143 Register registers[] = {a1, a0};
144 data->InitializePlatformSpecific(arraysize(registers), registers);
145 }
146
InitializePlatformSpecific(CallInterfaceDescriptorData * data)147 void CallWithSpreadDescriptor::InitializePlatformSpecific(
148 CallInterfaceDescriptorData* data) {
149 // a0 : number of arguments (on the stack, not including receiver)
150 // a1 : the target to call
151 // a2 : the object to spread
152 Register registers[] = {a1, a0, a2};
153 data->InitializePlatformSpecific(arraysize(registers), registers);
154 }
155
InitializePlatformSpecific(CallInterfaceDescriptorData * data)156 void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
157 CallInterfaceDescriptorData* data) {
158 // a1 : the target to call
159 // a2 : the arguments list
160 Register registers[] = {a1, a2};
161 data->InitializePlatformSpecific(arraysize(registers), registers);
162 }
163
InitializePlatformSpecific(CallInterfaceDescriptorData * data)164 void ConstructVarargsDescriptor::InitializePlatformSpecific(
165 CallInterfaceDescriptorData* data) {
166 // a0 : number of arguments (on the stack, not including receiver)
167 // a1 : the target to call
168 // a3 : the new target
169 // a4 : arguments list length (untagged)
170 // a2 : arguments list (FixedArray)
171 Register registers[] = {a1, a3, a0, a4, a2};
172 data->InitializePlatformSpecific(arraysize(registers), registers);
173 }
174
InitializePlatformSpecific(CallInterfaceDescriptorData * data)175 void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
176 CallInterfaceDescriptorData* data) {
177 // a1: the target to call
178 // a3: new target
179 // a0: number of arguments
180 // a2: start index (to support rest parameters)
181 Register registers[] = {a1, a3, a0, a2};
182 data->InitializePlatformSpecific(arraysize(registers), registers);
183 }
184
InitializePlatformSpecific(CallInterfaceDescriptorData * data)185 void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
186 CallInterfaceDescriptorData* data) {
187 // a0 : number of arguments (on the stack, not including receiver)
188 // a1 : the target to call
189 // a3 : the new target
190 // a2 : the object to spread
191 Register registers[] = {a1, a3, a0, a2};
192 data->InitializePlatformSpecific(arraysize(registers), registers);
193 }
194
InitializePlatformSpecific(CallInterfaceDescriptorData * data)195 void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
196 CallInterfaceDescriptorData* data) {
197 // a1 : the target to call
198 // a3 : the new target
199 // a2 : the arguments list
200 Register registers[] = {a1, a3, a2};
201 data->InitializePlatformSpecific(arraysize(registers), registers);
202 }
203
InitializePlatformSpecific(CallInterfaceDescriptorData * data)204 void ConstructStubDescriptor::InitializePlatformSpecific(
205 CallInterfaceDescriptorData* data) {
206 // a1: target
207 // a3: new target
208 // a0: number of arguments
209 // a2: allocation site or undefined
210 Register registers[] = {a1, a3, a0, a2};
211 data->InitializePlatformSpecific(arraysize(registers), registers);
212 }
213
InitializePlatformSpecific(CallInterfaceDescriptorData * data)214 void AbortDescriptor::InitializePlatformSpecific(
215 CallInterfaceDescriptorData* data) {
216 Register registers[] = {a0};
217 data->InitializePlatformSpecific(arraysize(registers), registers);
218 }
219
InitializePlatformSpecific(CallInterfaceDescriptorData * data)220 void CompareDescriptor::InitializePlatformSpecific(
221 CallInterfaceDescriptorData* data) {
222 Register registers[] = {a1, a0};
223 data->InitializePlatformSpecific(arraysize(registers), registers);
224 }
225
InitializePlatformSpecific(CallInterfaceDescriptorData * data)226 void BinaryOpDescriptor::InitializePlatformSpecific(
227 CallInterfaceDescriptorData* data) {
228 Register registers[] = {a1, a0};
229 data->InitializePlatformSpecific(arraysize(registers), registers);
230 }
231
InitializePlatformSpecific(CallInterfaceDescriptorData * data)232 void ArgumentsAdaptorDescriptor::InitializePlatformSpecific(
233 CallInterfaceDescriptorData* data) {
234 Register registers[] = {
235 a1, // JSFunction
236 a3, // the new target
237 a0, // actual number of arguments
238 a2, // expected number of arguments
239 };
240 data->InitializePlatformSpecific(arraysize(registers), registers);
241 }
242
InitializePlatformSpecific(CallInterfaceDescriptorData * data)243 void ApiCallbackDescriptor::InitializePlatformSpecific(
244 CallInterfaceDescriptorData* data) {
245 Register registers[] = {
246 a1, // kApiFunctionAddress
247 a2, // kArgc
248 a3, // kCallData
249 a0, // kHolder
250 };
251 data->InitializePlatformSpecific(arraysize(registers), registers);
252 }
253
InitializePlatformSpecific(CallInterfaceDescriptorData * data)254 void InterpreterDispatchDescriptor::InitializePlatformSpecific(
255 CallInterfaceDescriptorData* data) {
256 Register registers[] = {
257 kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
258 kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
259 data->InitializePlatformSpecific(arraysize(registers), registers);
260 }
261
InitializePlatformSpecific(CallInterfaceDescriptorData * data)262 void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
263 CallInterfaceDescriptorData* data) {
264 Register registers[] = {
265 a0, // argument count (not including receiver)
266 a2, // address of first argument
267 a1 // the target callable to be call
268 };
269 data->InitializePlatformSpecific(arraysize(registers), registers);
270 }
271
InitializePlatformSpecific(CallInterfaceDescriptorData * data)272 void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
273 CallInterfaceDescriptorData* data) {
274 Register registers[] = {
275 a0, // argument count (not including receiver)
276 a4, // address of the first argument
277 a1, // constructor to call
278 a3, // new target
279 a2, // allocation site feedback if available, undefined otherwise
280 };
281 data->InitializePlatformSpecific(arraysize(registers), registers);
282 }
283
InitializePlatformSpecific(CallInterfaceDescriptorData * data)284 void ResumeGeneratorDescriptor::InitializePlatformSpecific(
285 CallInterfaceDescriptorData* data) {
286 Register registers[] = {
287 v0, // the value to pass to the generator
288 a1 // the JSGeneratorObject to resume
289 };
290 data->InitializePlatformSpecific(arraysize(registers), registers);
291 }
292
InitializePlatformSpecific(CallInterfaceDescriptorData * data)293 void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
294 CallInterfaceDescriptorData* data) {
295 Register registers[] = {
296 a1, // loaded new FP
297 };
298 data->InitializePlatformSpecific(arraysize(registers), registers);
299 }
300
InitializePlatformSpecific(CallInterfaceDescriptorData * data)301 void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
302 CallInterfaceDescriptorData* data) {
303 Register registers[] = {a0, a1};
304 data->InitializePlatformSpecific(arraysize(registers), registers);
305 }
306
307 } // namespace internal
308 } // namespace v8
309
310 #endif // V8_TARGET_ARCH_MIPS64
311