80b059e9c97b8f72a9c315bb5f709688fc217b2d
[WebKit-https.git] / Source / JavaScriptCore / jit / CCallHelpers.h
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 CCallHelpers_h
27 #define CCallHelpers_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(JIT)
32
33 #include "AssemblyHelpers.h"
34 #include "GPRInfo.h"
35
36 namespace JSC {
37
38 class CCallHelpers : public AssemblyHelpers {
39 public:
40     CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
41         : AssemblyHelpers(vm, codeBlock)
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     }
97     
98     ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
99     {
100         resetCallArguments();
101         addCallArgument(arg1);
102     }
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
124     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
125     {
126         resetCallArguments();
127         addCallArgument(GPRInfo::callFrameRegister);
128         addCallArgument(arg1);
129     }
130
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
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
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
187     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
188     {
189         resetCallArguments();
190         addCallArgument(GPRInfo::callFrameRegister);
191         addCallArgument(arg1);
192         addCallArgument(arg2);
193     }
194
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
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
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
231     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3)
232     {
233         resetCallArguments();
234         addCallArgument(GPRInfo::callFrameRegister);
235         addCallArgument(arg1);
236         addCallArgument(arg2);
237         addCallArgument(arg3);
238     }
239
240     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
241     {
242         resetCallArguments();
243         addCallArgument(GPRInfo::callFrameRegister);
244         addCallArgument(arg1);
245         addCallArgument(arg2);
246         addCallArgument(arg3);
247     }
248
249     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
250     {
251         resetCallArguments();
252         addCallArgument(GPRInfo::callFrameRegister);
253         addCallArgument(arg1);
254         addCallArgument(arg2);
255         addCallArgument(arg3);
256     }
257
258     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
259     {
260         resetCallArguments();
261         addCallArgument(GPRInfo::callFrameRegister);
262         addCallArgument(arg1);
263         addCallArgument(arg2);
264         addCallArgument(arg3);
265         addCallArgument(arg4);
266     }
267
268     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
269     {
270         resetCallArguments();
271         addCallArgument(GPRInfo::callFrameRegister);
272         addCallArgument(arg1);
273         addCallArgument(arg2);
274         addCallArgument(arg3);
275         addCallArgument(arg4);
276         addCallArgument(arg5);
277     }
278
279     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
280     {
281         resetCallArguments();
282         addCallArgument(GPRInfo::callFrameRegister);
283         addCallArgument(arg1);
284         addCallArgument(arg2);
285         addCallArgument(arg3);
286         addCallArgument(arg4);
287     }
288
289     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
290     {
291         resetCallArguments();
292         addCallArgument(GPRInfo::callFrameRegister);
293         addCallArgument(arg1);
294         addCallArgument(arg2);
295         addCallArgument(arg3);
296         addCallArgument(arg4);
297     }
298
299     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
300     {
301         resetCallArguments();
302         addCallArgument(GPRInfo::callFrameRegister);
303         addCallArgument(arg1);
304         addCallArgument(arg2);
305         addCallArgument(arg3);
306     }
307
308     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
309     {
310         resetCallArguments();
311         addCallArgument(GPRInfo::callFrameRegister);
312         addCallArgument(arg1);
313         addCallArgument(arg2);
314         addCallArgument(arg3);
315         addCallArgument(arg4);
316     }
317
318     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
319     {
320         resetCallArguments();
321         addCallArgument(GPRInfo::callFrameRegister);
322         addCallArgument(arg1);
323         addCallArgument(arg2);
324         addCallArgument(arg3);
325         addCallArgument(arg4);
326     }
327
328     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
329     {
330         resetCallArguments();
331         addCallArgument(GPRInfo::callFrameRegister);
332         addCallArgument(arg1);
333         addCallArgument(arg2);
334         addCallArgument(arg3);
335         addCallArgument(arg4);
336     }
337
338     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
339     {
340         resetCallArguments();
341         addCallArgument(GPRInfo::callFrameRegister);
342         addCallArgument(arg1);
343         addCallArgument(arg2);
344         addCallArgument(arg3);
345         addCallArgument(arg4);
346         addCallArgument(arg5);
347     }
348
349     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
350     {
351         resetCallArguments();
352         addCallArgument(GPRInfo::callFrameRegister);
353         addCallArgument(arg1);
354         addCallArgument(arg2);
355     }
356
357     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
358     {
359         resetCallArguments();
360         addCallArgument(GPRInfo::callFrameRegister);
361         addCallArgument(arg1);
362         addCallArgument(arg2);
363         addCallArgument(arg3);
364     }
365 #endif // !NUMBER_OF_ARGUMENT_REGISTERS
366     // These methods are suitable for any calling convention that provides for
367     // at least 4 argument registers, e.g. X86_64, ARMv7.
368 #if NUMBER_OF_ARGUMENT_REGISTERS >= 4
369     template<GPRReg destA, GPRReg destB>
370     void setupTwoStubArgsGPR(GPRReg srcA, GPRReg srcB)
371     {
372         // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
373         // (1) both are already in arg regs, the right way around.
374         // (2) both are already in arg regs, the wrong way around.
375         // (3) neither are currently in arg registers.
376         // (4) srcA in in its correct reg.
377         // (5) srcA in in the incorrect reg.
378         // (6) srcB in in its correct reg.
379         // (7) srcB in in the incorrect reg.
380         //
381         // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
382         // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
383         // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
384         // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
385
386         if (srcB != destA) {
387             // Handle the easy cases - two simple moves.
388             move(srcA, destA);
389             move(srcB, destB);
390         } else if (srcA != destB) {
391             // Handle the non-swap case - just put srcB in place first.
392             move(srcB, destB);
393             move(srcA, destA);
394         } else
395             swap(destA, destB);
396     }
397 #if CPU(X86_64)
398     template<FPRReg destA, FPRReg destB>
399     void setupTwoStubArgsFPR(FPRReg srcA, FPRReg srcB)
400     {
401         // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
402         // (1) both are already in arg regs, the right way around.
403         // (2) both are already in arg regs, the wrong way around.
404         // (3) neither are currently in arg registers.
405         // (4) srcA in in its correct reg.
406         // (5) srcA in in the incorrect reg.
407         // (6) srcB in in its correct reg.
408         // (7) srcB in in the incorrect reg.
409         //
410         // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
411         // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
412         // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
413         // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
414
415         if (srcB != destA) {
416             // Handle the easy cases - two simple moves.
417             moveDouble(srcA, destA);
418             moveDouble(srcB, destB);
419             return;
420         }
421         
422         if (srcA != destB) {
423             // Handle the non-swap case - just put srcB in place first.
424             moveDouble(srcB, destB);
425             moveDouble(srcA, destA);
426             return;
427         }
428
429         ASSERT(srcB == destA && srcA == destB);
430         // Need to swap; pick a temporary register.
431         FPRReg temp;
432         if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3)
433             temp = FPRInfo::argumentFPR3;
434         else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2)
435             temp = FPRInfo::argumentFPR2;
436         else {
437             ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1);
438             temp = FPRInfo::argumentFPR1;
439         }
440         moveDouble(destA, temp);
441         moveDouble(destB, destA);
442         moveDouble(temp, destB);
443     }
444 #endif
445     void setupStubArguments(GPRReg arg1, GPRReg arg2)
446     {
447         setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
448     }
449     void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
450     {
451         // If neither of arg2/arg3 are in our way, then we can move arg1 into place.
452         // Then we can use setupTwoStubArgs to fix arg2/arg3.
453         if (arg2 != GPRInfo::argumentGPR1 && arg3 != GPRInfo::argumentGPR1) {
454             move(arg1, GPRInfo::argumentGPR1);
455             setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
456             return;
457         }
458
459         // If neither of arg1/arg3 are in our way, then we can move arg2 into place.
460         // Then we can use setupTwoStubArgs to fix arg1/arg3.
461         if (arg1 != GPRInfo::argumentGPR2 && arg3 != GPRInfo::argumentGPR2) {
462             move(arg2, GPRInfo::argumentGPR2);
463             setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
464             return;
465         }
466
467         // If neither of arg1/arg2 are in our way, then we can move arg3 into place.
468         // Then we can use setupTwoStubArgs to fix arg1/arg2.
469         if (arg1 != GPRInfo::argumentGPR3 && arg2 != GPRInfo::argumentGPR3) {
470             move(arg3, GPRInfo::argumentGPR3);
471             setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
472             return;
473         }
474
475         // If we get here, we haven't been able to move any of arg1/arg2/arg3.
476         // Since all three are blocked, then all three must already be in the argument register.
477         // But are they in the right ones?
478
479         // First, ensure arg1 is in place.
480         if (arg1 != GPRInfo::argumentGPR1) {
481             swap(arg1, GPRInfo::argumentGPR1);
482
483             // If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be.
484             ASSERT(arg2 == GPRInfo::argumentGPR1 || arg3 == GPRInfo::argumentGPR1);
485             // If arg2 was in argumentGPR1 it no longer is (due to the swap).
486             // Otherwise arg3 must have been. Mark him as moved.
487             if (arg2 == GPRInfo::argumentGPR1)
488                 arg2 = arg1;
489             else
490                 arg3 = arg1;
491         }
492
493         // Either arg2 & arg3 need swapping, or we're all done.
494         ASSERT((arg2 == GPRInfo::argumentGPR2 || arg3 == GPRInfo::argumentGPR3)
495             || (arg2 == GPRInfo::argumentGPR3 || arg3 == GPRInfo::argumentGPR2));
496
497         if (arg2 != GPRInfo::argumentGPR2)
498             swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3);
499     }
500
501 #if CPU(MIPS)
502 #define POKE_ARGUMENT_OFFSET 4
503 #else
504 #define POKE_ARGUMENT_OFFSET 0
505 #endif
506
507 #if CPU(X86_64)
508     ALWAYS_INLINE void setupArguments(FPRReg arg1)
509     {
510         moveDouble(arg1, FPRInfo::argumentFPR0);
511     }
512
513     ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
514     {
515         setupTwoStubArgsFPR<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
516     }
517     
518     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
519     {
520         moveDouble(arg1, FPRInfo::argumentFPR0);
521         move(arg2, GPRInfo::argumentGPR1);
522         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
523     }
524
525     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
526     {
527         moveDouble(arg3, FPRInfo::argumentFPR0);
528         setupStubArguments(arg1, arg2);
529         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
530     }
531 #elif CPU(ARM)
532 #if CPU(ARM_HARDFP)
533     ALWAYS_INLINE void setupArguments(FPRReg arg1)
534     {
535         moveDouble(arg1, FPRInfo::argumentFPR0);
536     }
537
538     ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
539     {
540         if (arg2 != FPRInfo::argumentFPR0) {
541             moveDouble(arg1, FPRInfo::argumentFPR0);
542             moveDouble(arg2, FPRInfo::argumentFPR1);
543         } else if (arg1 != FPRInfo::argumentFPR1) {
544             moveDouble(arg2, FPRInfo::argumentFPR1);
545             moveDouble(arg1, FPRInfo::argumentFPR0);
546         } else {
547             // Swap arg1, arg2.
548             moveDouble(FPRInfo::argumentFPR0, ARMRegisters::d2);
549             moveDouble(FPRInfo::argumentFPR1, FPRInfo::argumentFPR0);
550             moveDouble(ARMRegisters::d2, FPRInfo::argumentFPR1);
551         }
552     }
553
554     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
555     {
556         moveDouble(arg1, FPRInfo::argumentFPR0);
557         move(arg2, GPRInfo::argumentGPR1);
558         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
559     }
560
561     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
562     {
563         moveDouble(arg3, FPRInfo::argumentFPR0);
564         setupStubArguments(arg1, arg2);
565         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
566     }
567
568     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32, FPRReg arg2, GPRReg arg3)
569     {
570         moveDouble(arg2, FPRInfo::argumentFPR0);
571         move(arg3, GPRInfo::argumentGPR1);
572         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
573     }
574
575     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32, FPRReg arg4)
576     {
577         moveDouble(arg4, FPRInfo::argumentFPR0);
578         setupStubArguments(arg1, arg2);
579         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
580     }
581
582 #else
583     ALWAYS_INLINE void setupArguments(FPRReg arg1)
584     {
585         assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
586     }
587
588     ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
589     {
590         assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
591         assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
592     }
593
594     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
595     {
596         move(arg2, GPRInfo::argumentGPR3);
597         assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1);
598         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
599     }
600
601     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
602     {
603         setupStubArguments(arg1, arg2);
604         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
605         assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3);
606         poke(GPRInfo::nonArgGPR0);
607     }
608
609     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, FPRReg arg2, GPRReg arg3)
610     {
611         poke(arg3, POKE_ARGUMENT_OFFSET);
612         move(arg1, GPRInfo::argumentGPR1);
613         assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
614         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
615     }
616
617     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, FPRReg arg4)
618     {
619         setupStubArguments(arg1, arg2);
620         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
621         move(arg3, GPRInfo::argumentGPR3);
622         assembler().vmov(GPRInfo::nonArgGPR0, GPRInfo::nonArgGPR1, arg4);
623         poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET);
624         poke(GPRInfo::nonArgGPR1, POKE_ARGUMENT_OFFSET + 1);
625     }
626 #endif // CPU(ARM_HARDFP)
627 #elif CPU(MIPS)
628     ALWAYS_INLINE void setupArguments(FPRReg arg1)
629     {
630         moveDouble(arg1, FPRInfo::argumentFPR0);
631     }
632
633     ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
634     {
635         if (arg2 != FPRInfo::argumentFPR0) {
636             moveDouble(arg1, FPRInfo::argumentFPR0);
637             moveDouble(arg2, FPRInfo::argumentFPR1);
638         } else if (arg1 != FPRInfo::argumentFPR1) {
639             moveDouble(arg2, FPRInfo::argumentFPR1);
640             moveDouble(arg1, FPRInfo::argumentFPR0);
641         } else {
642             // Swap arg1, arg2.
643             swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
644         }
645     }
646
647     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
648     {
649         assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
650         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
651         poke(arg2, 4);
652     }
653
654     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
655     {
656         setupStubArguments(arg1, arg2);
657         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
658         poke(arg3, 4);
659     }
660
661     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, FPRReg arg2, GPRReg arg3)
662     {
663         setupArgumentsWithExecState(arg2, arg3);
664     }
665
666     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, FPRReg arg4)
667     {
668         setupArgumentsWithExecState(arg1, arg2, arg4);
669     }
670 #elif CPU(SH4)
671     ALWAYS_INLINE void setupArguments(FPRReg arg1)
672     {
673         moveDouble(arg1, FPRInfo::argumentFPR0);
674     }
675
676     ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
677     {
678         if (arg2 != FPRInfo::argumentFPR0) {
679             moveDouble(arg1, FPRInfo::argumentFPR0);
680             moveDouble(arg2, FPRInfo::argumentFPR1);
681         } else if (arg1 != FPRInfo::argumentFPR1) {
682             moveDouble(arg2, FPRInfo::argumentFPR1);
683             moveDouble(arg1, FPRInfo::argumentFPR0);
684         } else
685             swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
686     }
687
688     ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
689     {
690         moveDouble(arg1, FPRInfo::argumentFPR0);
691         move(arg2, GPRInfo::argumentGPR1);
692         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
693     }
694
695     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
696     {
697         moveDouble(arg3, FPRInfo::argumentFPR0);
698         setupStubArguments(arg1, arg2);
699         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
700     }
701 #else
702 #error "JIT not supported on this platform."
703 #endif
704
705     ALWAYS_INLINE void setupArguments(GPRReg arg1)
706     {
707         move(arg1, GPRInfo::argumentGPR0);
708     }
709
710     ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
711     {
712         setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
713     }
714     
715     ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
716     {
717         move(arg1, GPRInfo::argumentGPR0);
718     }
719
720     ALWAYS_INLINE void setupArgumentsExecState()
721     {
722         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
723     }
724
725     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
726     {
727         move(arg1, GPRInfo::argumentGPR1);
728         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
729     }
730
731     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
732     {
733         move(arg1, GPRInfo::argumentGPR1);
734         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
735     }
736
737     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
738     {
739         move(arg1, GPRInfo::argumentGPR1);
740         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
741     }
742
743     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
744     {
745         setupStubArguments(arg1, arg2);
746         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
747     }
748
749     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
750     {
751         move(arg1, GPRInfo::argumentGPR1);
752         move(arg2, GPRInfo::argumentGPR2);
753         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
754     }
755 #if CPU(X86_64)    
756     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm64 arg2)
757     {
758         move(arg1, GPRInfo::argumentGPR1);
759         move(arg2, GPRInfo::argumentGPR2);
760         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
761     }
762     
763     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm64 arg1, GPRReg arg2)
764     {
765         move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
766         move(arg1, GPRInfo::argumentGPR1);
767         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
768     }
769 #endif
770     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
771     {
772         move(arg1, GPRInfo::argumentGPR1);
773         move(arg2, GPRInfo::argumentGPR2);
774         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
775     }
776     
777     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2)
778     {
779         move(arg1, GPRInfo::argumentGPR1);
780         move(arg2, GPRInfo::argumentGPR2);
781         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
782     }
783
784     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
785     {
786         move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
787         move(arg1, GPRInfo::argumentGPR1);
788         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
789     }
790     
791     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
792     {
793         move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
794         move(arg1, GPRInfo::argumentGPR1);
795         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
796     }
797     
798     ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2)
799     {
800         move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
801         move(arg1, GPRInfo::argumentGPR1);
802         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
803     }
804
805     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
806     {
807         move(arg1, GPRInfo::argumentGPR1);
808         move(arg2, GPRInfo::argumentGPR2);
809         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
810     }
811
812     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
813     {
814         move(arg1, GPRInfo::argumentGPR1);
815         move(arg2, GPRInfo::argumentGPR2);
816         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
817     }
818
819     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
820     {
821         move(arg1, GPRInfo::argumentGPR1);
822         move(arg2, GPRInfo::argumentGPR2);
823         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
824     }
825
826     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
827     {
828         setupStubArguments(arg1, arg2, arg3);
829         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
830     }
831
832     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
833     {
834         setupStubArguments(arg1, arg2);
835         move(arg3, GPRInfo::argumentGPR3);
836         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
837     }
838
839     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
840     {
841         setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
842         move(arg2, GPRInfo::argumentGPR2);
843         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
844     }
845
846     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
847     {
848         move(arg1, GPRInfo::argumentGPR1);
849         move(arg2, GPRInfo::argumentGPR2);
850         move(arg3, GPRInfo::argumentGPR3);
851         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
852     }
853
854     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
855     {
856         move(arg1, GPRInfo::argumentGPR1);
857         move(arg2, GPRInfo::argumentGPR2);
858         move(arg3, GPRInfo::argumentGPR3);
859         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
860     }
861
862     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
863     {
864         move(arg1, GPRInfo::argumentGPR1);
865         move(arg2, GPRInfo::argumentGPR2);
866         move(arg3, GPRInfo::argumentGPR3);
867         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
868     }
869
870     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
871     {
872         setupStubArguments(arg1, arg2);
873         move(arg3, GPRInfo::argumentGPR3);
874         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
875     }
876
877     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
878     {
879         move(arg3, GPRInfo::argumentGPR3);
880         move(arg1, GPRInfo::argumentGPR1);
881         move(arg2, GPRInfo::argumentGPR2);
882         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
883     }
884
885     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
886     {
887         move(arg3, GPRInfo::argumentGPR3);
888         move(arg1, GPRInfo::argumentGPR1);
889         move(arg2, GPRInfo::argumentGPR2);
890         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
891     }
892
893     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3)
894     {
895         move(arg2, GPRInfo::argumentGPR2);
896         move(arg1, GPRInfo::argumentGPR1);
897         move(arg3, GPRInfo::argumentGPR3);
898         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
899     }
900
901     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3)
902     {
903         setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
904         move(arg1, GPRInfo::argumentGPR1);
905         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
906     }
907
908     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3)
909     {
910         setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
911         move(arg1, GPRInfo::argumentGPR1);
912         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
913     }
914
915     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
916     {
917         move(arg1, GPRInfo::argumentGPR1);
918         move(arg2, GPRInfo::argumentGPR2);
919         move(arg3, GPRInfo::argumentGPR3);
920         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
921     }
922
923     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3)
924     {
925         move(arg1, GPRInfo::argumentGPR1);
926         move(arg2, GPRInfo::argumentGPR2);
927         move(arg3, GPRInfo::argumentGPR3);
928         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
929     }
930
931 #endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
932     // These methods are suitable for any calling convention that provides for
933     // exactly 4 argument registers, e.g. ARMv7.
934 #if NUMBER_OF_ARGUMENT_REGISTERS == 4
935
936     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
937     {
938         poke(arg4, POKE_ARGUMENT_OFFSET);
939         setupArgumentsWithExecState(arg1, arg2, arg3);
940     }
941
942     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
943     {
944         poke(arg4, POKE_ARGUMENT_OFFSET);
945         setupArgumentsWithExecState(arg1, arg2, arg3);
946     }
947
948     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
949     {
950         poke(arg4, POKE_ARGUMENT_OFFSET);
951         setupArgumentsWithExecState(arg1, arg2, arg3);
952     }
953
954     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
955     {
956         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
957         poke(arg4, POKE_ARGUMENT_OFFSET);
958         setupArgumentsWithExecState(arg1, arg2, arg3);
959     }
960
961     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
962     {
963         poke(arg4, POKE_ARGUMENT_OFFSET);
964         setupArgumentsWithExecState(arg1, arg2, arg3);
965     }
966
967     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4, TrustedImm32 arg5)
968     {
969         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
970         poke(arg4, POKE_ARGUMENT_OFFSET);
971         setupArgumentsWithExecState(arg1, arg2, arg3);
972     }
973
974     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
975     {
976         poke(arg4, POKE_ARGUMENT_OFFSET);
977         setupArgumentsWithExecState(arg1, arg2, arg3);
978     }
979
980     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
981     {
982         poke(arg4, POKE_ARGUMENT_OFFSET);
983         setupArgumentsWithExecState(arg1, arg2, arg3);
984     }
985
986     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
987     {
988         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
989         poke(arg4, POKE_ARGUMENT_OFFSET);
990         setupArgumentsWithExecState(arg1, arg2, arg3);
991     }
992
993     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
994     {
995         poke(arg4, POKE_ARGUMENT_OFFSET);
996         setupArgumentsWithExecState(arg1, arg2, arg3);
997     }
998
999     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1000     {
1001         poke(arg4, POKE_ARGUMENT_OFFSET);
1002         setupArgumentsWithExecState(arg1, arg2, arg3);
1003     }
1004
1005     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
1006     {
1007         poke(arg4, POKE_ARGUMENT_OFFSET);
1008         setupArgumentsWithExecState(arg1, arg2, arg3);
1009     }
1010
1011     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
1012     {
1013         poke(arg4, POKE_ARGUMENT_OFFSET);
1014         setupArgumentsWithExecState(arg1, arg2, arg3);
1015     }
1016
1017     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1018     {
1019         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1020         poke(arg4, POKE_ARGUMENT_OFFSET);
1021         setupArgumentsWithExecState(arg1, arg2, arg3);
1022     }
1023
1024     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
1025     {
1026         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1027         poke(arg4, POKE_ARGUMENT_OFFSET);
1028         setupArgumentsWithExecState(arg1, arg2, arg3);
1029     }
1030
1031     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
1032     {
1033         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1034         poke(arg4, POKE_ARGUMENT_OFFSET);
1035         setupArgumentsWithExecState(arg1, arg2, arg3);
1036     }
1037
1038     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
1039     {
1040         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1041         poke(arg4, POKE_ARGUMENT_OFFSET);
1042         setupArgumentsWithExecState(arg1, arg2, arg3);
1043     }
1044
1045     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1046     {
1047         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1048         poke(arg4, POKE_ARGUMENT_OFFSET);
1049         setupArgumentsWithExecState(arg1, arg2, arg3);
1050     }
1051
1052     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
1053     {
1054         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1055         poke(arg4, POKE_ARGUMENT_OFFSET);
1056         setupArgumentsWithExecState(arg1, arg2, arg3);
1057     }
1058
1059 #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
1060
1061 #if NUMBER_OF_ARGUMENT_REGISTERS >= 5
1062     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
1063     {
1064         setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4);
1065         move(arg2, GPRInfo::argumentGPR2);
1066         move(arg3, GPRInfo::argumentGPR3);
1067         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1068     }
1069 #endif
1070
1071     void setupResults(GPRReg destA, GPRReg destB)
1072     {
1073         GPRReg srcA = GPRInfo::returnValueGPR;
1074         GPRReg srcB = GPRInfo::returnValueGPR2;
1075
1076         if (destA == InvalidGPRReg)
1077             move(srcB, destB);
1078         else if (destB == InvalidGPRReg)
1079             move(srcA, destA);
1080         else if (srcB != destA) {
1081             // Handle the easy cases - two simple moves.
1082             move(srcA, destA);
1083             move(srcB, destB);
1084         } else if (srcA != destB) {
1085             // Handle the non-swap case - just put srcB in place first.
1086             move(srcB, destB);
1087             move(srcA, destA);
1088         } else
1089             swap(destA, destB);
1090     }
1091 };
1092
1093 } // namespace JSC
1094
1095 #endif // ENABLE(JIT)
1096
1097 #endif // CCallHelpers_h
1098