]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGCCallHelpers.h
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef DFGCCallHelpers_h
27 #define DFGCCallHelpers_h
29 #include <wtf/Platform.h>
33 #include "DFGAssemblyHelpers.h"
34 #include "DFGGPRInfo.h"
36 namespace JSC
{ namespace DFG
{
38 class CCallHelpers
: public AssemblyHelpers
{
40 CCallHelpers(VM
* vm
, CodeBlock
* codeBlock
= 0)
41 : AssemblyHelpers(vm
, codeBlock
)
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
49 #if !NUMBER_OF_ARGUMENT_REGISTERS
50 unsigned m_callArgumentOffset
;
51 void resetCallArguments() { m_callArgumentOffset
= 0; }
53 // These methods are using internally to implement the callOperation methods.
54 void addCallArgument(GPRReg value
)
56 poke(value
, m_callArgumentOffset
++);
58 void addCallArgument(TrustedImm32 imm
)
60 poke(imm
, m_callArgumentOffset
++);
62 void addCallArgument(TrustedImmPtr pointer
)
64 poke(pointer
, m_callArgumentOffset
++);
66 void addCallArgument(FPRReg value
)
68 storeDouble(value
, Address(stackPointerRegister
, m_callArgumentOffset
* sizeof(void*)));
69 m_callArgumentOffset
+= sizeof(double) / sizeof(void*);
72 ALWAYS_INLINE
void setupArguments(FPRReg arg1
)
75 addCallArgument(arg1
);
78 ALWAYS_INLINE
void setupArguments(FPRReg arg1
, FPRReg arg2
)
81 addCallArgument(arg1
);
82 addCallArgument(arg2
);
85 ALWAYS_INLINE
void setupArguments(GPRReg arg1
)
88 addCallArgument(arg1
);
91 ALWAYS_INLINE
void setupArguments(GPRReg arg1
, GPRReg arg2
)
94 addCallArgument(arg1
);
95 addCallArgument(arg2
);
98 ALWAYS_INLINE
void setupArguments(TrustedImmPtr arg1
)
100 resetCallArguments();
101 addCallArgument(arg1
);
104 ALWAYS_INLINE
void setupArgumentsExecState()
106 resetCallArguments();
107 addCallArgument(GPRInfo::callFrameRegister
);
110 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
)
112 resetCallArguments();
113 addCallArgument(GPRInfo::callFrameRegister
);
114 addCallArgument(arg1
);
117 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
)
119 resetCallArguments();
120 addCallArgument(GPRInfo::callFrameRegister
);
121 addCallArgument(arg1
);
124 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
)
126 resetCallArguments();
127 addCallArgument(GPRInfo::callFrameRegister
);
128 addCallArgument(arg1
);
131 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
)
133 resetCallArguments();
134 addCallArgument(GPRInfo::callFrameRegister
);
135 addCallArgument(arg1
);
136 addCallArgument(arg2
);
139 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
)
141 resetCallArguments();
142 addCallArgument(GPRInfo::callFrameRegister
);
143 addCallArgument(arg1
);
144 addCallArgument(arg2
);
147 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
)
149 resetCallArguments();
150 addCallArgument(GPRInfo::callFrameRegister
);
151 addCallArgument(arg1
);
152 addCallArgument(arg2
);
155 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
)
157 resetCallArguments();
158 addCallArgument(GPRInfo::callFrameRegister
);
159 addCallArgument(arg1
);
160 addCallArgument(arg2
);
163 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, GPRReg arg2
)
165 resetCallArguments();
166 addCallArgument(GPRInfo::callFrameRegister
);
167 addCallArgument(arg1
);
168 addCallArgument(arg2
);
171 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
)
173 resetCallArguments();
174 addCallArgument(GPRInfo::callFrameRegister
);
175 addCallArgument(arg1
);
176 addCallArgument(arg2
);
179 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImmPtr arg2
)
181 resetCallArguments();
182 addCallArgument(GPRInfo::callFrameRegister
);
183 addCallArgument(arg1
);
184 addCallArgument(arg2
);
187 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImm32 arg2
)
189 resetCallArguments();
190 addCallArgument(GPRInfo::callFrameRegister
);
191 addCallArgument(arg1
);
192 addCallArgument(arg2
);
195 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
197 resetCallArguments();
198 addCallArgument(GPRInfo::callFrameRegister
);
199 addCallArgument(arg1
);
200 addCallArgument(arg2
);
201 addCallArgument(arg3
);
204 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImmPtr arg3
)
206 resetCallArguments();
207 addCallArgument(GPRInfo::callFrameRegister
);
208 addCallArgument(arg1
);
209 addCallArgument(arg2
);
210 addCallArgument(arg3
);
213 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
, GPRReg arg3
)
215 resetCallArguments();
216 addCallArgument(GPRInfo::callFrameRegister
);
217 addCallArgument(arg1
);
218 addCallArgument(arg2
);
219 addCallArgument(arg3
);
222 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
, TrustedImmPtr arg3
)
224 resetCallArguments();
225 addCallArgument(GPRInfo::callFrameRegister
);
226 addCallArgument(arg1
);
227 addCallArgument(arg2
);
228 addCallArgument(arg3
);
231 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImmPtr arg2
, TrustedImmPtr arg3
)
233 resetCallArguments();
234 addCallArgument(GPRInfo::callFrameRegister
);
235 addCallArgument(arg1
);
236 addCallArgument(arg2
);
237 addCallArgument(arg3
);
240 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImmPtr arg3
)
242 resetCallArguments();
243 addCallArgument(GPRInfo::callFrameRegister
);
244 addCallArgument(arg1
);
245 addCallArgument(arg2
);
246 addCallArgument(arg3
);
249 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
, GPRReg arg4
)
251 resetCallArguments();
252 addCallArgument(GPRInfo::callFrameRegister
);
253 addCallArgument(arg1
);
254 addCallArgument(arg2
);
255 addCallArgument(arg3
);
256 addCallArgument(arg4
);
259 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
, GPRReg arg4
, GPRReg arg5
)
261 resetCallArguments();
262 addCallArgument(GPRInfo::callFrameRegister
);
263 addCallArgument(arg1
);
264 addCallArgument(arg2
);
265 addCallArgument(arg3
);
266 addCallArgument(arg4
);
267 addCallArgument(arg5
);
270 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
)
272 resetCallArguments();
273 addCallArgument(GPRInfo::callFrameRegister
);
274 addCallArgument(arg1
);
275 addCallArgument(arg2
);
276 addCallArgument(arg3
);
277 addCallArgument(arg4
);
280 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImm32 arg4
)
282 resetCallArguments();
283 addCallArgument(GPRInfo::callFrameRegister
);
284 addCallArgument(arg1
);
285 addCallArgument(arg2
);
286 addCallArgument(arg3
);
287 addCallArgument(arg4
);
290 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImmPtr arg2
, GPRReg arg3
)
292 resetCallArguments();
293 addCallArgument(GPRInfo::callFrameRegister
);
294 addCallArgument(arg1
);
295 addCallArgument(arg2
);
296 addCallArgument(arg3
);
299 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImmPtr arg4
)
301 resetCallArguments();
302 addCallArgument(GPRInfo::callFrameRegister
);
303 addCallArgument(arg1
);
304 addCallArgument(arg2
);
305 addCallArgument(arg3
);
306 addCallArgument(arg4
);
309 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3
, TrustedImm32 arg4
)
311 resetCallArguments();
312 addCallArgument(GPRInfo::callFrameRegister
);
313 addCallArgument(arg1
);
314 addCallArgument(arg2
);
315 addCallArgument(arg3
);
316 addCallArgument(arg4
);
319 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
, GPRReg arg3
, GPRReg arg4
)
321 resetCallArguments();
322 addCallArgument(GPRInfo::callFrameRegister
);
323 addCallArgument(arg1
);
324 addCallArgument(arg2
);
325 addCallArgument(arg3
);
326 addCallArgument(arg4
);
329 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
, GPRReg arg5
)
331 resetCallArguments();
332 addCallArgument(GPRInfo::callFrameRegister
);
333 addCallArgument(arg1
);
334 addCallArgument(arg2
);
335 addCallArgument(arg3
);
336 addCallArgument(arg4
);
337 addCallArgument(arg5
);
340 ALWAYS_INLINE
void setupArgumentsWithExecState(FPRReg arg1
, GPRReg arg2
)
342 resetCallArguments();
343 addCallArgument(GPRInfo::callFrameRegister
);
344 addCallArgument(arg1
);
345 addCallArgument(arg2
);
348 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
350 resetCallArguments();
351 addCallArgument(GPRInfo::callFrameRegister
);
352 addCallArgument(arg1
);
353 addCallArgument(arg2
);
354 addCallArgument(arg3
);
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
)
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.
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.)
378 // Handle the easy cases - two simple moves.
381 } else if (srcA
!= destB
) {
382 // Handle the non-swap case - just put srcB in place first.
388 #if CPU(X86_64) || CPU(ARM64)
389 template<FPRReg destA
, FPRReg destB
>
390 void setupTwoStubArgs(FPRReg srcA
, FPRReg srcB
)
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.
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.)
407 // Handle the easy cases - two simple moves.
408 moveDouble(srcA
, destA
);
409 moveDouble(srcB
, destB
);
414 // Handle the non-swap case - just put srcB in place first.
415 moveDouble(srcB
, destB
);
416 moveDouble(srcA
, destA
);
420 ASSERT(srcB
== destA
&& srcA
== destB
);
421 // Need to swap; pick a temporary register.
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
;
428 ASSERT(destA
!= FPRInfo::argumentFPR1
&& destA
!= FPRInfo::argumentFPR1
);
429 temp
= FPRInfo::argumentFPR1
;
431 moveDouble(destA
, temp
);
432 moveDouble(destB
, destA
);
433 moveDouble(temp
, destB
);
436 void setupStubArguments(GPRReg arg1
, GPRReg arg2
)
438 setupTwoStubArgs
<GPRInfo::argumentGPR1
, GPRInfo::argumentGPR2
>(arg1
, arg2
);
440 void setupStubArguments(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
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
);
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
);
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
);
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?
470 // First, ensure arg1 is in place.
471 if (arg1
!= GPRInfo::argumentGPR1
) {
472 swap(arg1
, GPRInfo::argumentGPR1
);
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
)
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
));
488 if (arg2
!= GPRInfo::argumentGPR2
)
489 swap(GPRInfo::argumentGPR2
, GPRInfo::argumentGPR3
);
492 #if CPU(X86_64) || CPU(ARM64)
493 ALWAYS_INLINE
void setupArguments(FPRReg arg1
)
495 moveDouble(arg1
, FPRInfo::argumentFPR0
);
498 ALWAYS_INLINE
void setupArguments(FPRReg arg1
, FPRReg arg2
)
500 setupTwoStubArgs
<FPRInfo::argumentFPR0
, FPRInfo::argumentFPR1
>(arg1
, arg2
);
503 ALWAYS_INLINE
void setupArgumentsWithExecState(FPRReg arg1
, GPRReg arg2
)
505 moveDouble(arg1
, FPRInfo::argumentFPR0
);
506 move(arg2
, GPRInfo::argumentGPR1
);
507 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
510 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
512 moveDouble(arg3
, FPRInfo::argumentFPR0
);
513 setupStubArguments(arg1
, arg2
);
514 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
518 ALWAYS_INLINE
void setupArguments(FPRReg arg1
)
520 moveDouble(arg1
, FPRInfo::argumentFPR0
);
523 ALWAYS_INLINE
void setupArguments(FPRReg arg1
, FPRReg arg2
)
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
);
533 moveDouble(FPRInfo::argumentFPR0
, ARMRegisters::d2
);
534 moveDouble(FPRInfo::argumentFPR1
, FPRInfo::argumentFPR0
);
535 moveDouble(ARMRegisters::d2
, FPRInfo::argumentFPR1
);
539 ALWAYS_INLINE
void setupArgumentsWithExecState(FPRReg arg1
, GPRReg arg2
)
541 moveDouble(arg1
, FPRInfo::argumentFPR0
);
542 move(arg2
, GPRInfo::argumentGPR1
);
543 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
546 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
548 moveDouble(arg3
, FPRInfo::argumentFPR0
);
549 setupStubArguments(arg1
, arg2
);
550 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
553 ALWAYS_INLINE
void setupArguments(FPRReg arg1
)
555 assembler().vmov(GPRInfo::argumentGPR0
, GPRInfo::argumentGPR1
, arg1
);
558 ALWAYS_INLINE
void setupArguments(FPRReg arg1
, FPRReg arg2
)
560 assembler().vmov(GPRInfo::argumentGPR0
, GPRInfo::argumentGPR1
, arg1
);
561 assembler().vmov(GPRInfo::argumentGPR2
, GPRInfo::argumentGPR3
, arg2
);
564 ALWAYS_INLINE
void setupArgumentsWithExecState(FPRReg arg1
, GPRReg arg2
)
566 move(arg2
, GPRInfo::argumentGPR3
);
567 assembler().vmov(GPRInfo::argumentGPR1
, GPRInfo::argumentGPR2
, arg1
);
568 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
571 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
573 setupStubArguments(arg1
, arg2
);
574 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
575 assembler().vmov(GPRInfo::argumentGPR3
, GPRInfo::nonArgGPR0
, arg3
);
576 poke(GPRInfo::nonArgGPR0
);
578 #endif // CPU(ARM_HARDFP)
580 ALWAYS_INLINE
void setupArguments(FPRReg arg1
)
582 moveDouble(arg1
, FPRInfo::argumentFPR0
);
585 ALWAYS_INLINE
void setupArguments(FPRReg arg1
, FPRReg arg2
)
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
);
595 swapDouble(FPRInfo::argumentFPR0
, FPRInfo::argumentFPR1
);
599 ALWAYS_INLINE
void setupArgumentsWithExecState(FPRReg arg1
, GPRReg arg2
)
601 assembler().vmov(GPRInfo::argumentGPR2
, GPRInfo::argumentGPR3
, arg1
);
602 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
606 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
608 setupStubArguments(arg1
, arg2
);
609 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
613 #error "DFG JIT not supported on this platform."
616 ALWAYS_INLINE
void setupArguments(GPRReg arg1
)
618 move(arg1
, GPRInfo::argumentGPR0
);
621 ALWAYS_INLINE
void setupArguments(GPRReg arg1
, GPRReg arg2
)
623 setupTwoStubArgs
<GPRInfo::argumentGPR0
, GPRInfo::argumentGPR1
>(arg1
, arg2
);
626 ALWAYS_INLINE
void setupArguments(TrustedImmPtr arg1
)
628 move(arg1
, GPRInfo::argumentGPR0
);
631 ALWAYS_INLINE
void setupArgumentsExecState()
633 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
636 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
)
638 move(arg1
, GPRInfo::argumentGPR1
);
639 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
642 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
)
644 move(arg1
, GPRInfo::argumentGPR1
);
645 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
648 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
)
650 move(arg1
, GPRInfo::argumentGPR1
);
651 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
654 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
)
656 setupStubArguments(arg1
, arg2
);
657 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
660 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
)
662 move(arg1
, GPRInfo::argumentGPR1
);
663 move(arg2
, GPRInfo::argumentGPR2
);
664 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
666 #if CPU(X86_64) || CPU(ARM64)
667 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm64 arg2
)
669 move(arg1
, GPRInfo::argumentGPR1
);
670 move(arg2
, GPRInfo::argumentGPR2
);
671 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
674 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm64 arg1
, GPRReg arg2
)
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
);
681 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
)
683 move(arg1
, GPRInfo::argumentGPR1
);
684 move(arg2
, GPRInfo::argumentGPR2
);
685 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
688 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, ImmPtr arg2
)
690 move(arg1
, GPRInfo::argumentGPR1
);
691 move(arg2
, GPRInfo::argumentGPR2
);
692 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
695 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, GPRReg arg2
)
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
);
702 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
)
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
);
709 ALWAYS_INLINE
void setupArgumentsWithExecState(ImmPtr arg1
, GPRReg arg2
)
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
);
716 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
)
718 move(arg1
, GPRInfo::argumentGPR1
);
719 move(arg2
, GPRInfo::argumentGPR2
);
720 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
723 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImmPtr arg2
)
725 move(arg1
, GPRInfo::argumentGPR1
);
726 move(arg2
, GPRInfo::argumentGPR2
);
727 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
730 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImm32 arg2
)
732 move(arg1
, GPRInfo::argumentGPR1
);
733 move(arg2
, GPRInfo::argumentGPR2
);
734 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
737 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
739 setupStubArguments(arg1
, arg2
, arg3
);
740 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
743 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3
)
745 setupStubArguments(arg1
, arg2
);
746 move(arg3
, GPRInfo::argumentGPR3
);
747 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
750 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
, GPRReg arg3
)
752 setupTwoStubArgs
<GPRInfo::argumentGPR1
, GPRInfo::argumentGPR3
>(arg1
, arg3
);
753 move(arg2
, GPRInfo::argumentGPR2
);
754 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
757 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImm32 arg2
, TrustedImmPtr arg3
)
759 move(arg1
, GPRInfo::argumentGPR1
);
760 move(arg2
, GPRInfo::argumentGPR2
);
761 move(arg3
, GPRInfo::argumentGPR3
);
762 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
765 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
)
767 move(arg1
, GPRInfo::argumentGPR1
);
768 move(arg2
, GPRInfo::argumentGPR2
);
769 move(arg3
, GPRInfo::argumentGPR3
);
770 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
773 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImmPtr arg3
)
775 move(arg1
, GPRInfo::argumentGPR1
);
776 move(arg2
, GPRInfo::argumentGPR2
);
777 move(arg3
, GPRInfo::argumentGPR3
);
778 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
781 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImmPtr arg3
)
783 setupStubArguments(arg1
, arg2
);
784 move(arg3
, GPRInfo::argumentGPR3
);
785 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
788 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
, GPRReg arg3
)
790 move(arg3
, GPRInfo::argumentGPR3
);
791 move(arg1
, GPRInfo::argumentGPR1
);
792 move(arg2
, GPRInfo::argumentGPR2
);
793 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
796 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImmPtr arg2
, GPRReg arg3
)
798 move(arg3
, GPRInfo::argumentGPR3
);
799 move(arg1
, GPRInfo::argumentGPR1
);
800 move(arg2
, GPRInfo::argumentGPR2
);
801 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
804 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, TrustedImm32 arg3
)
806 move(arg2
, GPRInfo::argumentGPR2
);
807 move(arg1
, GPRInfo::argumentGPR1
);
808 move(arg3
, GPRInfo::argumentGPR3
);
809 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
812 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
)
814 setupTwoStubArgs
<GPRInfo::argumentGPR2
, GPRInfo::argumentGPR3
>(arg2
, arg3
);
815 move(arg1
, GPRInfo::argumentGPR1
);
816 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
819 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImmPtr arg1
, TrustedImmPtr arg2
, TrustedImmPtr arg3
)
821 move(arg1
, GPRInfo::argumentGPR1
);
822 move(arg2
, GPRInfo::argumentGPR2
);
823 move(arg3
, GPRInfo::argumentGPR3
);
824 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
827 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
, TrustedImm32 arg3
)
829 move(arg1
, GPRInfo::argumentGPR1
);
830 move(arg2
, GPRInfo::argumentGPR2
);
831 move(arg3
, GPRInfo::argumentGPR3
);
832 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
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
841 #define POKE_ARGUMENT_OFFSET 4
843 #define POKE_ARGUMENT_OFFSET 0
846 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
)
848 poke(arg4
, POKE_ARGUMENT_OFFSET
);
849 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
852 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImm32 arg4
)
854 poke(arg4
, POKE_ARGUMENT_OFFSET
);
855 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
858 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
, GPRReg arg4
)
860 poke(arg4
, POKE_ARGUMENT_OFFSET
);
861 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
864 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
, GPRReg arg4
, GPRReg arg5
)
866 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
867 poke(arg4
, POKE_ARGUMENT_OFFSET
);
868 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
871 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3
, TrustedImm32 arg4
)
873 poke(arg4
, POKE_ARGUMENT_OFFSET
);
874 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
877 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
, GPRReg arg3
, GPRReg arg4
)
879 poke(arg4
, POKE_ARGUMENT_OFFSET
);
880 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
883 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImmPtr arg4
)
885 poke(arg4
, POKE_ARGUMENT_OFFSET
);
886 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
889 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
, GPRReg arg5
)
891 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
892 poke(arg4
, POKE_ARGUMENT_OFFSET
);
893 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
896 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
)
898 poke(arg4
, POKE_ARGUMENT_OFFSET
);
899 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
902 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImmPtr arg4
)
904 poke(arg4
, POKE_ARGUMENT_OFFSET
);
905 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
908 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, TrustedImm32 arg3
, TrustedImmPtr arg4
)
910 poke(arg4
, POKE_ARGUMENT_OFFSET
);
911 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
914 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, TrustedImm32 arg3
, GPRReg arg4
)
916 poke(arg4
, POKE_ARGUMENT_OFFSET
);
917 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
920 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3
, GPRReg arg4
, GPRReg arg5
)
922 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
923 poke(arg4
, POKE_ARGUMENT_OFFSET
);
924 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
927 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3
, GPRReg arg4
, TrustedImm32 arg5
)
929 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
930 poke(arg4
, POKE_ARGUMENT_OFFSET
);
931 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
934 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
, TrustedImmPtr arg5
)
936 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
937 poke(arg4
, POKE_ARGUMENT_OFFSET
);
938 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
941 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
, TrustedImm32 arg4
, TrustedImm32 arg5
)
943 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
944 poke(arg4
, POKE_ARGUMENT_OFFSET
);
945 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
948 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, TrustedImm32 arg2
, TrustedImm32 arg3
, GPRReg arg4
, GPRReg arg5
)
950 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
951 poke(arg4
, POKE_ARGUMENT_OFFSET
);
952 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
955 ALWAYS_INLINE
void setupArgumentsWithExecState(TrustedImm32 arg1
, GPRReg arg2
, GPRReg arg3
, GPRReg arg4
, GPRReg arg5
)
957 poke(arg5
, POKE_ARGUMENT_OFFSET
+ 1);
958 poke(arg4
, POKE_ARGUMENT_OFFSET
);
959 setupArgumentsWithExecState(arg1
, arg2
, arg3
);
962 #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
964 #if NUMBER_OF_ARGUMENT_REGISTERS >= 5
965 ALWAYS_INLINE
void setupArgumentsWithExecState(GPRReg arg1
, TrustedImmPtr arg2
, TrustedImm32 arg3
, GPRReg arg4
)
967 setupTwoStubArgs
<GPRInfo::argumentGPR1
, GPRInfo::argumentGPR4
>(arg1
, arg4
);
968 move(arg2
, GPRInfo::argumentGPR2
);
969 move(arg3
, GPRInfo::argumentGPR3
);
970 move(GPRInfo::callFrameRegister
, GPRInfo::argumentGPR0
);
974 void setupResults(GPRReg destA
, GPRReg destB
)
976 GPRReg srcA
= GPRInfo::returnValueGPR
;
977 GPRReg srcB
= GPRInfo::returnValueGPR2
;
980 // Handle the easy cases - two simple moves.
983 } else if (srcA
!= destB
) {
984 // Handle the non-swap case - just put srcB in place first.
992 } } // namespace JSC::DFG
994 #endif // ENABLE(DFG_JIT)
996 #endif // DFGCCallHelpers_h