1f299cc574146e7a95920b16022c486c31d380b8
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGGPRInfo.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 DFGGPRInfo_h
27 #define DFGGPRInfo_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "DFGRegisterBank.h"
34 #include "MacroAssembler.h"
35
36 namespace JSC { namespace DFG {
37
38 typedef MacroAssembler::RegisterID GPRReg;
39 #define InvalidGPRReg ((::JSC::DFG::GPRReg)-1)
40
41 #if USE(JSVALUE64)
42 class JSValueRegs {
43 public:
44     JSValueRegs()
45         : m_gpr(InvalidGPRReg)
46     {
47     }
48     
49     explicit JSValueRegs(GPRReg gpr)
50         : m_gpr(gpr)
51     {
52     }
53     
54     static JSValueRegs payloadOnly(GPRReg gpr)
55     {
56         return JSValueRegs(gpr);
57     }
58     
59     bool operator!() const { return m_gpr == InvalidGPRReg; }
60     
61     GPRReg gpr() const { return m_gpr; }
62     GPRReg payloadGPR() const { return m_gpr; }
63     
64 private:
65     GPRReg m_gpr;
66 };
67
68 class JSValueSource {
69 public:
70     JSValueSource()
71         : m_offset(notAddress())
72         , m_base(InvalidGPRReg)
73     {
74     }
75     
76     JSValueSource(JSValueRegs regs)
77         : m_offset(notAddress())
78         , m_base(regs.gpr())
79     {
80     }
81     
82     explicit JSValueSource(GPRReg gpr)
83         : m_offset(notAddress())
84         , m_base(gpr)
85     {
86     }
87     
88     JSValueSource(MacroAssembler::Address address)
89         : m_offset(address.offset)
90         , m_base(address.base)
91     {
92         ASSERT(m_offset != notAddress());
93         ASSERT(m_base != InvalidGPRReg);
94     }
95     
96     static JSValueSource unboxedCell(GPRReg payloadGPR)
97     {
98         return JSValueSource(payloadGPR);
99     }
100     
101     bool operator!() const { return m_base == InvalidGPRReg; }
102     
103     bool isAddress() const { return m_offset != notAddress(); }
104     
105     int32_t offset() const
106     {
107         ASSERT(isAddress());
108         return m_offset;
109     }
110     
111     GPRReg base() const
112     {
113         ASSERT(isAddress());
114         return m_base;
115     }
116     
117     GPRReg gpr() const
118     {
119         ASSERT(!isAddress());
120         return m_base;
121     }
122     
123     MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
124     
125 private:
126     static inline int32_t notAddress() { return 0x80000000; }     
127           
128     int32_t m_offset;
129     GPRReg m_base;
130 };
131 #endif
132
133 #if USE(JSVALUE32_64)
134 class JSValueRegs {
135 public:
136     JSValueRegs()
137         : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
138         , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
139     {
140     }
141     
142     JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
143         : m_tagGPR(tagGPR)
144         , m_payloadGPR(payloadGPR)
145     {
146     }
147     
148     static JSValueRegs payloadOnly(GPRReg gpr)
149     {
150         return JSValueRegs(InvalidGPRReg, gpr);
151     }
152     
153     bool operator!() const
154     {
155         return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg
156             && static_cast<GPRReg>(m_payloadGPR) == InvalidGPRReg;
157     }
158     
159     GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
160     GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }
161     GPRReg gpr(WhichValueWord which) const
162     {
163         switch (which) {
164         case TagWord:
165             return tagGPR();
166         case PayloadWord:
167             return payloadGPR();
168         }
169     }
170
171 private:
172     int8_t m_tagGPR;
173     int8_t m_payloadGPR;
174 };
175
176 class JSValueSource {
177 public:
178     JSValueSource()
179         : m_offset(notAddress())
180         , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
181         , m_payload(static_cast<int8_t>(InvalidGPRReg))
182         , m_tagType(0)
183     {
184     }
185     
186     JSValueSource(JSValueRegs regs)
187         : m_offset(notAddress())
188         , m_baseOrTag(regs.tagGPR())
189         , m_payload(regs.payloadGPR())
190         , m_tagType(0)
191     {
192     }
193     
194     JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
195         : m_offset(notAddress())
196         , m_baseOrTag(static_cast<int8_t>(tagGPR))
197         , m_payload(static_cast<int8_t>(payloadGPR))
198         , m_tagType(0)
199     {
200     }
201     
202     JSValueSource(MacroAssembler::Address address)
203         : m_offset(address.offset)
204         , m_baseOrTag(static_cast<int8_t>(address.base))
205         , m_payload(static_cast<int8_t>(InvalidGPRReg))
206         , m_tagType(0)
207     {
208         ASSERT(m_offset != notAddress());
209         ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
210     }
211     
212     static JSValueSource unboxedCell(GPRReg payloadGPR)
213     {
214         JSValueSource result;
215         result.m_offset = notAddress();
216         result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
217         result.m_payload = static_cast<int8_t>(payloadGPR);
218         result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
219         return result;
220     }
221     
222     bool operator!() const
223     {
224         return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg
225             && static_cast<GPRReg>(m_payload) == InvalidGPRReg;
226     }
227     
228     bool isAddress() const
229     {
230         ASSERT(!!*this);
231         return m_offset != notAddress();
232     }
233     
234     int32_t offset() const
235     {
236         ASSERT(isAddress());
237         return m_offset;
238     }
239     
240     GPRReg base() const
241     {
242         ASSERT(isAddress());
243         return static_cast<GPRReg>(m_baseOrTag);
244     }
245     
246     GPRReg tagGPR() const
247     {
248         ASSERT(!isAddress() && static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
249         return static_cast<GPRReg>(m_baseOrTag);
250     }
251     
252     GPRReg payloadGPR() const
253     {
254         ASSERT(!isAddress());
255         return static_cast<GPRReg>(m_payload);
256     }
257     
258     bool hasKnownTag() const
259     {
260         ASSERT(!!*this);
261         ASSERT(!isAddress());
262         return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
263     }
264     
265     uint32_t tag() const
266     {
267         return static_cast<int32_t>(m_tagType);
268     }
269     
270     MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
271     
272 private:
273     static inline int32_t notAddress() { return 0x80000000; }     
274           
275     int32_t m_offset;
276     int8_t m_baseOrTag;
277     int8_t m_payload; 
278     int8_t m_tagType; // Contains the low bits of the tag.
279 };
280 #endif
281
282 #if CPU(X86)
283 #define NUMBER_OF_ARGUMENT_REGISTERS 0
284
285 class GPRInfo {
286 public:
287     typedef GPRReg RegisterType;
288     static const unsigned numberOfRegisters = 5;
289     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
290
291     // Temporary registers.
292     static const GPRReg regT0 = X86Registers::eax;
293     static const GPRReg regT1 = X86Registers::edx;
294     static const GPRReg regT2 = X86Registers::ecx;
295     static const GPRReg regT3 = X86Registers::ebx;
296     static const GPRReg regT4 = X86Registers::esi;
297     // These registers match the baseline JIT.
298     static const GPRReg cachedResultRegister = regT0;
299     static const GPRReg cachedResultRegister2 = regT1;
300     static const GPRReg callFrameRegister = X86Registers::edi;
301     // These constants provide the names for the general purpose argument & return value registers.
302     static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2
303     static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
304     static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0
305     static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3
306     static const GPRReg nonArgGPR2 = X86Registers::esi; // regT4
307     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
308     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
309     static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
310
311     static GPRReg toRegister(unsigned index)
312     {
313         ASSERT(index < numberOfRegisters);
314         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4 };
315         return registerForIndex[index];
316     }
317
318     static unsigned toIndex(GPRReg reg)
319     {
320         ASSERT(reg != InvalidGPRReg);
321         ASSERT(static_cast<int>(reg) < 8);
322         static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, InvalidIndex };
323         unsigned result = indexForRegister[reg];
324         ASSERT(result != InvalidIndex);
325         return result;
326     }
327
328     static const char* debugName(GPRReg reg)
329     {
330         ASSERT(reg != InvalidGPRReg);
331         ASSERT(static_cast<int>(reg) < 8);
332         static const char* nameForRegister[8] = {
333             "eax", "ecx", "edx", "ebx",
334             "esp", "ebp", "esi", "edi",
335         };
336         return nameForRegister[reg];
337     }
338 private:
339
340     static const unsigned InvalidIndex = 0xffffffff;
341 };
342
343 #endif
344
345 #if CPU(X86_64)
346 #define NUMBER_OF_ARGUMENT_REGISTERS 6
347
348 class GPRInfo {
349 public:
350     typedef GPRReg RegisterType;
351     static const unsigned numberOfRegisters = 9;
352     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
353
354     // These registers match the baseline JIT.
355     static const GPRReg cachedResultRegister = X86Registers::eax;
356     static const GPRReg callFrameRegister = X86Registers::r13;
357     static const GPRReg tagTypeNumberRegister = X86Registers::r14;
358     static const GPRReg tagMaskRegister = X86Registers::r15;
359     // Temporary registers.
360     static const GPRReg regT0 = X86Registers::eax;
361     static const GPRReg regT1 = X86Registers::edx;
362     static const GPRReg regT2 = X86Registers::ecx;
363     static const GPRReg regT3 = X86Registers::ebx;
364     static const GPRReg regT4 = X86Registers::edi;
365     static const GPRReg regT5 = X86Registers::esi;
366     static const GPRReg regT6 = X86Registers::r8;
367     static const GPRReg regT7 = X86Registers::r9;
368     static const GPRReg regT8 = X86Registers::r10;
369     // These constants provide the names for the general purpose argument & return value registers.
370     static const GPRReg argumentGPR0 = X86Registers::edi; // regT4
371     static const GPRReg argumentGPR1 = X86Registers::esi; // regT5
372     static const GPRReg argumentGPR2 = X86Registers::edx; // regT1
373     static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2
374     static const GPRReg argumentGPR4 = X86Registers::r8;  // regT6
375     static const GPRReg argumentGPR5 = X86Registers::r9;  // regT7
376     static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0
377     static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3
378     static const GPRReg nonArgGPR2 = X86Registers::r10; // regT8
379     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
380     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
381     static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
382
383     static GPRReg toRegister(unsigned index)
384     {
385         ASSERT(index < numberOfRegisters);
386         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 };
387         return registerForIndex[index];
388     }
389     
390     static GPRReg toArgumentRegister(unsigned index)
391     {
392         ASSERT(index < numberOfArgumentRegisters);
393         static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3, argumentGPR4, argumentGPR5 };
394         return registerForIndex[index];
395     }
396     
397     static unsigned toIndex(GPRReg reg)
398     {
399         ASSERT(reg != InvalidGPRReg);
400         ASSERT(static_cast<int>(reg) < 16);
401         static const unsigned indexForRegister[16] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4, 6, 7, 8, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
402         unsigned result = indexForRegister[reg];
403         ASSERT(result != InvalidIndex);
404         return result;
405     }
406
407     static const char* debugName(GPRReg reg)
408     {
409         ASSERT(reg != InvalidGPRReg);
410         ASSERT(static_cast<int>(reg) < 16);
411         static const char* nameForRegister[16] = {
412             "rax", "rcx", "rdx", "rbx",
413             "rsp", "rbp", "rsi", "rdi",
414             "r8", "r9", "r10", "r11",
415             "r12", "r13", "r14", "r15"
416         };
417         return nameForRegister[reg];
418     }
419 private:
420
421     static const unsigned InvalidIndex = 0xffffffff;
422 };
423
424 #endif
425
426 #if CPU(ARM)
427 #define NUMBER_OF_ARGUMENT_REGISTERS 4
428
429 class GPRInfo {
430 public:
431     typedef GPRReg RegisterType;
432     static const unsigned numberOfRegisters = 8;
433     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
434
435     // Temporary registers.
436     static const GPRReg regT0 = ARMRegisters::r0;
437     static const GPRReg regT1 = ARMRegisters::r1;
438     static const GPRReg regT2 = ARMRegisters::r2;
439     static const GPRReg regT3 = ARMRegisters::r4;
440     static const GPRReg regT4 = ARMRegisters::r8;
441     static const GPRReg regT5 = ARMRegisters::r9;
442     static const GPRReg regT6 = ARMRegisters::r10;
443     static const GPRReg regT7 = ARMRegisters::r11;
444     // These registers match the baseline JIT.
445     static const GPRReg cachedResultRegister = regT0;
446     static const GPRReg cachedResultRegister2 = regT1;
447     static const GPRReg callFrameRegister = ARMRegisters::r5;
448     // These constants provide the names for the general purpose argument & return value registers.
449     static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0
450     static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
451     static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
452     // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems
453     // This could threoretically be a problem if this is used in code generation
454     // between the arguments being set up, and the call being made. That said,
455     // any change introducing a problem here is likely to be immediately apparent!
456     static const GPRReg argumentGPR3 = ARMRegisters::r3; // FIXME!
457     static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT3
458     static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
459     static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
460     static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
461     static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
462     static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2;
463
464     static GPRReg toRegister(unsigned index)
465     {
466         ASSERT(index < numberOfRegisters);
467         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
468         return registerForIndex[index];
469     }
470
471     static unsigned toIndex(GPRReg reg)
472     {
473         ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg);
474         ASSERT(static_cast<unsigned>(reg) < 16);
475         static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
476         unsigned result = indexForRegister[reg];
477         ASSERT(result != InvalidIndex);
478         return result;
479     }
480
481     static const char* debugName(GPRReg reg)
482     {
483         ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg);
484         ASSERT(static_cast<unsigned>(reg) < 16);
485         static const char* nameForRegister[16] = {
486             "r0", "r1", "r2", "r3",
487             "r4", "r5", "r6", "r7",
488             "r8", "r9", "r10", "r11",
489             "r12", "r13", "r14", "r15"
490         };
491         return nameForRegister[reg];
492     }
493 private:
494
495     static const unsigned InvalidIndex = 0xffffffff;
496 };
497
498 #endif
499
500 #if CPU(MIPS)
501 #define NUMBER_OF_ARGUMENT_REGISTERS 4
502
503 class GPRInfo {
504 public:
505     typedef GPRReg RegisterType;
506     static const unsigned numberOfRegisters = 6;
507     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
508
509     // Temporary registers.
510     static const GPRReg regT0 = MIPSRegisters::v0;
511     static const GPRReg regT1 = MIPSRegisters::v1;
512     static const GPRReg regT2 = MIPSRegisters::t4;
513     static const GPRReg regT3 = MIPSRegisters::t5;
514     static const GPRReg regT4 = MIPSRegisters::t6;
515     static const GPRReg regT5 = MIPSRegisters::t7;
516     // These registers match the baseline JIT.
517     static const GPRReg cachedResultRegister = regT0;
518     static const GPRReg cachedResultRegister2 = regT1;
519     static const GPRReg callFrameRegister = MIPSRegisters::s0;
520     // These constants provide the names for the general purpose argument & return value registers.
521     static const GPRReg argumentGPR0 = MIPSRegisters::a0;
522     static const GPRReg argumentGPR1 = MIPSRegisters::a1;
523     static const GPRReg argumentGPR2 = MIPSRegisters::a2;
524     static const GPRReg argumentGPR3 = MIPSRegisters::a3;
525     static const GPRReg nonArgGPR0 = regT2;
526     static const GPRReg nonArgGPR1 = regT3;
527     static const GPRReg nonArgGPR2 = regT4;
528     static const GPRReg returnValueGPR = regT0;
529     static const GPRReg returnValueGPR2 = regT1;
530     static const GPRReg nonPreservedNonReturnGPR = regT5;
531
532     static GPRReg toRegister(unsigned index)
533     {
534         ASSERT(index < numberOfRegisters);
535         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 };
536         return registerForIndex[index];
537     }
538
539     static unsigned toIndex(GPRReg reg)
540     {
541         ASSERT(reg != InvalidGPRReg);
542         ASSERT(reg < 16);
543         static const unsigned indexForRegister[16] = { InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, 2, 3, 4, 5 };
544         unsigned result = indexForRegister[reg];
545         ASSERT(result != InvalidIndex);
546         return result;
547     }
548
549     static const char* debugName(GPRReg reg)
550     {
551         ASSERT(reg != InvalidGPRReg);
552         ASSERT(reg < 16);
553         static const char* nameForRegister[16] = {
554             "zero", "at", "v0", "v1",
555             "a0", "a1", "a2", "a3",
556             "t0", "t1", "t2", "t3",
557             "t4", "t5", "t6", "t7"
558         };
559         return nameForRegister[reg];
560     }
561 private:
562
563     static const unsigned InvalidIndex = 0xffffffff;
564 };
565
566 #endif
567
568 #if CPU(SH4)
569 #define NUMBER_OF_ARGUMENT_REGISTERS 4
570
571 class GPRInfo {
572 public:
573     typedef GPRReg RegisterType;
574     static const unsigned numberOfRegisters = 10;
575
576     // Temporary registers.
577     static const GPRReg regT0 = SH4Registers::r0;
578     static const GPRReg regT1 = SH4Registers::r1;
579     static const GPRReg regT2 = SH4Registers::r2;
580     static const GPRReg regT3 = SH4Registers::r10;
581     static const GPRReg regT4 = SH4Registers::r4;
582     static const GPRReg regT5 = SH4Registers::r5;
583     static const GPRReg regT6 = SH4Registers::r6;
584     static const GPRReg regT7 = SH4Registers::r7;
585     static const GPRReg regT8 = SH4Registers::r8;
586     static const GPRReg regT9 = SH4Registers::r9;
587     // These registers match the baseline JIT.
588     static const GPRReg cachedResultRegister = regT0;
589     static const GPRReg cachedResultRegister2 = regT1;
590     static const GPRReg callFrameRegister = SH4Registers::fp;
591     // These constants provide the names for the general purpose argument & return value registers.
592     static const GPRReg argumentGPR0 = regT4;
593     static const GPRReg argumentGPR1 = regT5;
594     static const GPRReg argumentGPR2 = regT6;
595     static const GPRReg argumentGPR3 = regT7;
596     static const GPRReg nonArgGPR0 = regT3;
597     static const GPRReg nonArgGPR1 = regT8;
598     static const GPRReg nonArgGPR2 = regT9;
599     static const GPRReg returnValueGPR = regT0;
600     static const GPRReg returnValueGPR2 = regT1;
601     static const GPRReg nonPreservedNonReturnGPR = regT2;
602
603     static GPRReg toRegister(unsigned index)
604     {
605         ASSERT(index < numberOfRegisters);
606         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8, regT9 };
607         return registerForIndex[index];
608     }
609
610     static unsigned toIndex(GPRReg reg)
611     {
612         ASSERT(reg != InvalidGPRReg);
613         ASSERT(reg < 14);
614         static const unsigned indexForRegister[14] = { 0, 1, 2, InvalidIndex, 4, 5, 6, 7, 8, 9, 3, InvalidIndex, InvalidIndex, InvalidIndex };
615         unsigned result = indexForRegister[reg];
616         ASSERT(result != InvalidIndex);
617         return result;
618     }
619
620     static const char* debugName(GPRReg reg)
621     {
622         ASSERT(reg != InvalidGPRReg);
623         ASSERT(reg < 16);
624         static const char* nameForRegister[16] = {
625             "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
626             "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
627         };
628         return nameForRegister[reg];
629     }
630
631 private:
632     static const unsigned InvalidIndex = 0xffffffff;
633 };
634
635 #endif
636
637 typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
638
639 } } // namespace JSC::DFG
640
641 #endif
642 #endif