]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 A |
1 | /* |
2 | * Copyright (C) 2011 Apple Inc. All rights reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
7 | * 1. Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | |
9 | * 2. Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | |
12 | * | |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 | */ | |
25 | ||
26 | #ifndef DFGCCallHelpers_h | |
27 | #define DFGCCallHelpers_h | |
28 | ||
29 | #include <wtf/Platform.h> | |
30 | ||
31 | #if ENABLE(DFG_JIT) | |
32 | ||
33 | #include "DFGAssemblyHelpers.h" | |
34 | #include "DFGGPRInfo.h" | |
35 | ||
36 | namespace JSC { namespace DFG { | |
37 | ||
38 | class CCallHelpers : public AssemblyHelpers { | |
39 | public: | |
93a37866 A |
40 | CCallHelpers(VM* vm, CodeBlock* codeBlock = 0) |
41 | : AssemblyHelpers(vm, codeBlock) | |
6fe7ccc8 A |
42 | { |
43 | } | |
44 | ||
45 | // These methods used to sort arguments into the correct registers. | |
46 | // On X86 we use cdecl calling conventions, which pass all arguments on the | |
47 | // stack. On other architectures we may need to sort values into the | |
48 | // correct registers. | |
49 | #if !NUMBER_OF_ARGUMENT_REGISTERS | |
50 | unsigned m_callArgumentOffset; | |
51 | void resetCallArguments() { m_callArgumentOffset = 0; } | |
52 | ||
53 | // These methods are using internally to implement the callOperation methods. | |
54 | void addCallArgument(GPRReg value) | |
55 | { | |
56 | poke(value, m_callArgumentOffset++); | |
57 | } | |
58 | void addCallArgument(TrustedImm32 imm) | |
59 | { | |
60 | poke(imm, m_callArgumentOffset++); | |
61 | } | |
62 | void addCallArgument(TrustedImmPtr pointer) | |
63 | { | |
64 | poke(pointer, m_callArgumentOffset++); | |
65 | } | |
66 | void addCallArgument(FPRReg value) | |
67 | { | |
68 | storeDouble(value, Address(stackPointerRegister, m_callArgumentOffset * sizeof(void*))); | |
69 | m_callArgumentOffset += sizeof(double) / sizeof(void*); | |
70 | } | |
71 | ||
72 | ALWAYS_INLINE void setupArguments(FPRReg arg1) | |
73 | { | |
74 | resetCallArguments(); | |
75 | addCallArgument(arg1); | |
76 | } | |
77 | ||
78 | ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2) | |
79 | { | |
80 | resetCallArguments(); | |
81 | addCallArgument(arg1); | |
82 | addCallArgument(arg2); | |
83 | } | |
84 | ||
85 | ALWAYS_INLINE void setupArguments(GPRReg arg1) | |
86 | { | |
87 | resetCallArguments(); | |
88 | addCallArgument(arg1); | |
89 | } | |
90 | ||
91 | ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2) | |
92 | { | |
93 | resetCallArguments(); | |
94 | addCallArgument(arg1); | |
95 | addCallArgument(arg2); | |
96 | } | |
93a37866 A |
97 | |
98 | ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1) | |
99 | { | |
100 | resetCallArguments(); | |
101 | addCallArgument(arg1); | |
102 | } | |
6fe7ccc8 A |
103 | |
104 | ALWAYS_INLINE void setupArgumentsExecState() | |
105 | { | |
106 | resetCallArguments(); | |
107 | addCallArgument(GPRInfo::callFrameRegister); | |
108 | } | |
109 | ||
110 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1) | |
111 | { | |
112 | resetCallArguments(); | |
113 | addCallArgument(GPRInfo::callFrameRegister); | |
114 | addCallArgument(arg1); | |
115 | } | |
116 | ||
117 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1) | |
118 | { | |
119 | resetCallArguments(); | |
120 | addCallArgument(GPRInfo::callFrameRegister); | |
121 | addCallArgument(arg1); | |
122 | } | |
123 | ||
93a37866 A |
124 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1) |
125 | { | |
126 | resetCallArguments(); | |
127 | addCallArgument(GPRInfo::callFrameRegister); | |
128 | addCallArgument(arg1); | |
129 | } | |
130 | ||
6fe7ccc8 A |
131 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2) |
132 | { | |
133 | resetCallArguments(); | |
134 | addCallArgument(GPRInfo::callFrameRegister); | |
135 | addCallArgument(arg1); | |
136 | addCallArgument(arg2); | |
137 | } | |
138 | ||
139 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2) | |
140 | { | |
141 | resetCallArguments(); | |
142 | addCallArgument(GPRInfo::callFrameRegister); | |
143 | addCallArgument(arg1); | |
144 | addCallArgument(arg2); | |
145 | } | |
146 | ||
93a37866 A |
147 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2) |
148 | { | |
149 | resetCallArguments(); | |
150 | addCallArgument(GPRInfo::callFrameRegister); | |
151 | addCallArgument(arg1); | |
152 | addCallArgument(arg2); | |
153 | } | |
154 | ||
155 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2) | |
156 | { | |
157 | resetCallArguments(); | |
158 | addCallArgument(GPRInfo::callFrameRegister); | |
159 | addCallArgument(arg1); | |
160 | addCallArgument(arg2); | |
161 | } | |
162 | ||
163 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2) | |
164 | { | |
165 | resetCallArguments(); | |
166 | addCallArgument(GPRInfo::callFrameRegister); | |
167 | addCallArgument(arg1); | |
168 | addCallArgument(arg2); | |
169 | } | |
170 | ||
6fe7ccc8 A |
171 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2) |
172 | { | |
173 | resetCallArguments(); | |
174 | addCallArgument(GPRInfo::callFrameRegister); | |
175 | addCallArgument(arg1); | |
176 | addCallArgument(arg2); | |
177 | } | |
178 | ||
179 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2) | |
180 | { | |
181 | resetCallArguments(); | |
182 | addCallArgument(GPRInfo::callFrameRegister); | |
183 | addCallArgument(arg1); | |
184 | addCallArgument(arg2); | |
185 | } | |
186 | ||
93a37866 A |
187 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2) |
188 | { | |
189 | resetCallArguments(); | |
190 | addCallArgument(GPRInfo::callFrameRegister); | |
191 | addCallArgument(arg1); | |
192 | addCallArgument(arg2); | |
193 | } | |
194 | ||
6fe7ccc8 A |
195 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3) |
196 | { | |
197 | resetCallArguments(); | |
198 | addCallArgument(GPRInfo::callFrameRegister); | |
199 | addCallArgument(arg1); | |
200 | addCallArgument(arg2); | |
201 | addCallArgument(arg3); | |
202 | } | |
203 | ||
204 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3) | |
205 | { | |
206 | resetCallArguments(); | |
207 | addCallArgument(GPRInfo::callFrameRegister); | |
208 | addCallArgument(arg1); | |
209 | addCallArgument(arg2); | |
210 | addCallArgument(arg3); | |
211 | } | |
212 | ||
93a37866 A |
213 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3) |
214 | { | |
215 | resetCallArguments(); | |
216 | addCallArgument(GPRInfo::callFrameRegister); | |
217 | addCallArgument(arg1); | |
218 | addCallArgument(arg2); | |
219 | addCallArgument(arg3); | |
220 | } | |
221 | ||
6fe7ccc8 A |
222 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3) |
223 | { | |
224 | resetCallArguments(); | |
225 | addCallArgument(GPRInfo::callFrameRegister); | |
226 | addCallArgument(arg1); | |
227 | addCallArgument(arg2); | |
228 | addCallArgument(arg3); | |
229 | } | |
230 | ||
93a37866 A |
231 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) |
232 | { | |
233 | resetCallArguments(); | |
234 | addCallArgument(GPRInfo::callFrameRegister); | |
235 | addCallArgument(arg1); | |
236 | addCallArgument(arg2); | |
237 | addCallArgument(arg3); | |
238 | } | |
239 | ||
6fe7ccc8 A |
240 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) |
241 | { | |
242 | resetCallArguments(); | |
243 | addCallArgument(GPRInfo::callFrameRegister); | |
244 | addCallArgument(arg1); | |
245 | addCallArgument(arg2); | |
246 | addCallArgument(arg3); | |
247 | } | |
248 | ||
93a37866 A |
249 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) |
250 | { | |
251 | resetCallArguments(); | |
252 | addCallArgument(GPRInfo::callFrameRegister); | |
253 | addCallArgument(arg1); | |
254 | addCallArgument(arg2); | |
255 | addCallArgument(arg3); | |
256 | addCallArgument(arg4); | |
257 | } | |
258 | ||
259 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) | |
260 | { | |
261 | resetCallArguments(); | |
262 | addCallArgument(GPRInfo::callFrameRegister); | |
263 | addCallArgument(arg1); | |
264 | addCallArgument(arg2); | |
265 | addCallArgument(arg3); | |
266 | addCallArgument(arg4); | |
267 | addCallArgument(arg5); | |
268 | } | |
269 | ||
6fe7ccc8 A |
270 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) |
271 | { | |
272 | resetCallArguments(); | |
273 | addCallArgument(GPRInfo::callFrameRegister); | |
274 | addCallArgument(arg1); | |
275 | addCallArgument(arg2); | |
276 | addCallArgument(arg3); | |
277 | addCallArgument(arg4); | |
278 | } | |
279 | ||
93a37866 A |
280 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4) |
281 | { | |
282 | resetCallArguments(); | |
283 | addCallArgument(GPRInfo::callFrameRegister); | |
284 | addCallArgument(arg1); | |
285 | addCallArgument(arg2); | |
286 | addCallArgument(arg3); | |
287 | addCallArgument(arg4); | |
288 | } | |
289 | ||
290 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3) | |
291 | { | |
292 | resetCallArguments(); | |
293 | addCallArgument(GPRInfo::callFrameRegister); | |
294 | addCallArgument(arg1); | |
295 | addCallArgument(arg2); | |
296 | addCallArgument(arg3); | |
297 | } | |
298 | ||
6fe7ccc8 A |
299 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4) |
300 | { | |
301 | resetCallArguments(); | |
302 | addCallArgument(GPRInfo::callFrameRegister); | |
303 | addCallArgument(arg1); | |
304 | addCallArgument(arg2); | |
305 | addCallArgument(arg3); | |
306 | addCallArgument(arg4); | |
307 | } | |
308 | ||
309 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4) | |
310 | { | |
311 | resetCallArguments(); | |
312 | addCallArgument(GPRInfo::callFrameRegister); | |
313 | addCallArgument(arg1); | |
314 | addCallArgument(arg2); | |
315 | addCallArgument(arg3); | |
316 | addCallArgument(arg4); | |
317 | } | |
318 | ||
319 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4) | |
320 | { | |
321 | resetCallArguments(); | |
322 | addCallArgument(GPRInfo::callFrameRegister); | |
323 | addCallArgument(arg1); | |
324 | addCallArgument(arg2); | |
325 | addCallArgument(arg3); | |
326 | addCallArgument(arg4); | |
327 | } | |
328 | ||
329 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) | |
330 | { | |
331 | resetCallArguments(); | |
332 | addCallArgument(GPRInfo::callFrameRegister); | |
333 | addCallArgument(arg1); | |
334 | addCallArgument(arg2); | |
335 | addCallArgument(arg3); | |
336 | addCallArgument(arg4); | |
337 | addCallArgument(arg5); | |
338 | } | |
93a37866 A |
339 | |
340 | ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) | |
341 | { | |
342 | resetCallArguments(); | |
343 | addCallArgument(GPRInfo::callFrameRegister); | |
344 | addCallArgument(arg1); | |
345 | addCallArgument(arg2); | |
346 | } | |
347 | ||
348 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) | |
349 | { | |
350 | resetCallArguments(); | |
351 | addCallArgument(GPRInfo::callFrameRegister); | |
352 | addCallArgument(arg1); | |
353 | addCallArgument(arg2); | |
354 | addCallArgument(arg3); | |
355 | } | |
6fe7ccc8 A |
356 | #endif // !NUMBER_OF_ARGUMENT_REGISTERS |
357 | // These methods are suitable for any calling convention that provides for | |
358 | // at least 4 argument registers, e.g. X86_64, ARMv7. | |
359 | #if NUMBER_OF_ARGUMENT_REGISTERS >= 4 | |
360 | template<GPRReg destA, GPRReg destB> | |
361 | void setupTwoStubArgs(GPRReg srcA, GPRReg srcB) | |
362 | { | |
363 | // Assuming that srcA != srcB, there are 7 interesting states the registers may be in: | |
364 | // (1) both are already in arg regs, the right way around. | |
365 | // (2) both are already in arg regs, the wrong way around. | |
366 | // (3) neither are currently in arg registers. | |
367 | // (4) srcA in in its correct reg. | |
368 | // (5) srcA in in the incorrect reg. | |
369 | // (6) srcB in in its correct reg. | |
370 | // (7) srcB in in the incorrect reg. | |
371 | // | |
372 | // The trivial approach is to simply emit two moves, to put srcA in place then srcB in | |
373 | // place (the MacroAssembler will omit redundant moves). This apporach will be safe in | |
374 | // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2 | |
375 | // (requires a swap) and 7 (must move srcB first, to avoid trampling.) | |
376 | ||
377 | if (srcB != destA) { | |
378 | // Handle the easy cases - two simple moves. | |
379 | move(srcA, destA); | |
380 | move(srcB, destB); | |
381 | } else if (srcA != destB) { | |
382 | // Handle the non-swap case - just put srcB in place first. | |
383 | move(srcB, destB); | |
384 | move(srcA, destA); | |
385 | } else | |
386 | swap(destA, destB); | |
387 | } | |
93a37866 | 388 | #if CPU(X86_64) || CPU(ARM64) |
6fe7ccc8 A |
389 | template<FPRReg destA, FPRReg destB> |
390 | void setupTwoStubArgs(FPRReg srcA, FPRReg srcB) | |
391 | { | |
392 | // Assuming that srcA != srcB, there are 7 interesting states the registers may be in: | |
393 | // (1) both are already in arg regs, the right way around. | |
394 | // (2) both are already in arg regs, the wrong way around. | |
395 | // (3) neither are currently in arg registers. | |
396 | // (4) srcA in in its correct reg. | |
397 | // (5) srcA in in the incorrect reg. | |
398 | // (6) srcB in in its correct reg. | |
399 | // (7) srcB in in the incorrect reg. | |
400 | // | |
401 | // The trivial approach is to simply emit two moves, to put srcA in place then srcB in | |
402 | // place (the MacroAssembler will omit redundant moves). This apporach will be safe in | |
403 | // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2 | |
404 | // (requires a swap) and 7 (must move srcB first, to avoid trampling.) | |
405 | ||
406 | if (srcB != destA) { | |
407 | // Handle the easy cases - two simple moves. | |
408 | moveDouble(srcA, destA); | |
409 | moveDouble(srcB, destB); | |
410 | return; | |
411 | } | |
412 | ||
413 | if (srcA != destB) { | |
414 | // Handle the non-swap case - just put srcB in place first. | |
415 | moveDouble(srcB, destB); | |
416 | moveDouble(srcA, destA); | |
417 | return; | |
418 | } | |
419 | ||
420 | ASSERT(srcB == destA && srcA == destB); | |
421 | // Need to swap; pick a temporary register. | |
422 | FPRReg temp; | |
423 | if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3) | |
424 | temp = FPRInfo::argumentFPR3; | |
425 | else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2) | |
426 | temp = FPRInfo::argumentFPR2; | |
427 | else { | |
428 | ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1); | |
429 | temp = FPRInfo::argumentFPR1; | |
430 | } | |
431 | moveDouble(destA, temp); | |
432 | moveDouble(destB, destA); | |
433 | moveDouble(temp, destB); | |
434 | } | |
435 | #endif | |
436 | void setupStubArguments(GPRReg arg1, GPRReg arg2) | |
437 | { | |
438 | setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2); | |
439 | } | |
440 | void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3) | |
441 | { | |
442 | // If neither of arg2/arg3 are in our way, then we can move arg1 into place. | |
443 | // Then we can use setupTwoStubArgs to fix arg2/arg3. | |
444 | if (arg2 != GPRInfo::argumentGPR1 && arg3 != GPRInfo::argumentGPR1) { | |
445 | move(arg1, GPRInfo::argumentGPR1); | |
446 | setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3); | |
447 | return; | |
448 | } | |
449 | ||
450 | // If neither of arg1/arg3 are in our way, then we can move arg2 into place. | |
451 | // Then we can use setupTwoStubArgs to fix arg1/arg3. | |
452 | if (arg1 != GPRInfo::argumentGPR2 && arg3 != GPRInfo::argumentGPR2) { | |
453 | move(arg2, GPRInfo::argumentGPR2); | |
454 | setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3); | |
455 | return; | |
456 | } | |
457 | ||
458 | // If neither of arg1/arg2 are in our way, then we can move arg3 into place. | |
459 | // Then we can use setupTwoStubArgs to fix arg1/arg2. | |
460 | if (arg1 != GPRInfo::argumentGPR3 && arg2 != GPRInfo::argumentGPR3) { | |
461 | move(arg3, GPRInfo::argumentGPR3); | |
462 | setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2); | |
463 | return; | |
464 | } | |
465 | ||
466 | // If we get here, we haven't been able to move any of arg1/arg2/arg3. | |
467 | // Since all three are blocked, then all three must already be in the argument register. | |
468 | // But are they in the right ones? | |
469 | ||
470 | // First, ensure arg1 is in place. | |
471 | if (arg1 != GPRInfo::argumentGPR1) { | |
472 | swap(arg1, GPRInfo::argumentGPR1); | |
473 | ||
474 | // If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be. | |
475 | ASSERT(arg2 == GPRInfo::argumentGPR1 || arg3 == GPRInfo::argumentGPR1); | |
476 | // If arg2 was in argumentGPR1 it no longer is (due to the swap). | |
477 | // Otherwise arg3 must have been. Mark him as moved. | |
478 | if (arg2 == GPRInfo::argumentGPR1) | |
479 | arg2 = arg1; | |
480 | else | |
481 | arg3 = arg1; | |
482 | } | |
483 | ||
484 | // Either arg2 & arg3 need swapping, or we're all done. | |
485 | ASSERT((arg2 == GPRInfo::argumentGPR2 || arg3 == GPRInfo::argumentGPR3) | |
486 | || (arg2 == GPRInfo::argumentGPR3 || arg3 == GPRInfo::argumentGPR2)); | |
487 | ||
488 | if (arg2 != GPRInfo::argumentGPR2) | |
489 | swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3); | |
490 | } | |
491 | ||
93a37866 | 492 | #if CPU(X86_64) || CPU(ARM64) |
6fe7ccc8 A |
493 | ALWAYS_INLINE void setupArguments(FPRReg arg1) |
494 | { | |
495 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
496 | } | |
497 | ||
498 | ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2) | |
499 | { | |
500 | setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2); | |
501 | } | |
93a37866 A |
502 | |
503 | ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) | |
504 | { | |
505 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
506 | move(arg2, GPRInfo::argumentGPR1); | |
507 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
508 | } | |
509 | ||
510 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) | |
511 | { | |
512 | moveDouble(arg3, FPRInfo::argumentFPR0); | |
513 | setupStubArguments(arg1, arg2); | |
514 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
515 | } | |
516 | #elif CPU(ARM) | |
517 | #if CPU(ARM_HARDFP) | |
518 | ALWAYS_INLINE void setupArguments(FPRReg arg1) | |
519 | { | |
520 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
521 | } | |
522 | ||
523 | ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2) | |
524 | { | |
525 | if (arg2 != FPRInfo::argumentFPR0) { | |
526 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
527 | moveDouble(arg2, FPRInfo::argumentFPR1); | |
528 | } else if (arg1 != FPRInfo::argumentFPR1) { | |
529 | moveDouble(arg2, FPRInfo::argumentFPR1); | |
530 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
531 | } else { | |
532 | // Swap arg1, arg2. | |
533 | moveDouble(FPRInfo::argumentFPR0, ARMRegisters::d2); | |
534 | moveDouble(FPRInfo::argumentFPR1, FPRInfo::argumentFPR0); | |
535 | moveDouble(ARMRegisters::d2, FPRInfo::argumentFPR1); | |
536 | } | |
537 | } | |
538 | ||
539 | ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) | |
540 | { | |
541 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
542 | move(arg2, GPRInfo::argumentGPR1); | |
543 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
544 | } | |
545 | ||
546 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) | |
547 | { | |
548 | moveDouble(arg3, FPRInfo::argumentFPR0); | |
549 | setupStubArguments(arg1, arg2); | |
550 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
551 | } | |
6fe7ccc8 A |
552 | #else |
553 | ALWAYS_INLINE void setupArguments(FPRReg arg1) | |
554 | { | |
555 | assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1); | |
556 | } | |
557 | ||
558 | ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2) | |
559 | { | |
560 | assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1); | |
561 | assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2); | |
562 | } | |
93a37866 A |
563 | |
564 | ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) | |
565 | { | |
566 | move(arg2, GPRInfo::argumentGPR3); | |
567 | assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1); | |
568 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
569 | } | |
570 | ||
571 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) | |
572 | { | |
573 | setupStubArguments(arg1, arg2); | |
574 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
575 | assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3); | |
576 | poke(GPRInfo::nonArgGPR0); | |
577 | } | |
578 | #endif // CPU(ARM_HARDFP) | |
579 | #elif CPU(MIPS) | |
580 | ALWAYS_INLINE void setupArguments(FPRReg arg1) | |
581 | { | |
582 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
583 | } | |
584 | ||
585 | ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2) | |
586 | { | |
587 | if (arg2 != FPRInfo::argumentFPR0) { | |
588 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
589 | moveDouble(arg2, FPRInfo::argumentFPR1); | |
590 | } else if (arg1 != FPRInfo::argumentFPR1) { | |
591 | moveDouble(arg2, FPRInfo::argumentFPR1); | |
592 | moveDouble(arg1, FPRInfo::argumentFPR0); | |
593 | } else { | |
594 | // Swap arg1, arg2. | |
595 | swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1); | |
596 | } | |
597 | } | |
598 | ||
599 | ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2) | |
600 | { | |
601 | assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1); | |
602 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
603 | poke(arg2, 4); | |
604 | } | |
605 | ||
606 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3) | |
607 | { | |
608 | setupStubArguments(arg1, arg2); | |
609 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
610 | poke(arg3, 4); | |
611 | } | |
612 | #else | |
613 | #error "DFG JIT not supported on this platform." | |
6fe7ccc8 A |
614 | #endif |
615 | ||
616 | ALWAYS_INLINE void setupArguments(GPRReg arg1) | |
617 | { | |
618 | move(arg1, GPRInfo::argumentGPR0); | |
619 | } | |
620 | ||
621 | ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2) | |
622 | { | |
623 | setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2); | |
624 | } | |
93a37866 A |
625 | |
626 | ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1) | |
627 | { | |
628 | move(arg1, GPRInfo::argumentGPR0); | |
629 | } | |
6fe7ccc8 A |
630 | |
631 | ALWAYS_INLINE void setupArgumentsExecState() | |
632 | { | |
633 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
634 | } | |
635 | ||
636 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1) | |
637 | { | |
638 | move(arg1, GPRInfo::argumentGPR1); | |
639 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
640 | } | |
641 | ||
642 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1) | |
643 | { | |
644 | move(arg1, GPRInfo::argumentGPR1); | |
645 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
646 | } | |
647 | ||
93a37866 A |
648 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1) |
649 | { | |
650 | move(arg1, GPRInfo::argumentGPR1); | |
651 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
652 | } | |
653 | ||
6fe7ccc8 A |
654 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2) |
655 | { | |
656 | setupStubArguments(arg1, arg2); | |
657 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
658 | } | |
659 | ||
660 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2) | |
661 | { | |
662 | move(arg1, GPRInfo::argumentGPR1); | |
663 | move(arg2, GPRInfo::argumentGPR2); | |
664 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
665 | } | |
93a37866 A |
666 | #if CPU(X86_64) || CPU(ARM64) |
667 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm64 arg2) | |
668 | { | |
669 | move(arg1, GPRInfo::argumentGPR1); | |
670 | move(arg2, GPRInfo::argumentGPR2); | |
671 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
672 | } | |
673 | ||
674 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm64 arg1, GPRReg arg2) | |
675 | { | |
676 | move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample! | |
677 | move(arg1, GPRInfo::argumentGPR1); | |
678 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
679 | } | |
680 | #endif | |
681 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2) | |
682 | { | |
683 | move(arg1, GPRInfo::argumentGPR1); | |
684 | move(arg2, GPRInfo::argumentGPR2); | |
685 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
686 | } | |
6fe7ccc8 A |
687 | |
688 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2) | |
689 | { | |
690 | move(arg1, GPRInfo::argumentGPR1); | |
691 | move(arg2, GPRInfo::argumentGPR2); | |
692 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
693 | } | |
694 | ||
695 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2) | |
696 | { | |
697 | move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample! | |
698 | move(arg1, GPRInfo::argumentGPR1); | |
699 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
700 | } | |
701 | ||
93a37866 A |
702 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2) |
703 | { | |
704 | move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample! | |
705 | move(arg1, GPRInfo::argumentGPR1); | |
706 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
707 | } | |
708 | ||
6fe7ccc8 A |
709 | ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2) |
710 | { | |
711 | move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample! | |
712 | move(arg1, GPRInfo::argumentGPR1); | |
713 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
714 | } | |
715 | ||
716 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2) | |
717 | { | |
718 | move(arg1, GPRInfo::argumentGPR1); | |
719 | move(arg2, GPRInfo::argumentGPR2); | |
720 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
721 | } | |
722 | ||
723 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2) | |
724 | { | |
725 | move(arg1, GPRInfo::argumentGPR1); | |
726 | move(arg2, GPRInfo::argumentGPR2); | |
727 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
728 | } | |
729 | ||
93a37866 A |
730 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2) |
731 | { | |
732 | move(arg1, GPRInfo::argumentGPR1); | |
733 | move(arg2, GPRInfo::argumentGPR2); | |
734 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
735 | } | |
736 | ||
6fe7ccc8 A |
737 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3) |
738 | { | |
739 | setupStubArguments(arg1, arg2, arg3); | |
740 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
741 | } | |
742 | ||
743 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3) | |
744 | { | |
745 | setupStubArguments(arg1, arg2); | |
746 | move(arg3, GPRInfo::argumentGPR3); | |
747 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
748 | } | |
749 | ||
93a37866 A |
750 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3) |
751 | { | |
752 | setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3); | |
753 | move(arg2, GPRInfo::argumentGPR2); | |
754 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
755 | } | |
756 | ||
6fe7ccc8 A |
757 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3) |
758 | { | |
759 | move(arg1, GPRInfo::argumentGPR1); | |
760 | move(arg2, GPRInfo::argumentGPR2); | |
761 | move(arg3, GPRInfo::argumentGPR3); | |
762 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
763 | } | |
764 | ||
93a37866 A |
765 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3) |
766 | { | |
767 | move(arg1, GPRInfo::argumentGPR1); | |
768 | move(arg2, GPRInfo::argumentGPR2); | |
769 | move(arg3, GPRInfo::argumentGPR3); | |
770 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
771 | } | |
772 | ||
6fe7ccc8 A |
773 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) |
774 | { | |
775 | move(arg1, GPRInfo::argumentGPR1); | |
776 | move(arg2, GPRInfo::argumentGPR2); | |
777 | move(arg3, GPRInfo::argumentGPR3); | |
778 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
779 | } | |
780 | ||
781 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3) | |
782 | { | |
783 | setupStubArguments(arg1, arg2); | |
784 | move(arg3, GPRInfo::argumentGPR3); | |
785 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
786 | } | |
787 | ||
788 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3) | |
93a37866 A |
789 | { |
790 | move(arg3, GPRInfo::argumentGPR3); | |
791 | move(arg1, GPRInfo::argumentGPR1); | |
792 | move(arg2, GPRInfo::argumentGPR2); | |
793 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
794 | } | |
795 | ||
796 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3) | |
797 | { | |
798 | move(arg3, GPRInfo::argumentGPR3); | |
799 | move(arg1, GPRInfo::argumentGPR1); | |
800 | move(arg2, GPRInfo::argumentGPR2); | |
801 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
802 | } | |
803 | ||
804 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3) | |
805 | { | |
806 | move(arg2, GPRInfo::argumentGPR2); | |
807 | move(arg1, GPRInfo::argumentGPR1); | |
808 | move(arg3, GPRInfo::argumentGPR3); | |
809 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
810 | } | |
811 | ||
812 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3) | |
813 | { | |
814 | setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3); | |
815 | move(arg1, GPRInfo::argumentGPR1); | |
816 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
817 | } | |
818 | ||
819 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3) | |
820 | { | |
821 | move(arg1, GPRInfo::argumentGPR1); | |
822 | move(arg2, GPRInfo::argumentGPR2); | |
823 | move(arg3, GPRInfo::argumentGPR3); | |
824 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
825 | } | |
826 | ||
827 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3) | |
6fe7ccc8 A |
828 | { |
829 | move(arg1, GPRInfo::argumentGPR1); | |
830 | move(arg2, GPRInfo::argumentGPR2); | |
831 | move(arg3, GPRInfo::argumentGPR3); | |
832 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
833 | } | |
834 | ||
835 | #endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4 | |
836 | // These methods are suitable for any calling convention that provides for | |
837 | // exactly 4 argument registers, e.g. ARMv7. | |
838 | #if NUMBER_OF_ARGUMENT_REGISTERS == 4 | |
93a37866 A |
839 | |
840 | #if CPU(MIPS) | |
841 | #define POKE_ARGUMENT_OFFSET 4 | |
842 | #else | |
843 | #define POKE_ARGUMENT_OFFSET 0 | |
844 | #endif | |
845 | ||
6fe7ccc8 A |
846 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) |
847 | { | |
93a37866 A |
848 | poke(arg4, POKE_ARGUMENT_OFFSET); |
849 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
850 | } | |
851 | ||
852 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4) | |
853 | { | |
854 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
855 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
856 | } | |
857 | ||
858 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) | |
859 | { | |
860 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
861 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
862 | } | |
863 | ||
864 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) | |
865 | { | |
866 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
867 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
6fe7ccc8 A |
868 | setupArgumentsWithExecState(arg1, arg2, arg3); |
869 | } | |
870 | ||
871 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4) | |
872 | { | |
93a37866 | 873 | poke(arg4, POKE_ARGUMENT_OFFSET); |
6fe7ccc8 A |
874 | setupArgumentsWithExecState(arg1, arg2, arg3); |
875 | } | |
876 | ||
877 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4) | |
878 | { | |
93a37866 | 879 | poke(arg4, POKE_ARGUMENT_OFFSET); |
6fe7ccc8 A |
880 | setupArgumentsWithExecState(arg1, arg2, arg3); |
881 | } | |
882 | ||
883 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4) | |
884 | { | |
93a37866 | 885 | poke(arg4, POKE_ARGUMENT_OFFSET); |
6fe7ccc8 A |
886 | setupArgumentsWithExecState(arg1, arg2, arg3); |
887 | } | |
888 | ||
889 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) | |
890 | { | |
93a37866 A |
891 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); |
892 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
6fe7ccc8 A |
893 | setupArgumentsWithExecState(arg1, arg2, arg3); |
894 | } | |
93a37866 A |
895 | |
896 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4) | |
897 | { | |
898 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
899 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
900 | } | |
901 | ||
902 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4) | |
903 | { | |
904 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
905 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
906 | } | |
907 | ||
908 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4) | |
909 | { | |
910 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
911 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
912 | } | |
913 | ||
914 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4) | |
915 | { | |
916 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
917 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
918 | } | |
919 | ||
920 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) | |
921 | { | |
922 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
923 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
924 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
925 | } | |
926 | ||
927 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5) | |
928 | { | |
929 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
930 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
931 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
932 | } | |
933 | ||
934 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5) | |
935 | { | |
936 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
937 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
938 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
939 | } | |
940 | ||
941 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5) | |
942 | { | |
943 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
944 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
945 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
946 | } | |
947 | ||
948 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5) | |
949 | { | |
950 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
951 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
952 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
953 | } | |
954 | ||
955 | ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5) | |
956 | { | |
957 | poke(arg5, POKE_ARGUMENT_OFFSET + 1); | |
958 | poke(arg4, POKE_ARGUMENT_OFFSET); | |
959 | setupArgumentsWithExecState(arg1, arg2, arg3); | |
960 | } | |
961 | ||
6fe7ccc8 A |
962 | #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4 |
963 | ||
93a37866 A |
964 | #if NUMBER_OF_ARGUMENT_REGISTERS >= 5 |
965 | ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4) | |
966 | { | |
967 | setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4); | |
968 | move(arg2, GPRInfo::argumentGPR2); | |
969 | move(arg3, GPRInfo::argumentGPR3); | |
970 | move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); | |
971 | } | |
972 | #endif | |
973 | ||
6fe7ccc8 A |
974 | void setupResults(GPRReg destA, GPRReg destB) |
975 | { | |
976 | GPRReg srcA = GPRInfo::returnValueGPR; | |
977 | GPRReg srcB = GPRInfo::returnValueGPR2; | |
978 | ||
979 | if (srcB != destA) { | |
980 | // Handle the easy cases - two simple moves. | |
981 | move(srcA, destA); | |
982 | move(srcB, destB); | |
983 | } else if (srcA != destB) { | |
984 | // Handle the non-swap case - just put srcB in place first. | |
985 | move(srcB, destB); | |
986 | move(srcA, destA); | |
987 | } else | |
988 | swap(destA, destB); | |
989 | } | |
990 | }; | |
991 | ||
992 | } } // namespace JSC::DFG | |
993 | ||
994 | #endif // ENABLE(DFG_JIT) | |
995 | ||
996 | #endif // DFGCCallHelpers_h | |
997 |