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#if ENABLE(JIT)
30
31#include "AssemblyHelpers.h"
32#include "GPRInfo.h"
33
34namespace JSC {
35
36class CCallHelpers : public AssemblyHelpers {
37public:
38    CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
39        : AssemblyHelpers(vm, codeBlock)
40    {
41    }
42
43    // These methods used to sort arguments into the correct registers.
44    // On X86 we use cdecl calling conventions, which pass all arguments on the
45    // stack. On other architectures we may need to sort values into the
46    // correct registers.
47#if !NUMBER_OF_ARGUMENT_REGISTERS
48    unsigned m_callArgumentOffset;
49    void resetCallArguments() { m_callArgumentOffset = 0; }
50
51    // These methods are using internally to implement the callOperation methods.
52    void addCallArgument(GPRReg value)
53    {
54        poke(value, m_callArgumentOffset++);
55    }
56    void addCallArgument(TrustedImm32 imm)
57    {
58        poke(imm, m_callArgumentOffset++);
59    }
60    void addCallArgument(TrustedImmPtr pointer)
61    {
62        poke(pointer, m_callArgumentOffset++);
63    }
64    void addCallArgument(FPRReg value)
65    {
66        storeDouble(value, Address(stackPointerRegister, m_callArgumentOffset * sizeof(void*)));
67        m_callArgumentOffset += sizeof(double) / sizeof(void*);
68    }
69
70    ALWAYS_INLINE void setupArguments(FPRReg arg1)
71    {
72        resetCallArguments();
73        addCallArgument(arg1);
74    }
75
76    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
77    {
78        resetCallArguments();
79        addCallArgument(arg1);
80        addCallArgument(arg2);
81    }
82
83    ALWAYS_INLINE void setupArguments(GPRReg arg1)
84    {
85        resetCallArguments();
86        addCallArgument(arg1);
87    }
88
89    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
90    {
91        resetCallArguments();
92        addCallArgument(arg1);
93        addCallArgument(arg2);
94    }
95
96    ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1, GPRReg arg2)
97    {
98        resetCallArguments();
99        addCallArgument(arg1);
100        addCallArgument(arg2);
101    }
102
103    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
104    {
105        resetCallArguments();
106        addCallArgument(arg1);
107        addCallArgument(arg2);
108        addCallArgument(arg3);
109    }
110
111    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImmPtr arg4)
112    {
113        resetCallArguments();
114        addCallArgument(arg1);
115        addCallArgument(arg2);
116        addCallArgument(arg3);
117        addCallArgument(arg4);
118    }
119
120    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImm32 arg4, GPRReg arg5)
121    {
122        resetCallArguments();
123        addCallArgument(arg1);
124        addCallArgument(arg2);
125        addCallArgument(arg3);
126        addCallArgument(arg4);
127        addCallArgument(arg5);
128    }
129
130    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImm32 arg4, GPRReg arg5, GPRReg arg6)
131    {
132        resetCallArguments();
133        addCallArgument(arg1);
134        addCallArgument(arg2);
135        addCallArgument(arg3);
136        addCallArgument(arg4);
137        addCallArgument(arg5);
138        addCallArgument(arg6);
139    }
140
141    ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
142    {
143        resetCallArguments();
144        addCallArgument(arg1);
145    }
146
147    ALWAYS_INLINE void setupArgumentsExecState()
148    {
149        resetCallArguments();
150        addCallArgument(GPRInfo::callFrameRegister);
151    }
152
153    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
154    {
155        resetCallArguments();
156        addCallArgument(GPRInfo::callFrameRegister);
157        addCallArgument(arg1);
158    }
159
160    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
161    {
162        resetCallArguments();
163        addCallArgument(GPRInfo::callFrameRegister);
164        addCallArgument(arg1);
165    }
166
167    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
168    {
169        resetCallArguments();
170        addCallArgument(GPRInfo::callFrameRegister);
171        addCallArgument(arg1);
172    }
173
174    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
175    {
176        resetCallArguments();
177        addCallArgument(GPRInfo::callFrameRegister);
178        addCallArgument(arg1);
179        addCallArgument(arg2);
180    }
181
182    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
183    {
184        resetCallArguments();
185        addCallArgument(GPRInfo::callFrameRegister);
186        addCallArgument(arg1);
187        addCallArgument(arg2);
188    }
189
190    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
191    {
192        resetCallArguments();
193        addCallArgument(GPRInfo::callFrameRegister);
194        addCallArgument(arg1);
195        addCallArgument(arg2);
196    }
197
198    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
199    {
200        resetCallArguments();
201        addCallArgument(GPRInfo::callFrameRegister);
202        addCallArgument(arg1);
203        addCallArgument(arg2);
204    }
205
206    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
207    {
208        resetCallArguments();
209        addCallArgument(GPRInfo::callFrameRegister);
210        addCallArgument(arg1);
211        addCallArgument(arg2);
212    }
213
214    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
215    {
216        resetCallArguments();
217        addCallArgument(GPRInfo::callFrameRegister);
218        addCallArgument(arg1);
219        addCallArgument(arg2);
220    }
221
222    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
223    {
224        resetCallArguments();
225        addCallArgument(GPRInfo::callFrameRegister);
226        addCallArgument(arg1);
227        addCallArgument(arg2);
228    }
229
230    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
231    {
232        resetCallArguments();
233        addCallArgument(GPRInfo::callFrameRegister);
234        addCallArgument(arg1);
235        addCallArgument(arg2);
236    }
237
238    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, TrustedImm32 arg3)
239    {
240        resetCallArguments();
241        addCallArgument(GPRInfo::callFrameRegister);
242        addCallArgument(arg1);
243        addCallArgument(arg2);
244        addCallArgument(arg3);
245    }
246
247    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
248    {
249        resetCallArguments();
250        addCallArgument(GPRInfo::callFrameRegister);
251        addCallArgument(arg1);
252        addCallArgument(arg2);
253        addCallArgument(arg3);
254    }
255
256    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
257    {
258        resetCallArguments();
259        addCallArgument(GPRInfo::callFrameRegister);
260        addCallArgument(arg1);
261        addCallArgument(arg2);
262        addCallArgument(arg3);
263    }
264
265    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
266    {
267        resetCallArguments();
268        addCallArgument(GPRInfo::callFrameRegister);
269        addCallArgument(arg1);
270        addCallArgument(arg2);
271        addCallArgument(arg3);
272    }
273
274    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
275    {
276        resetCallArguments();
277        addCallArgument(GPRInfo::callFrameRegister);
278        addCallArgument(arg1);
279        addCallArgument(arg2);
280        addCallArgument(arg3);
281    }
282
283    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
284    {
285        resetCallArguments();
286        addCallArgument(GPRInfo::callFrameRegister);
287        addCallArgument(arg1);
288        addCallArgument(arg2);
289        addCallArgument(arg3);
290    }
291
292    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3)
293    {
294        resetCallArguments();
295        addCallArgument(GPRInfo::callFrameRegister);
296        addCallArgument(arg1);
297        addCallArgument(arg2);
298        addCallArgument(arg3);
299    }
300
301    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3)
302    {
303        resetCallArguments();
304        addCallArgument(GPRInfo::callFrameRegister);
305        addCallArgument(arg1);
306        addCallArgument(arg2);
307        addCallArgument(arg3);
308    }
309
310    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImmPtr arg3)
311    {
312        resetCallArguments();
313        addCallArgument(GPRInfo::callFrameRegister);
314        addCallArgument(arg1);
315        addCallArgument(arg2);
316        addCallArgument(arg3);
317    }
318
319    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
320    {
321        resetCallArguments();
322        addCallArgument(GPRInfo::callFrameRegister);
323        addCallArgument(arg1);
324        addCallArgument(arg2);
325        addCallArgument(arg3);
326    }
327
328    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
329    {
330        resetCallArguments();
331        addCallArgument(GPRInfo::callFrameRegister);
332        addCallArgument(arg1);
333        addCallArgument(arg2);
334        addCallArgument(arg3);
335    }
336
337    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
338    {
339        resetCallArguments();
340        addCallArgument(GPRInfo::callFrameRegister);
341        addCallArgument(arg1);
342        addCallArgument(arg2);
343        addCallArgument(arg3);
344    }
345
346    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
347    {
348        resetCallArguments();
349        addCallArgument(GPRInfo::callFrameRegister);
350        addCallArgument(arg1);
351        addCallArgument(arg2);
352        addCallArgument(arg3);
353        addCallArgument(arg4);
354    }
355
356    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, GPRReg arg3, TrustedImmPtr arg4)
357    {
358        resetCallArguments();
359        addCallArgument(GPRInfo::callFrameRegister);
360        addCallArgument(arg1);
361        addCallArgument(arg2);
362        addCallArgument(arg3);
363        addCallArgument(arg4);
364    }
365
366    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
367    {
368        resetCallArguments();
369        addCallArgument(GPRInfo::callFrameRegister);
370        addCallArgument(arg1);
371        addCallArgument(arg2);
372        addCallArgument(arg3);
373        addCallArgument(arg4);
374    }
375
376    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
377    {
378        resetCallArguments();
379        addCallArgument(GPRInfo::callFrameRegister);
380        addCallArgument(arg1);
381        addCallArgument(arg2);
382        addCallArgument(arg3);
383        addCallArgument(arg4);
384        addCallArgument(arg5);
385    }
386
387    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
388    {
389        resetCallArguments();
390        addCallArgument(GPRInfo::callFrameRegister);
391        addCallArgument(arg1);
392        addCallArgument(arg2);
393        addCallArgument(arg3);
394        addCallArgument(arg4);
395        addCallArgument(arg5);
396    }
397
398    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
399    {
400        resetCallArguments();
401        addCallArgument(GPRInfo::callFrameRegister);
402        addCallArgument(arg1);
403        addCallArgument(arg2);
404        addCallArgument(arg3);
405        addCallArgument(arg4);
406    }
407
408    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
409    {
410        resetCallArguments();
411        addCallArgument(GPRInfo::callFrameRegister);
412        addCallArgument(arg1);
413        addCallArgument(arg2);
414        addCallArgument(arg3);
415        addCallArgument(arg4);
416    }
417
418    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
419    {
420        resetCallArguments();
421        addCallArgument(GPRInfo::callFrameRegister);
422        addCallArgument(arg1);
423        addCallArgument(arg2);
424        addCallArgument(arg3);
425    }
426
427    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
428    {
429        resetCallArguments();
430        addCallArgument(GPRInfo::callFrameRegister);
431        addCallArgument(arg1);
432        addCallArgument(arg2);
433        addCallArgument(arg3);
434        addCallArgument(arg4);
435    }
436
437    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
438    {
439        resetCallArguments();
440        addCallArgument(GPRInfo::callFrameRegister);
441        addCallArgument(arg1);
442        addCallArgument(arg2);
443        addCallArgument(arg3);
444        addCallArgument(arg4);
445    }
446
447    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
448    {
449        resetCallArguments();
450        addCallArgument(GPRInfo::callFrameRegister);
451        addCallArgument(arg1);
452        addCallArgument(arg2);
453        addCallArgument(arg3);
454        addCallArgument(arg4);
455    }
456
457    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
458    {
459        resetCallArguments();
460        addCallArgument(GPRInfo::callFrameRegister);
461        addCallArgument(arg1);
462        addCallArgument(arg2);
463        addCallArgument(arg3);
464        addCallArgument(arg4);
465    }
466
467    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
468    {
469        resetCallArguments();
470        addCallArgument(GPRInfo::callFrameRegister);
471        addCallArgument(arg1);
472        addCallArgument(arg2);
473        addCallArgument(arg3);
474        addCallArgument(arg4);
475    }
476
477    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
478    {
479        resetCallArguments();
480        addCallArgument(GPRInfo::callFrameRegister);
481        addCallArgument(arg1);
482        addCallArgument(arg2);
483        addCallArgument(arg3);
484        addCallArgument(arg4);
485        addCallArgument(arg5);
486    }
487
488    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImmPtr arg6)
489    {
490        resetCallArguments();
491        addCallArgument(GPRInfo::callFrameRegister);
492        addCallArgument(arg1);
493        addCallArgument(arg2);
494        addCallArgument(arg3);
495        addCallArgument(arg4);
496        addCallArgument(arg5);
497        addCallArgument(arg6);
498    }
499
500    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5, TrustedImmPtr arg6)
501    {
502        resetCallArguments();
503        addCallArgument(GPRInfo::callFrameRegister);
504        addCallArgument(arg1);
505        addCallArgument(arg2);
506        addCallArgument(arg3);
507        addCallArgument(arg4);
508        addCallArgument(arg5);
509        addCallArgument(arg6);
510    }
511
512    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
513    {
514        resetCallArguments();
515        addCallArgument(GPRInfo::callFrameRegister);
516        addCallArgument(arg1);
517        addCallArgument(arg2);
518        addCallArgument(arg3);
519        addCallArgument(arg4);
520    }
521
522    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
523    {
524        resetCallArguments();
525        addCallArgument(GPRInfo::callFrameRegister);
526        addCallArgument(arg1);
527        addCallArgument(arg2);
528        addCallArgument(arg3);
529        addCallArgument(arg4);
530    }
531
532    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
533    {
534        resetCallArguments();
535        addCallArgument(GPRInfo::callFrameRegister);
536        addCallArgument(arg1);
537        addCallArgument(arg2);
538        addCallArgument(arg3);
539        addCallArgument(arg4);
540    }
541
542    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
543    {
544        resetCallArguments();
545        addCallArgument(GPRInfo::callFrameRegister);
546        addCallArgument(arg1);
547        addCallArgument(arg2);
548        addCallArgument(arg3);
549        addCallArgument(arg4);
550        addCallArgument(arg5);
551    }
552
553    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
554    {
555        resetCallArguments();
556        addCallArgument(GPRInfo::callFrameRegister);
557        addCallArgument(arg1);
558        addCallArgument(arg2);
559        addCallArgument(arg3);
560        addCallArgument(arg4);
561        addCallArgument(arg5);
562    }
563
564    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
565    {
566        resetCallArguments();
567        addCallArgument(GPRInfo::callFrameRegister);
568        addCallArgument(arg1);
569        addCallArgument(arg2);
570        addCallArgument(arg3);
571        addCallArgument(arg4);
572        addCallArgument(arg5);
573    }
574
575    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
576    {
577        resetCallArguments();
578        addCallArgument(GPRInfo::callFrameRegister);
579        addCallArgument(arg1);
580        addCallArgument(arg2);
581        addCallArgument(arg3);
582        addCallArgument(arg4);
583        addCallArgument(arg5);
584    }
585
586    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
587    {
588        resetCallArguments();
589        addCallArgument(GPRInfo::callFrameRegister);
590        addCallArgument(arg1);
591        addCallArgument(arg2);
592        addCallArgument(arg3);
593        addCallArgument(arg4);
594        addCallArgument(arg5);
595    }
596
597    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6)
598    {
599        resetCallArguments();
600        addCallArgument(GPRInfo::callFrameRegister);
601        addCallArgument(arg1);
602        addCallArgument(arg2);
603        addCallArgument(arg3);
604        addCallArgument(arg4);
605        addCallArgument(arg5);
606        addCallArgument(arg6);
607    }
608
609
610    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
611    {
612        resetCallArguments();
613        addCallArgument(GPRInfo::callFrameRegister);
614        addCallArgument(arg1);
615        addCallArgument(arg2);
616        addCallArgument(arg3);
617        addCallArgument(arg4);
618        addCallArgument(arg5);
619        addCallArgument(arg6);
620    }
621
622    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
623    {
624        resetCallArguments();
625        addCallArgument(GPRInfo::callFrameRegister);
626        addCallArgument(arg1);
627        addCallArgument(arg2);
628    }
629
630    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
631    {
632        resetCallArguments();
633        addCallArgument(GPRInfo::callFrameRegister);
634        addCallArgument(arg1);
635        addCallArgument(arg2);
636        addCallArgument(arg3);
637    }
638#endif // !NUMBER_OF_ARGUMENT_REGISTERS
639    // These methods are suitable for any calling convention that provides for
640    // at least 4 argument registers, e.g. X86_64, ARMv7.
641#if NUMBER_OF_ARGUMENT_REGISTERS >= 4
642    template<GPRReg destA, GPRReg destB>
643    void setupTwoStubArgsGPR(GPRReg srcA, GPRReg srcB)
644    {
645        // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
646        // (1) both are already in arg regs, the right way around.
647        // (2) both are already in arg regs, the wrong way around.
648        // (3) neither are currently in arg registers.
649        // (4) srcA in in its correct reg.
650        // (5) srcA in in the incorrect reg.
651        // (6) srcB in in its correct reg.
652        // (7) srcB in in the incorrect reg.
653        //
654        // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
655        // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
656        // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
657        // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
658
659        if (srcB != destA) {
660            // Handle the easy cases - two simple moves.
661            move(srcA, destA);
662            move(srcB, destB);
663        } else if (srcA != destB) {
664            // Handle the non-swap case - just put srcB in place first.
665            move(srcB, destB);
666            move(srcA, destA);
667        } else
668            swap(destA, destB);
669    }
670
671    template<GPRReg destA, GPRReg destB, GPRReg destC>
672    void setupThreeStubArgsGPR(GPRReg srcA, GPRReg srcB, GPRReg srcC)
673    {
674        // If neither of srcB/srcC are in our way, then we can move srcA into place.
675        // Then we can use setupTwoStubArgs to fix srcB/srcC.
676        if (srcB != destA && srcC != destA) {
677            move(srcA, destA);
678            setupTwoStubArgsGPR<destB, destC>(srcB, srcC);
679            return;
680        }
681
682        // If neither of srcA/srcC are in our way, then we can move srcB into place.
683        // Then we can use setupTwoStubArgs to fix srcA/srcC.
684        if (srcA != destB && srcC != destB) {
685            move(srcB, destB);
686            setupTwoStubArgsGPR<destA, destC>(srcA, srcC);
687            return;
688        }
689
690        // If neither of srcA/srcB are in our way, then we can move srcC into place.
691        // Then we can use setupTwoStubArgs to fix srcA/srcB.
692        if (srcA != destC && srcB != destC) {
693            move(srcC, destC);
694            setupTwoStubArgsGPR<destA, destB>(srcA, srcB);
695            return;
696        }
697
698        // If we get here, we haven't been able to move any of srcA/srcB/srcC.
699        // Since all three are blocked, then all three must already be in the argument register.
700        // But are they in the right ones?
701
702        // First, ensure srcA is in place.
703        if (srcA != destA) {
704            swap(srcA, destA);
705
706            // If srcA wasn't in argumentGPR1, one of srcB/srcC must be.
707            ASSERT(srcB == destA || srcC == destA);
708            // If srcB was in argumentGPR1 it no longer is (due to the swap).
709            // Otherwise srcC must have been. Mark him as moved.
710            if (srcB == destA)
711                srcB = srcA;
712            else
713                srcC = srcA;
714        }
715
716        // Either srcB & srcC need swapping, or we're all done.
717        ASSERT((srcB == destB || srcC == destC)
718            || (srcB == destC || srcC == destB));
719
720        if (srcB != destB)
721            swap(destB, destC);
722    }
723
724#if CPU(X86_64) || CPU(ARM64)
725    template<FPRReg destA, FPRReg destB>
726    void setupTwoStubArgsFPR(FPRReg srcA, FPRReg srcB)
727    {
728        // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
729        // (1) both are already in arg regs, the right way around.
730        // (2) both are already in arg regs, the wrong way around.
731        // (3) neither are currently in arg registers.
732        // (4) srcA in in its correct reg.
733        // (5) srcA in in the incorrect reg.
734        // (6) srcB in in its correct reg.
735        // (7) srcB in in the incorrect reg.
736        //
737        // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
738        // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
739        // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
740        // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
741
742        if (srcB != destA) {
743            // Handle the easy cases - two simple moves.
744            moveDouble(srcA, destA);
745            moveDouble(srcB, destB);
746            return;
747        }
748
749        if (srcA != destB) {
750            // Handle the non-swap case - just put srcB in place first.
751            moveDouble(srcB, destB);
752            moveDouble(srcA, destA);
753            return;
754        }
755
756        ASSERT(srcB == destA && srcA == destB);
757        // Need to swap; pick a temporary register.
758        FPRReg temp;
759        if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3)
760            temp = FPRInfo::argumentFPR3;
761        else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2)
762            temp = FPRInfo::argumentFPR2;
763        else {
764            ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1);
765            temp = FPRInfo::argumentFPR1;
766        }
767        moveDouble(destA, temp);
768        moveDouble(destB, destA);
769        moveDouble(temp, destB);
770    }
771#endif
772    void setupStubArguments(GPRReg arg1, GPRReg arg2)
773    {
774        setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
775    }
776
777    void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
778    {
779        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
780    }
781
782#if CPU(MIPS) || (OS(WINDOWS) && CPU(X86_64))
783#define POKE_ARGUMENT_OFFSET 4
784#else
785#define POKE_ARGUMENT_OFFSET 0
786#endif
787
788#if CPU(X86_64) || CPU(ARM64)
789    ALWAYS_INLINE void setupArguments(FPRReg arg1)
790    {
791        moveDouble(arg1, FPRInfo::argumentFPR0);
792    }
793
794    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
795    {
796        setupTwoStubArgsFPR<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
797    }
798
799    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
800    {
801#if OS(WINDOWS) && CPU(X86_64)
802        // On Windows, arguments map to designated registers based on the argument positions, even when there are interlaced scalar and floating point arguments.
803        // See http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
804        moveDouble(arg1, FPRInfo::argumentFPR1);
805        move(arg2, GPRInfo::argumentGPR2);
806#else
807        moveDouble(arg1, FPRInfo::argumentFPR0);
808        move(arg2, GPRInfo::argumentGPR1);
809#endif
810        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
811    }
812
813    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
814    {
815#if OS(WINDOWS) && CPU(X86_64)
816        // On Windows, arguments map to designated registers based on the argument positions, even when there are interlaced scalar and floating point arguments.
817        // See http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
818        moveDouble(arg3, FPRInfo::argumentFPR3);
819#else
820        moveDouble(arg3, FPRInfo::argumentFPR0);
821#endif
822        setupStubArguments(arg1, arg2);
823        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
824    }
825#elif CPU(ARM)
826#if CPU(ARM_HARDFP)
827    ALWAYS_INLINE void setupArguments(FPRReg arg1)
828    {
829        moveDouble(arg1, FPRInfo::argumentFPR0);
830    }
831
832    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
833    {
834        if (arg2 != FPRInfo::argumentFPR0) {
835            moveDouble(arg1, FPRInfo::argumentFPR0);
836            moveDouble(arg2, FPRInfo::argumentFPR1);
837        } else if (arg1 != FPRInfo::argumentFPR1) {
838            moveDouble(arg2, FPRInfo::argumentFPR1);
839            moveDouble(arg1, FPRInfo::argumentFPR0);
840        } else {
841            // Swap arg1, arg2.
842            moveDouble(FPRInfo::argumentFPR0, ARMRegisters::d2);
843            moveDouble(FPRInfo::argumentFPR1, FPRInfo::argumentFPR0);
844            moveDouble(ARMRegisters::d2, FPRInfo::argumentFPR1);
845        }
846    }
847
848    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
849    {
850        moveDouble(arg1, FPRInfo::argumentFPR0);
851        move(arg2, GPRInfo::argumentGPR1);
852        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
853    }
854
855    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
856    {
857        moveDouble(arg3, FPRInfo::argumentFPR0);
858        setupStubArguments(arg1, arg2);
859        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
860    }
861
862    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32, FPRReg arg2, GPRReg arg3)
863    {
864        moveDouble(arg2, FPRInfo::argumentFPR0);
865        move(arg3, GPRInfo::argumentGPR1);
866        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
867    }
868
869    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32, FPRReg arg4)
870    {
871        moveDouble(arg4, FPRInfo::argumentFPR0);
872        setupStubArguments(arg1, arg2);
873        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
874    }
875
876#else
877    ALWAYS_INLINE void setupArguments(FPRReg arg1)
878    {
879        assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
880    }
881
882    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
883    {
884        assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
885        assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
886    }
887
888    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
889    {
890        move(arg2, GPRInfo::argumentGPR3);
891        assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1);
892        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
893    }
894
895    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
896    {
897        setupStubArguments(arg1, arg2);
898        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
899        assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3);
900        poke(GPRInfo::nonArgGPR0);
901    }
902
903    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, FPRReg arg2, GPRReg arg3)
904    {
905        poke(arg3, POKE_ARGUMENT_OFFSET);
906        move(arg1, GPRInfo::argumentGPR1);
907        assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
908        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
909    }
910
911    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, FPRReg arg4)
912    {
913        setupStubArguments(arg1, arg2);
914        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
915        move(arg3, GPRInfo::argumentGPR3);
916        assembler().vmov(GPRInfo::nonArgGPR0, GPRInfo::nonArgGPR1, arg4);
917        poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET);
918        poke(GPRInfo::nonArgGPR1, POKE_ARGUMENT_OFFSET + 1);
919    }
920#endif // CPU(ARM_HARDFP)
921#elif CPU(MIPS)
922    ALWAYS_INLINE void setupArguments(FPRReg arg1)
923    {
924        moveDouble(arg1, FPRInfo::argumentFPR0);
925    }
926
927    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
928    {
929        if (arg2 != FPRInfo::argumentFPR0) {
930            moveDouble(arg1, FPRInfo::argumentFPR0);
931            moveDouble(arg2, FPRInfo::argumentFPR1);
932        } else if (arg1 != FPRInfo::argumentFPR1) {
933            moveDouble(arg2, FPRInfo::argumentFPR1);
934            moveDouble(arg1, FPRInfo::argumentFPR0);
935        } else {
936            // Swap arg1, arg2.
937            swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
938        }
939    }
940
941    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
942    {
943        assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
944        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
945        poke(arg2, 4);
946    }
947
948    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
949    {
950        setupStubArguments(arg1, arg2);
951        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
952        poke(arg3, 4);
953    }
954
955    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, FPRReg arg2, GPRReg arg3)
956    {
957        setupArgumentsWithExecState(arg2, arg3);
958    }
959
960    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, FPRReg arg4)
961    {
962        setupArgumentsWithExecState(arg1, arg2, arg4);
963    }
964#elif CPU(SH4)
965    ALWAYS_INLINE void setupArguments(FPRReg arg1)
966    {
967        moveDouble(arg1, FPRInfo::argumentFPR0);
968    }
969
970    ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
971    {
972        if (arg2 != FPRInfo::argumentFPR0) {
973            moveDouble(arg1, FPRInfo::argumentFPR0);
974            moveDouble(arg2, FPRInfo::argumentFPR1);
975        } else if (arg1 != FPRInfo::argumentFPR1) {
976            moveDouble(arg2, FPRInfo::argumentFPR1);
977            moveDouble(arg1, FPRInfo::argumentFPR0);
978        } else
979            swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
980    }
981
982    ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
983    {
984        moveDouble(arg1, FPRInfo::argumentFPR0);
985        move(arg2, GPRInfo::argumentGPR1);
986        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
987    }
988
989    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
990    {
991        moveDouble(arg3, FPRInfo::argumentFPR0);
992        setupStubArguments(arg1, arg2);
993        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
994    }
995#else
996#error "JIT not supported on this platform."
997#endif
998
999    ALWAYS_INLINE void setupArguments(GPRReg arg1)
1000    {
1001        move(arg1, GPRInfo::argumentGPR0);
1002    }
1003
1004    ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1, GPRReg arg2)
1005    {
1006        move(arg2, GPRInfo::argumentGPR1);
1007        move(arg1, GPRInfo::argumentGPR0);
1008    }
1009
1010    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
1011    {
1012        setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
1013    }
1014
1015    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
1016    {
1017        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2, arg3);
1018    }
1019
1020    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImmPtr arg4)
1021    {
1022        setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
1023        move(arg3, GPRInfo::argumentGPR2);
1024        move(arg4, GPRInfo::argumentGPR3);
1025    }
1026
1027    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1028    {
1029        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2, arg3);
1030        move(arg4, GPRInfo::argumentGPR3);
1031    }
1032
1033    ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, TrustedImmPtr arg4)
1034    {
1035        setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2>(arg1, arg3);
1036        move(arg2, GPRInfo::argumentGPR1);
1037        move(arg4, GPRInfo::argumentGPR3);
1038    }
1039
1040    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImm32 arg4, GPRReg arg5, GPRReg arg6)
1041    {
1042        poke(arg6, POKE_ARGUMENT_OFFSET + 1);
1043        poke(arg5, POKE_ARGUMENT_OFFSET);
1044        setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
1045        move(arg3, GPRInfo::argumentGPR2);
1046        move(arg4, GPRInfo::argumentGPR3);
1047    }
1048
1049    ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
1050    {
1051        move(arg1, GPRInfo::argumentGPR0);
1052    }
1053
1054    ALWAYS_INLINE void setupArgumentsExecState()
1055    {
1056        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1057    }
1058
1059    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
1060    {
1061        move(arg1, GPRInfo::argumentGPR1);
1062        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1063    }
1064
1065    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
1066    {
1067        move(arg1, GPRInfo::argumentGPR1);
1068        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1069    }
1070
1071    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
1072    {
1073        move(arg1, GPRInfo::argumentGPR1);
1074        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1075    }
1076
1077#if OS(WINDOWS) && CPU(X86_64)
1078    ALWAYS_INLINE void setupArgumentsWithExecStateForCallWithSlowPathReturnType(TrustedImm32 arg1)
1079    {
1080        move(arg1, GPRInfo::argumentGPR2);
1081        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
1082    }
1083#endif
1084
1085    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
1086    {
1087        setupStubArguments(arg1, arg2);
1088        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1089    }
1090
1091    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
1092    {
1093        move(arg1, GPRInfo::argumentGPR1);
1094        move(arg2, GPRInfo::argumentGPR2);
1095        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1096    }
1097#if CPU(X86_64) || CPU(ARM64)
1098    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm64 arg2)
1099    {
1100        move(arg1, GPRInfo::argumentGPR1);
1101        move(arg2, GPRInfo::argumentGPR2);
1102        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1103    }
1104
1105    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm64 arg1, GPRReg arg2)
1106    {
1107        move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
1108        move(arg1, GPRInfo::argumentGPR1);
1109        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1110    }
1111#endif
1112    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
1113    {
1114        move(arg1, GPRInfo::argumentGPR1);
1115        move(arg2, GPRInfo::argumentGPR2);
1116        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1117    }
1118
1119    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2)
1120    {
1121        move(arg1, GPRInfo::argumentGPR1);
1122        move(arg2, GPRInfo::argumentGPR2);
1123        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1124    }
1125
1126    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
1127    {
1128        move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
1129        move(arg1, GPRInfo::argumentGPR1);
1130        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1131    }
1132
1133    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
1134    {
1135        move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
1136        move(arg1, GPRInfo::argumentGPR1);
1137        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1138    }
1139
1140    ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2)
1141    {
1142        move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
1143        move(arg1, GPRInfo::argumentGPR1);
1144        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1145    }
1146
1147    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
1148    {
1149        move(arg1, GPRInfo::argumentGPR1);
1150        move(arg2, GPRInfo::argumentGPR2);
1151        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1152    }
1153
1154    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
1155    {
1156        move(arg1, GPRInfo::argumentGPR1);
1157        move(arg2, GPRInfo::argumentGPR2);
1158        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1159    }
1160
1161    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
1162    {
1163        move(arg1, GPRInfo::argumentGPR1);
1164        move(arg2, GPRInfo::argumentGPR2);
1165        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1166    }
1167
1168    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, TrustedImm32 arg3)
1169    {
1170        move(arg1, GPRInfo::argumentGPR1);
1171        move(arg2, GPRInfo::argumentGPR2);
1172        move(arg3, GPRInfo::argumentGPR3);
1173        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1174    }
1175
1176    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
1177    {
1178        setupStubArguments(arg1, arg2, arg3);
1179        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1180    }
1181
1182    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
1183    {
1184        setupStubArguments(arg1, arg2);
1185        move(arg3, GPRInfo::argumentGPR3);
1186        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1187    }
1188
1189    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
1190    {
1191        setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
1192        move(arg2, GPRInfo::argumentGPR2);
1193        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1194    }
1195
1196    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3)
1197    {
1198        setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
1199        move(arg2, GPRInfo::argumentGPR2);
1200        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1201    }
1202
1203    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
1204    {
1205        move(arg1, GPRInfo::argumentGPR1);
1206        move(arg2, GPRInfo::argumentGPR2);
1207        move(arg3, GPRInfo::argumentGPR3);
1208        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1209    }
1210
1211    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
1212    {
1213        move(arg1, GPRInfo::argumentGPR1);
1214        move(arg2, GPRInfo::argumentGPR2);
1215        move(arg3, GPRInfo::argumentGPR3);
1216        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1217    }
1218
1219    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImm32 arg3)
1220    {
1221        move(arg1, GPRInfo::argumentGPR1);
1222        move(arg2, GPRInfo::argumentGPR2);
1223        move(arg3, GPRInfo::argumentGPR3);
1224        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1225    }
1226
1227    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
1228    {
1229        move(arg1, GPRInfo::argumentGPR1);
1230        move(arg2, GPRInfo::argumentGPR2);
1231        move(arg3, GPRInfo::argumentGPR3);
1232        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1233    }
1234
1235    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
1236    {
1237        setupStubArguments(arg1, arg2);
1238        move(arg3, GPRInfo::argumentGPR3);
1239        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1240    }
1241
1242    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
1243    {
1244        move(arg3, GPRInfo::argumentGPR3);
1245        move(arg1, GPRInfo::argumentGPR1);
1246        move(arg2, GPRInfo::argumentGPR2);
1247        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1248    }
1249
1250    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
1251    {
1252        move(arg3, GPRInfo::argumentGPR3);
1253        move(arg1, GPRInfo::argumentGPR1);
1254        move(arg2, GPRInfo::argumentGPR2);
1255        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1256    }
1257
1258    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3)
1259    {
1260        move(arg2, GPRInfo::argumentGPR2);
1261        move(arg1, GPRInfo::argumentGPR1);
1262        move(arg3, GPRInfo::argumentGPR3);
1263        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1264    }
1265
1266    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3)
1267    {
1268        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
1269        move(arg1, GPRInfo::argumentGPR1);
1270        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1271    }
1272
1273    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3)
1274    {
1275        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
1276        move(arg1, GPRInfo::argumentGPR1);
1277        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1278    }
1279
1280    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3)
1281    {
1282        move(arg2, GPRInfo::argumentGPR2); // In case arg2 is argumentGPR1.
1283        move(arg1, GPRInfo::argumentGPR1);
1284        move(arg3, GPRInfo::argumentGPR3);
1285        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1286    }
1287
1288    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImmPtr arg3)
1289    {
1290        move(arg2, GPRInfo::argumentGPR2); // In case arg2 is argumentGPR1.
1291        move(arg1, GPRInfo::argumentGPR1);
1292        move(arg3, GPRInfo::argumentGPR3);
1293        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1294    }
1295
1296    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
1297    {
1298        move(arg1, GPRInfo::argumentGPR1);
1299        move(arg2, GPRInfo::argumentGPR2);
1300        move(arg3, GPRInfo::argumentGPR3);
1301        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1302    }
1303
1304    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
1305    {
1306        move(arg1, GPRInfo::argumentGPR1);
1307        move(arg2, GPRInfo::argumentGPR2);
1308        move(arg3, GPRInfo::argumentGPR3);
1309        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1310    }
1311
1312    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3)
1313    {
1314        move(arg1, GPRInfo::argumentGPR1);
1315        move(arg2, GPRInfo::argumentGPR2);
1316        move(arg3, GPRInfo::argumentGPR3);
1317        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1318    }
1319
1320#endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
1321    // These methods are suitable for any calling convention that provides for
1322    // exactly 4 argument registers, e.g. ARMv7.
1323#if NUMBER_OF_ARGUMENT_REGISTERS == 4
1324
1325    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
1326    {
1327        poke(arg4, POKE_ARGUMENT_OFFSET);
1328        setupArgumentsWithExecState(arg1, arg2, arg3);
1329    }
1330
1331    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
1332    {
1333        poke(arg4, POKE_ARGUMENT_OFFSET);
1334        setupArgumentsWithExecState(arg1, arg2, arg3);
1335    }
1336
1337    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3,  GPRReg arg4)
1338    {
1339        poke(arg4, POKE_ARGUMENT_OFFSET);
1340        setupArgumentsWithExecState(arg1, arg2, arg3);
1341    }
1342
1343    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
1344    {
1345        poke(arg4, POKE_ARGUMENT_OFFSET);
1346        setupArgumentsWithExecState(arg1, arg2, arg3);
1347    }
1348
1349    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
1350    {
1351        poke(arg4, POKE_ARGUMENT_OFFSET);
1352        setupArgumentsWithExecState(arg1, arg2, arg3);
1353    }
1354
1355    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1356    {
1357        poke(arg4, POKE_ARGUMENT_OFFSET);
1358        setupArgumentsWithExecState(arg1, arg2, arg3);
1359    }
1360
1361    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
1362    {
1363        poke(arg4, POKE_ARGUMENT_OFFSET);
1364        setupArgumentsWithExecState(arg1, arg2, arg3);
1365    }
1366
1367    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImmPtr arg5)
1368    {
1369        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1370        poke(arg4, POKE_ARGUMENT_OFFSET);
1371        setupArgumentsWithExecState(arg1, arg2, arg3);
1372    }
1373
1374    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1375    {
1376        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1377        poke(arg4, POKE_ARGUMENT_OFFSET);
1378        setupArgumentsWithExecState(arg1, arg2, arg3);
1379    }
1380
1381    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
1382    {
1383        poke(arg4, POKE_ARGUMENT_OFFSET);
1384        setupArgumentsWithExecState(arg1, arg2, arg3);
1385    }
1386
1387    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4, TrustedImm32 arg5)
1388    {
1389        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1390        poke(arg4, POKE_ARGUMENT_OFFSET);
1391        setupArgumentsWithExecState(arg1, arg2, arg3);
1392    }
1393
1394    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
1395    {
1396        poke(arg4, POKE_ARGUMENT_OFFSET);
1397        setupArgumentsWithExecState(arg1, arg2, arg3);
1398    }
1399
1400    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1401    {
1402        poke(arg4, POKE_ARGUMENT_OFFSET);
1403        setupArgumentsWithExecState(arg1, arg2, arg3);
1404    }
1405
1406    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
1407    {
1408        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1409        poke(arg4, POKE_ARGUMENT_OFFSET);
1410        setupArgumentsWithExecState(arg1, arg2, arg3);
1411    }
1412
1413    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
1414    {
1415        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1416        poke(arg4, POKE_ARGUMENT_OFFSET);
1417        setupArgumentsWithExecState(arg1, arg2, arg3);
1418    }
1419
1420    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
1421    {
1422        poke(arg4, POKE_ARGUMENT_OFFSET);
1423        setupArgumentsWithExecState(arg1, arg2, arg3);
1424    }
1425
1426    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1427    {
1428        poke(arg4, POKE_ARGUMENT_OFFSET);
1429        setupArgumentsWithExecState(arg1, arg2, arg3);
1430    }
1431
1432    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
1433    {
1434        poke(arg4, POKE_ARGUMENT_OFFSET);
1435        setupArgumentsWithExecState(arg1, arg2, arg3);
1436    }
1437
1438    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
1439    {
1440        poke(arg4, POKE_ARGUMENT_OFFSET);
1441        setupArgumentsWithExecState(arg1, arg2, arg3);
1442    }
1443
1444    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
1445    {
1446        poke(arg4, POKE_ARGUMENT_OFFSET);
1447        setupArgumentsWithExecState(arg1, arg2, arg3);
1448    }
1449
1450    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
1451    {
1452        poke(arg4, POKE_ARGUMENT_OFFSET);
1453        setupArgumentsWithExecState(arg1, arg2, arg3);
1454    }
1455
1456    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1457    {
1458        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1459        poke(arg4, POKE_ARGUMENT_OFFSET);
1460        setupArgumentsWithExecState(arg1, arg2, arg3);
1461    }
1462
1463    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
1464    {
1465        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1466        poke(arg4, POKE_ARGUMENT_OFFSET);
1467        setupArgumentsWithExecState(arg1, arg2, arg3);
1468    }
1469
1470    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
1471    {
1472        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1473        poke(arg4, POKE_ARGUMENT_OFFSET);
1474        setupArgumentsWithExecState(arg1, arg2, arg3);
1475    }
1476
1477    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
1478    {
1479        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1480        poke(arg4, POKE_ARGUMENT_OFFSET);
1481        setupArgumentsWithExecState(arg1, arg2, arg3);
1482    }
1483
1484    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1485    {
1486        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1487        poke(arg4, POKE_ARGUMENT_OFFSET);
1488        setupArgumentsWithExecState(arg1, arg2, arg3);
1489    }
1490
1491    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1492    {
1493        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1494        poke(arg4, POKE_ARGUMENT_OFFSET);
1495        setupArgumentsWithExecState(arg1, arg2, arg3);
1496    }
1497
1498    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
1499    {
1500        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1501        poke(arg4, POKE_ARGUMENT_OFFSET);
1502        setupArgumentsWithExecState(arg1, arg2, arg3);
1503    }
1504
1505    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, GPRReg arg4, TrustedImm32 arg5)
1506    {
1507        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1508        poke(arg4, POKE_ARGUMENT_OFFSET);
1509        setupArgumentsWithExecState(arg1, arg2, arg3);
1510    }
1511
1512    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6)
1513    {
1514        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1515        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1516        poke(arg4, POKE_ARGUMENT_OFFSET);
1517        setupArgumentsWithExecState(arg1, arg2, arg3);
1518    }
1519
1520    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
1521    {
1522        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1523        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1524        poke(arg4, POKE_ARGUMENT_OFFSET);
1525        setupArgumentsWithExecState(arg1, arg2, arg3);
1526    }
1527
1528    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
1529    {
1530        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1531        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1532        poke(arg4, POKE_ARGUMENT_OFFSET);
1533        setupArgumentsWithExecState(arg1, arg2, arg3);
1534    }
1535
1536    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, GPRReg arg4, GPRReg arg5)
1537    {
1538        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1539        poke(arg4, POKE_ARGUMENT_OFFSET);
1540        setupArgumentsWithExecState(arg1, arg2, arg3);
1541    }
1542
1543    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5, TrustedImmPtr arg6)
1544    {
1545        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1546        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1547        poke(arg4, POKE_ARGUMENT_OFFSET);
1548        setupArgumentsWithExecState(arg1, arg2, arg3);
1549    }
1550
1551    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImmPtr arg6)
1552    {
1553        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1554        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1555        poke(arg4, POKE_ARGUMENT_OFFSET);
1556        setupArgumentsWithExecState(arg1, arg2, arg3);
1557    }
1558
1559    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5, TrustedImmPtr arg6)
1560    {
1561        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1562        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1563        poke(arg4, POKE_ARGUMENT_OFFSET);
1564        setupArgumentsWithExecState(arg1, arg2, arg3);
1565    }
1566
1567    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, TrustedImm32 arg6)
1568    {
1569        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1570        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1571        poke(arg4, POKE_ARGUMENT_OFFSET);
1572        setupArgumentsWithExecState(arg1, arg2, arg3);
1573    }
1574
1575    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, GPRReg arg5, GPRReg arg6)
1576    {
1577        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1578        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1579        poke(arg4, POKE_ARGUMENT_OFFSET);
1580        setupArgumentsWithExecState(arg1, arg2, arg3);
1581    }
1582
1583    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, GPRReg arg7)
1584    {
1585        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
1586        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1587        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1588        poke(arg4, POKE_ARGUMENT_OFFSET);
1589        setupArgumentsWithExecState(arg1, arg2, arg3);
1590    }
1591
1592    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5, GPRReg arg6, GPRReg arg7)
1593    {
1594        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
1595        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1596        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1597        poke(arg4, POKE_ARGUMENT_OFFSET);
1598        setupArgumentsWithExecState(arg1, arg2, arg3);
1599    }
1600
1601    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5, GPRReg arg6, GPRReg arg7)
1602    {
1603        poke(arg7, POKE_ARGUMENT_OFFSET + 3);
1604        poke(arg6, POKE_ARGUMENT_OFFSET + 2);
1605        poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1606        poke(arg4, POKE_ARGUMENT_OFFSET);
1607        setupArgumentsWithExecState(arg1, arg2, arg3);
1608    }
1609
1610    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImm32 arg4, GPRReg arg5)
1611    {
1612        poke(arg5, POKE_ARGUMENT_OFFSET);
1613        setupTwoStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
1614        move(arg3, GPRInfo::argumentGPR2);
1615        move(arg4, GPRInfo::argumentGPR3);
1616    }
1617#endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
1618
1619#if NUMBER_OF_ARGUMENT_REGISTERS >= 5
1620    void setupStubArguments134(GPRReg arg1, GPRReg arg3, GPRReg arg4)
1621    {
1622        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3, GPRInfo::argumentGPR4>(arg1, arg3, arg4);
1623    }
1624
1625    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
1626    {
1627        setupTwoStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4);
1628        move(arg2, GPRInfo::argumentGPR2);
1629        move(arg3, GPRInfo::argumentGPR3);
1630        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1631    }
1632
1633    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
1634    {
1635        setupStubArguments134(arg1, arg3, arg4);
1636        move(arg2, GPRInfo::argumentGPR2);
1637        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1638    }
1639
1640    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1641    {
1642        setupTwoStubArgsGPR<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
1643        move(arg1, GPRInfo::argumentGPR1);
1644        move(arg4, GPRInfo::argumentGPR4);
1645        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1646    }
1647
1648    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
1649    {
1650        setupThreeStubArgsGPR<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg2, arg3);
1651        move(arg4, GPRInfo::argumentGPR4);
1652        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1653    }
1654
1655    ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
1656    {
1657        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg3, arg4);
1658        move(arg2, GPRInfo::argumentGPR1);
1659        move(arg5, GPRInfo::argumentGPR4);
1660    }
1661
1662    ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3, TrustedImm32 arg4, GPRReg arg5)
1663    {
1664        setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg2, arg5);
1665        move(arg3, GPRInfo::argumentGPR2);
1666        move(arg4, GPRInfo::argumentGPR3);
1667    }
1668#endif
1669
1670    void setupResults(GPRReg destA, GPRReg destB)
1671    {
1672        GPRReg srcA = GPRInfo::returnValueGPR;
1673        GPRReg srcB = GPRInfo::returnValueGPR2;
1674
1675        if (destA == InvalidGPRReg)
1676            move(srcB, destB);
1677        else if (destB == InvalidGPRReg)
1678            move(srcA, destA);
1679        else if (srcB != destA) {
1680            // Handle the easy cases - two simple moves.
1681            move(srcA, destA);
1682            move(srcB, destB);
1683        } else if (srcA != destB) {
1684            // Handle the non-swap case - just put srcB in place first.
1685            move(srcB, destB);
1686            move(srcA, destA);
1687        } else
1688            swap(destA, destB);
1689    }
1690
1691    void setupResults(JSValueRegs regs)
1692    {
1693#if USE(JSVALUE64)
1694        move(GPRInfo::returnValueGPR, regs.gpr());
1695#else
1696        setupResults(regs.payloadGPR(), regs.tagGPR());
1697#endif
1698    }
1699
1700    void jumpToExceptionHandler()
1701    {
1702        // genericUnwind() leaves the handler CallFrame* in vm->callFrameForThrow,
1703        // and the address of the handler in vm->targetMachinePCForThrow.
1704        loadPtr(&vm()->targetMachinePCForThrow, GPRInfo::regT1);
1705        jump(GPRInfo::regT1);
1706    }
1707};
1708
1709} // namespace JSC
1710
1711#endif // ENABLE(JIT)
1712
1713#endif // CCallHelpers_h
1714
1715