• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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