Update FTL to support UntypedUse operands for op_sub.
[WebKit-https.git] / Source / JavaScriptCore / jit / GPRInfo.h
1 /*
2  * Copyright (C) 2011, 2013-2015 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 GPRInfo_h
27 #define GPRInfo_h
28
29 #include "MacroAssembler.h"
30 #include <array>
31 #include <wtf/PrintStream.h>
32
33 namespace JSC {
34
35 // We use the same conventions in the basline JIT as in the LLint. If you
36 // change mappings in the GPRInfo, you should change them in the offlineasm
37 // compiler adequately. The register naming conventions are described at the
38 // top of the LowLevelInterpreter.asm file.
39
40 typedef MacroAssembler::RegisterID GPRReg;
41 #define InvalidGPRReg ((::JSC::GPRReg)-1)
42
43 #if ENABLE(JIT)
44
45 #if USE(JSVALUE64)
46 class JSValueRegs {
47 public:
48     JSValueRegs()
49         : m_gpr(InvalidGPRReg)
50     {
51     }
52     
53     explicit JSValueRegs(GPRReg gpr)
54         : m_gpr(gpr)
55     {
56     }
57     
58     static JSValueRegs payloadOnly(GPRReg gpr)
59     {
60         return JSValueRegs(gpr);
61     }
62     
63     static JSValueRegs withTwoAvailableRegs(GPRReg gpr, GPRReg)
64     {
65         return JSValueRegs(gpr);
66     }
67     
68     bool operator!() const { return m_gpr == InvalidGPRReg; }
69     explicit operator bool() const { return m_gpr != InvalidGPRReg; }
70
71     bool operator==(JSValueRegs other) { return m_gpr == other.m_gpr; }
72     bool operator!=(JSValueRegs other) { return !(*this == other); }
73     
74     GPRReg gpr() const { return m_gpr; }
75     GPRReg tagGPR() const { return InvalidGPRReg; }
76     GPRReg payloadGPR() const { return m_gpr; }
77     
78     bool uses(GPRReg gpr) const { return m_gpr == gpr; }
79     
80 private:
81     GPRReg m_gpr;
82 };
83
84 class JSValueSource {
85 public:
86     JSValueSource()
87         : m_offset(notAddress())
88         , m_base(InvalidGPRReg)
89     {
90     }
91     
92     JSValueSource(JSValueRegs regs)
93         : m_offset(notAddress())
94         , m_base(regs.gpr())
95     {
96     }
97     
98     explicit JSValueSource(GPRReg gpr)
99         : m_offset(notAddress())
100         , m_base(gpr)
101     {
102     }
103     
104     JSValueSource(MacroAssembler::Address address)
105         : m_offset(address.offset)
106         , m_base(address.base)
107     {
108         ASSERT(m_offset != notAddress());
109         ASSERT(m_base != InvalidGPRReg);
110     }
111     
112     static JSValueSource unboxedCell(GPRReg payloadGPR)
113     {
114         return JSValueSource(payloadGPR);
115     }
116     
117     bool operator!() const { return m_base == InvalidGPRReg; }
118     explicit operator bool() const { return m_base != InvalidGPRReg; }
119     
120     bool isAddress() const { return m_offset != notAddress(); }
121     
122     int32_t offset() const
123     {
124         ASSERT(isAddress());
125         return m_offset;
126     }
127     
128     GPRReg base() const
129     {
130         ASSERT(isAddress());
131         return m_base;
132     }
133     
134     GPRReg gpr() const
135     {
136         ASSERT(!isAddress());
137         return m_base;
138     }
139     
140     MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
141     
142 private:
143     static inline int32_t notAddress() { return 0x80000000; }     
144           
145     int32_t m_offset;
146     GPRReg m_base;
147 };
148 #endif // USE(JSVALUE64)
149
150 #if USE(JSVALUE32_64)
151 class JSValueRegs {
152 public:
153     JSValueRegs()
154         : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
155         , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
156     {
157     }
158     
159     JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
160         : m_tagGPR(tagGPR)
161         , m_payloadGPR(payloadGPR)
162     {
163     }
164     
165     static JSValueRegs withTwoAvailableRegs(GPRReg gpr1, GPRReg gpr2)
166     {
167         return JSValueRegs(gpr1, gpr2);
168     }
169     
170     static JSValueRegs payloadOnly(GPRReg gpr)
171     {
172         return JSValueRegs(InvalidGPRReg, gpr);
173     }
174     
175     bool operator!() const { return !static_cast<bool>(*this); }
176     explicit operator bool() const
177     {
178         return static_cast<GPRReg>(m_tagGPR) != InvalidGPRReg
179             || static_cast<GPRReg>(m_payloadGPR) != InvalidGPRReg;
180     }
181
182     bool operator==(JSValueRegs other) const
183     {
184         return m_tagGPR == other.m_tagGPR
185             && m_payloadGPR == other.m_payloadGPR;
186     }
187     bool operator!=(JSValueRegs other) const { return !(*this == other); }
188     
189     GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
190     GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }
191     GPRReg gpr(WhichValueWord which) const
192     {
193         switch (which) {
194         case TagWord:
195             return tagGPR();
196         case PayloadWord:
197             return payloadGPR();
198         }
199         ASSERT_NOT_REACHED();
200         return tagGPR();
201     }
202
203     bool uses(GPRReg gpr) const { return m_tagGPR == gpr || m_payloadGPR == gpr; }
204     
205 private:
206     int8_t m_tagGPR;
207     int8_t m_payloadGPR;
208 };
209
210 class JSValueSource {
211 public:
212     JSValueSource()
213         : m_offset(notAddress())
214         , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
215         , m_payload(static_cast<int8_t>(InvalidGPRReg))
216         , m_tagType(0)
217     {
218     }
219     
220     JSValueSource(JSValueRegs regs)
221         : m_offset(notAddress())
222         , m_baseOrTag(regs.tagGPR())
223         , m_payload(regs.payloadGPR())
224         , m_tagType(0)
225     {
226     }
227     
228     JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
229         : m_offset(notAddress())
230         , m_baseOrTag(static_cast<int8_t>(tagGPR))
231         , m_payload(static_cast<int8_t>(payloadGPR))
232         , m_tagType(0)
233     {
234     }
235     
236     JSValueSource(MacroAssembler::Address address)
237         : m_offset(address.offset)
238         , m_baseOrTag(static_cast<int8_t>(address.base))
239         , m_payload(static_cast<int8_t>(InvalidGPRReg))
240         , m_tagType(0)
241     {
242         ASSERT(m_offset != notAddress());
243         ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
244     }
245     
246     static JSValueSource unboxedCell(GPRReg payloadGPR)
247     {
248         JSValueSource result;
249         result.m_offset = notAddress();
250         result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
251         result.m_payload = static_cast<int8_t>(payloadGPR);
252         result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
253         return result;
254     }
255
256     bool operator!() const { return !static_cast<bool>(*this); }
257     explicit operator bool() const
258     {
259         return static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg
260             || static_cast<GPRReg>(m_payload) != InvalidGPRReg;
261     }
262     
263     bool isAddress() const
264     {
265         ASSERT(!!*this);
266         return m_offset != notAddress();
267     }
268     
269     int32_t offset() const
270     {
271         ASSERT(isAddress());
272         return m_offset;
273     }
274     
275     GPRReg base() const
276     {
277         ASSERT(isAddress());
278         return static_cast<GPRReg>(m_baseOrTag);
279     }
280     
281     GPRReg tagGPR() const
282     {
283         ASSERT(!isAddress() && static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
284         return static_cast<GPRReg>(m_baseOrTag);
285     }
286     
287     GPRReg payloadGPR() const
288     {
289         ASSERT(!isAddress());
290         return static_cast<GPRReg>(m_payload);
291     }
292     
293     bool hasKnownTag() const
294     {
295         ASSERT(!!*this);
296         ASSERT(!isAddress());
297         return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
298     }
299     
300     uint32_t tag() const
301     {
302         return static_cast<int32_t>(m_tagType);
303     }
304     
305     MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
306     
307 private:
308     static inline int32_t notAddress() { return 0x80000000; }     
309           
310     int32_t m_offset;
311     int8_t m_baseOrTag;
312     int8_t m_payload; 
313     int8_t m_tagType; // Contains the low bits of the tag.
314 };
315 #endif // USE(JSVALUE32_64)
316
317 #if CPU(X86)
318 #define NUMBER_OF_ARGUMENT_REGISTERS 0u
319 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
320
321 class GPRInfo {
322 public:
323     typedef GPRReg RegisterType;
324     static const unsigned numberOfRegisters = 6;
325     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
326
327     // Temporary registers.
328     static const GPRReg regT0 = X86Registers::eax;
329     static const GPRReg regT1 = X86Registers::edx;
330     static const GPRReg regT2 = X86Registers::ecx;
331     static const GPRReg regT3 = X86Registers::ebx; // Callee-save
332     static const GPRReg regT4 = X86Registers::esi; // Callee-save
333     static const GPRReg regT5 = X86Registers::edi; // Callee-save
334     static const GPRReg callFrameRegister = X86Registers::ebp;
335     // These constants provide the names for the general purpose argument & return value registers.
336     static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2
337     static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
338     static const GPRReg argumentGPR2 = X86Registers::eax; // regT0
339     static const GPRReg argumentGPR3 = X86Registers::ebx; // regT3
340     static const GPRReg nonArgGPR0 = X86Registers::esi; // regT4
341     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
342     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
343     static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
344
345     static GPRReg toRegister(unsigned index)
346     {
347         ASSERT(index < numberOfRegisters);
348         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 };
349         return registerForIndex[index];
350     }
351
352     static GPRReg toArgumentRegister(unsigned)
353     {
354         UNREACHABLE_FOR_PLATFORM();
355         return InvalidGPRReg;
356     }
357
358     static unsigned toIndex(GPRReg reg)
359     {
360         ASSERT(reg != InvalidGPRReg);
361         ASSERT(static_cast<int>(reg) < 8);
362         static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, 5 };
363         unsigned result = indexForRegister[reg];
364         return result;
365     }
366
367     static const char* debugName(GPRReg reg)
368     {
369         ASSERT(reg != InvalidGPRReg);
370         ASSERT(static_cast<int>(reg) < 8);
371         static const char* nameForRegister[8] = {
372             "eax", "ecx", "edx", "ebx",
373             "esp", "ebp", "esi", "edi",
374         };
375         return nameForRegister[reg];
376     }
377
378     static const unsigned InvalidIndex = 0xffffffff;
379 };
380
381 #endif // CPU(X86)
382
383 #if CPU(X86_64)
384 #if !OS(WINDOWS)
385 #define NUMBER_OF_ARGUMENT_REGISTERS 6u
386 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 5u
387 #else
388 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
389 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 7u
390 #endif
391
392 class GPRInfo {
393 public:
394     typedef GPRReg RegisterType;
395     static const unsigned numberOfRegisters = 11;
396     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
397
398     // These registers match the baseline JIT.
399     static const GPRReg callFrameRegister = X86Registers::ebp;
400     static const GPRReg tagTypeNumberRegister = X86Registers::r14;
401     static const GPRReg tagMaskRegister = X86Registers::r15;
402     static const GPRReg scratchRegister = MacroAssembler::scratchRegister;
403
404     // Temporary registers.
405     static const GPRReg regT0 = X86Registers::eax;
406 #if !OS(WINDOWS)
407     static const GPRReg regT1 = X86Registers::esi;
408     static const GPRReg regT2 = X86Registers::edx;
409     static const GPRReg regT3 = X86Registers::ecx;
410     static const GPRReg regT4 = X86Registers::r8;
411     static const GPRReg regT5 = X86Registers::r10;
412     static const GPRReg regT6 = X86Registers::edi;
413     static const GPRReg regT7 = X86Registers::r9;
414 #else
415     static const GPRReg regT1 = X86Registers::edx;
416     static const GPRReg regT2 = X86Registers::r8;
417     static const GPRReg regT3 = X86Registers::r9;
418     static const GPRReg regT4 = X86Registers::r10;
419     static const GPRReg regT5 = X86Registers::ecx;
420 #endif
421
422     static const GPRReg regCS0 = X86Registers::ebx;
423
424 #if !OS(WINDOWS)
425     static const GPRReg regCS1 = X86Registers::r12;
426     static const GPRReg regCS2 = X86Registers::r13;
427     static const GPRReg regCS3 = X86Registers::r14;
428     static const GPRReg regCS4 = X86Registers::r15;
429 #else
430     static const GPRReg regCS1 = X86Registers::esi;
431     static const GPRReg regCS2 = X86Registers::edi;
432     static const GPRReg regCS3 = X86Registers::r12;
433     static const GPRReg regCS4 = X86Registers::r13;
434     static const GPRReg regCS5 = X86Registers::r14;
435     static const GPRReg regCS6 = X86Registers::r15;
436 #endif
437
438     // These constants provide the names for the general purpose argument & return value registers.
439 #if !OS(WINDOWS)
440     static const GPRReg argumentGPR0 = X86Registers::edi; // regT6
441     static const GPRReg argumentGPR1 = X86Registers::esi; // regT1
442     static const GPRReg argumentGPR2 = X86Registers::edx; // regT2
443     static const GPRReg argumentGPR3 = X86Registers::ecx; // regT3
444     static const GPRReg argumentGPR4 = X86Registers::r8; // regT4
445     static const GPRReg argumentGPR5 = X86Registers::r9; // regT7
446 #else
447     static const GPRReg argumentGPR0 = X86Registers::ecx; // regT5
448     static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
449     static const GPRReg argumentGPR2 = X86Registers::r8; // regT2
450     static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
451 #endif
452     static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
453     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
454     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
455     static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
456     static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
457     static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
458
459     static GPRReg toRegister(unsigned index)
460     {
461         ASSERT(index < numberOfRegisters);
462 #if !OS(WINDOWS)
463         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regCS0, regCS1, regCS2 };
464 #else
465         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regCS0, regCS1, regCS2, regCS3, regCS4 };
466 #endif
467         return registerForIndex[index];
468     }
469     
470     static GPRReg toArgumentRegister(unsigned index)
471     {
472         ASSERT(index < numberOfArgumentRegisters);
473 #if !OS(WINDOWS)
474         static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3, argumentGPR4, argumentGPR5 };
475 #else
476         static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3 };
477 #endif
478         return registerForIndex[index];
479     }
480     
481     static unsigned toIndex(GPRReg reg)
482     {
483         ASSERT(reg != InvalidGPRReg);
484         ASSERT(static_cast<int>(reg) < 16);
485 #if !OS(WINDOWS)
486         static const unsigned indexForRegister[16] = { 0, 3, 2, 8, InvalidIndex, InvalidIndex, 1, 6, 4, 7, 5, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
487 #else
488         static const unsigned indexForRegister[16] = { 0, 5, 1, 6, InvalidIndex, InvalidIndex, 7, 8, 2, 3, 4, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
489 #endif
490         return indexForRegister[reg];
491     }
492
493     static const char* debugName(GPRReg reg)
494     {
495         ASSERT(reg != InvalidGPRReg);
496         ASSERT(static_cast<int>(reg) < 16);
497         static const char* nameForRegister[16] = {
498             "rax", "rcx", "rdx", "rbx",
499             "rsp", "rbp", "rsi", "rdi",
500             "r8", "r9", "r10", "r11",
501             "r12", "r13", "r14", "r15"
502         };
503         return nameForRegister[reg];
504     }
505
506     static const std::array<GPRReg, 3>& reservedRegisters()
507     {
508         static const std::array<GPRReg, 3> reservedRegisters { {
509             scratchRegister,
510             tagTypeNumberRegister,
511             tagMaskRegister,
512         } };
513         return reservedRegisters;
514     }
515     
516     static const unsigned InvalidIndex = 0xffffffff;
517 };
518
519 #endif // CPU(X86_64)
520
521 #if CPU(ARM)
522 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
523 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
524
525 class GPRInfo {
526 public:
527     typedef GPRReg RegisterType;
528     static const unsigned numberOfRegisters = 9;
529     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
530
531     // Temporary registers.
532     static const GPRReg regT0 = ARMRegisters::r0;
533     static const GPRReg regT1 = ARMRegisters::r1;
534     static const GPRReg regT2 = ARMRegisters::r2;
535     static const GPRReg regT3 = ARMRegisters::r3;
536     static const GPRReg regT4 = ARMRegisters::r8;
537     static const GPRReg regT5 = ARMRegisters::r9;
538     static const GPRReg regT6 = ARMRegisters::r10;
539 #if CPU(ARM_THUMB2)
540     static const GPRReg regT7 = ARMRegisters::r11;
541 #else 
542     static const GPRReg regT7 = ARMRegisters::r7;
543 #endif
544     static const GPRReg regT8 = ARMRegisters::r4;
545     // These registers match the baseline JIT.
546     static const GPRReg callFrameRegister = ARMRegisters::fp;
547     // These constants provide the names for the general purpose argument & return value registers.
548     static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0
549     static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
550     static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
551     static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT3
552     static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT8
553     static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
554     static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
555     static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
556     static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5;
557
558     static GPRReg toRegister(unsigned index)
559     {
560         ASSERT(index < numberOfRegisters);
561         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 };
562         return registerForIndex[index];
563     }
564
565     static GPRReg toArgumentRegister(unsigned index)
566     {
567         ASSERT(index < numberOfArgumentRegisters);
568         static const GPRReg registerForIndex[numberOfArgumentRegisters] = { argumentGPR0, argumentGPR1, argumentGPR2, argumentGPR3 };
569         return registerForIndex[index];
570     }
571
572     static unsigned toIndex(GPRReg reg)
573     {
574         ASSERT(reg != InvalidGPRReg);
575         ASSERT(static_cast<int>(reg) < 16);
576         static const unsigned indexForRegister[16] =
577 #if CPU(ARM_THUMB2)
578             { 0, 1, 2, 3, 8, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
579 #else
580             { 0, 1, 2, 3, 8, InvalidIndex, InvalidIndex, 7, 4, 5, 6, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
581 #endif
582         unsigned result = indexForRegister[reg];
583         return result;
584     }
585
586     static const char* debugName(GPRReg reg)
587     {
588         ASSERT(reg != InvalidGPRReg);
589         ASSERT(static_cast<int>(reg) < 16);
590         static const char* nameForRegister[16] = {
591             "r0", "r1", "r2", "r3",
592             "r4", "r5", "r6", "r7",
593             "r8", "r9", "r10", "r11",
594             "r12", "r13", "r14", "r15"
595         };
596         return nameForRegister[reg];
597     }
598
599     static const unsigned InvalidIndex = 0xffffffff;
600 };
601
602 #endif // CPU(ARM)
603
604 #if CPU(ARM64)
605 #define NUMBER_OF_ARGUMENT_REGISTERS 8u
606 // Callee Saves includes x19..x28 and FP registers q8..q15
607 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 18u
608
609 class GPRInfo {
610 public:
611     typedef GPRReg RegisterType;
612     static const unsigned numberOfRegisters = 16;
613     static const unsigned numberOfArgumentRegisters = 8;
614
615     // These registers match the baseline JIT.
616     static const GPRReg callFrameRegister = ARM64Registers::fp;
617     static const GPRReg tagTypeNumberRegister = ARM64Registers::x27;
618     static const GPRReg tagMaskRegister = ARM64Registers::x28;
619     static const GPRReg dataTempRegister = MacroAssembler::dataTempRegister;
620     static const GPRReg memoryTempRegister = MacroAssembler::memoryTempRegister;
621     // Temporary registers.
622     static const GPRReg regT0 = ARM64Registers::x0;
623     static const GPRReg regT1 = ARM64Registers::x1;
624     static const GPRReg regT2 = ARM64Registers::x2;
625     static const GPRReg regT3 = ARM64Registers::x3;
626     static const GPRReg regT4 = ARM64Registers::x4;
627     static const GPRReg regT5 = ARM64Registers::x5;
628     static const GPRReg regT6 = ARM64Registers::x6;
629     static const GPRReg regT7 = ARM64Registers::x7;
630     static const GPRReg regT8 = ARM64Registers::x8;
631     static const GPRReg regT9 = ARM64Registers::x9;
632     static const GPRReg regT10 = ARM64Registers::x10;
633     static const GPRReg regT11 = ARM64Registers::x11;
634     static const GPRReg regT12 = ARM64Registers::x12;
635     static const GPRReg regT13 = ARM64Registers::x13;
636     static const GPRReg regT14 = ARM64Registers::x14;
637     static const GPRReg regT15 = ARM64Registers::x15;
638     static const GPRReg regCS0 = ARM64Registers::x19; // Used by FTL only
639     static const GPRReg regCS1 = ARM64Registers::x20; // Used by FTL only
640     static const GPRReg regCS2 = ARM64Registers::x21; // Used by FTL only
641     static const GPRReg regCS3 = ARM64Registers::x22; // Used by FTL only
642     static const GPRReg regCS4 = ARM64Registers::x23; // Used by FTL only
643     static const GPRReg regCS5 = ARM64Registers::x24; // Used by FTL only
644     static const GPRReg regCS6 = ARM64Registers::x25; // Used by FTL only
645     static const GPRReg regCS7 = ARM64Registers::x26;
646     static const GPRReg regCS8 = ARM64Registers::x27; // tagTypeNumber
647     static const GPRReg regCS9 = ARM64Registers::x28; // tagMask
648     // These constants provide the names for the general purpose argument & return value registers.
649     static const GPRReg argumentGPR0 = ARM64Registers::x0; // regT0
650     static const GPRReg argumentGPR1 = ARM64Registers::x1; // regT1
651     static const GPRReg argumentGPR2 = ARM64Registers::x2; // regT2
652     static const GPRReg argumentGPR3 = ARM64Registers::x3; // regT3
653     static const GPRReg argumentGPR4 = ARM64Registers::x4; // regT4
654     static const GPRReg argumentGPR5 = ARM64Registers::x5; // regT5
655     static const GPRReg argumentGPR6 = ARM64Registers::x6; // regT6
656     static const GPRReg argumentGPR7 = ARM64Registers::x7; // regT7
657     static const GPRReg nonArgGPR0 = ARM64Registers::x8; // regT8
658     static const GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9
659     static const GPRReg returnValueGPR = ARM64Registers::x0; // regT0
660     static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1
661     static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
662     static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
663     static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
664
665     // GPRReg mapping is direct, the machine register numbers can
666     // be used directly as indices into the GPR RegisterBank.
667     COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0);
668     COMPILE_ASSERT(ARM64Registers::q1 == 1, q1_is_1);
669     COMPILE_ASSERT(ARM64Registers::q2 == 2, q2_is_2);
670     COMPILE_ASSERT(ARM64Registers::q3 == 3, q3_is_3);
671     COMPILE_ASSERT(ARM64Registers::q4 == 4, q4_is_4);
672     COMPILE_ASSERT(ARM64Registers::q5 == 5, q5_is_5);
673     COMPILE_ASSERT(ARM64Registers::q6 == 6, q6_is_6);
674     COMPILE_ASSERT(ARM64Registers::q7 == 7, q7_is_7);
675     COMPILE_ASSERT(ARM64Registers::q8 == 8, q8_is_8);
676     COMPILE_ASSERT(ARM64Registers::q9 == 9, q9_is_9);
677     COMPILE_ASSERT(ARM64Registers::q10 == 10, q10_is_10);
678     COMPILE_ASSERT(ARM64Registers::q11 == 11, q11_is_11);
679     COMPILE_ASSERT(ARM64Registers::q12 == 12, q12_is_12);
680     COMPILE_ASSERT(ARM64Registers::q13 == 13, q13_is_13);
681     COMPILE_ASSERT(ARM64Registers::q14 == 14, q14_is_14);
682     COMPILE_ASSERT(ARM64Registers::q15 == 15, q15_is_15);
683     static GPRReg toRegister(unsigned index)
684     {
685         return (GPRReg)index;
686     }
687     static unsigned toIndex(GPRReg reg)
688     {
689         if (reg > regT15)
690             return InvalidIndex;
691         return (unsigned)reg;
692     }
693
694     static GPRReg toArgumentRegister(unsigned index)
695     {
696         ASSERT(index < numberOfArgumentRegisters);
697         return toRegister(index);
698     }
699
700     static const char* debugName(GPRReg reg)
701     {
702         ASSERT(reg != InvalidGPRReg);
703         ASSERT(static_cast<unsigned>(reg) < 32);
704         static const char* nameForRegister[32] = {
705             "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
706             "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
707             "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
708             "r24", "r25", "r26", "r27", "r28", "fp", "lr", "sp"
709         };
710         return nameForRegister[reg];
711     }
712
713     static const std::array<GPRReg, 4>& reservedRegisters()
714     {
715         static const std::array<GPRReg, 4> reservedRegisters { {
716             dataTempRegister,
717             memoryTempRegister,
718             tagTypeNumberRegister,
719             tagMaskRegister,
720         } };
721         return reservedRegisters;
722     }
723     
724     static const unsigned InvalidIndex = 0xffffffff;
725 };
726
727 #endif // CPU(ARM64)
728
729 #if CPU(MIPS)
730 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
731 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
732
733 class GPRInfo {
734 public:
735     typedef GPRReg RegisterType;
736     static const unsigned numberOfRegisters = 8;
737     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
738
739     // regT0 must be v0 for returning a 32-bit value.
740     // regT1 must be v1 for returning a pair of 32-bit value.
741
742     // Temporary registers.
743     static const GPRReg regT0 = MIPSRegisters::v0;
744     static const GPRReg regT1 = MIPSRegisters::v1;
745     static const GPRReg regT2 = MIPSRegisters::t2;
746     static const GPRReg regT3 = MIPSRegisters::t3;
747     static const GPRReg regT4 = MIPSRegisters::t4;
748     static const GPRReg regT5 = MIPSRegisters::t5;
749     static const GPRReg regT6 = MIPSRegisters::t0;
750     static const GPRReg regT7 = MIPSRegisters::t1;
751     // These registers match the baseline JIT.
752     static const GPRReg callFrameRegister = MIPSRegisters::fp;
753     // These constants provide the names for the general purpose argument & return value registers.
754     static const GPRReg argumentGPR0 = MIPSRegisters::a0;
755     static const GPRReg argumentGPR1 = MIPSRegisters::a1;
756     static const GPRReg argumentGPR2 = MIPSRegisters::a2;
757     static const GPRReg argumentGPR3 = MIPSRegisters::a3;
758     static const GPRReg nonArgGPR0 = regT0;
759     static const GPRReg returnValueGPR = regT0;
760     static const GPRReg returnValueGPR2 = regT1;
761     static const GPRReg nonPreservedNonReturnGPR = regT2;
762
763     static GPRReg toRegister(unsigned index)
764     {
765         ASSERT(index < numberOfRegisters);
766         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
767         return registerForIndex[index];
768     }
769
770     static unsigned toIndex(GPRReg reg)
771     {
772         ASSERT(reg != InvalidGPRReg);
773         ASSERT(reg < 24);
774         static const unsigned indexForRegister[24] = {
775             InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
776             6, 7, 2, 3, 4, 5, InvalidIndex, InvalidIndex,
777             InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex
778         };
779         unsigned result = indexForRegister[reg];
780         return result;
781     }
782
783     static const char* debugName(GPRReg reg)
784     {
785         ASSERT(reg != InvalidGPRReg);
786         ASSERT(reg < 16);
787         static const char* nameForRegister[16] = {
788             "zero", "at", "v0", "v1",
789             "a0", "a1", "a2", "a3",
790             "t0", "t1", "t2", "t3",
791             "t4", "t5", "t6", "t7"
792         };
793         return nameForRegister[reg];
794     }
795
796     static const unsigned InvalidIndex = 0xffffffff;
797 };
798
799 #endif // CPU(MIPS)
800
801 #if CPU(SH4)
802 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
803 #define NUMBER_OF_CALLEE_SAVES_REGISTERS 0u
804
805 class GPRInfo {
806 public:
807     typedef GPRReg RegisterType;
808     static const unsigned numberOfRegisters = 10;
809
810     // Note: regT3 is required to be callee-preserved.
811
812     // Temporary registers.
813     static const GPRReg regT0 = SH4Registers::r0;
814     static const GPRReg regT1 = SH4Registers::r1;
815     static const GPRReg regT2 = SH4Registers::r6;
816     static const GPRReg regT3 = SH4Registers::r7;
817     static const GPRReg regT4 = SH4Registers::r2;
818     static const GPRReg regT5 = SH4Registers::r3;
819     static const GPRReg regT6 = SH4Registers::r4;
820     static const GPRReg regT7 = SH4Registers::r5;
821     static const GPRReg regT8 = SH4Registers::r8;
822     static const GPRReg regT9 = SH4Registers::r9;
823     // These registers match the baseline JIT.
824     static const GPRReg cachedResultRegister = regT0;
825     static const GPRReg cachedResultRegister2 = regT1;
826     static const GPRReg callFrameRegister = SH4Registers::fp;
827     // These constants provide the names for the general purpose argument & return value registers.
828     static const GPRReg argumentGPR0 = SH4Registers::r4; // regT6
829     static const GPRReg argumentGPR1 = SH4Registers::r5; // regT7
830     static const GPRReg argumentGPR2 = SH4Registers::r6; // regT2
831     static const GPRReg argumentGPR3 = SH4Registers::r7; // regT3
832     static const GPRReg nonArgGPR0 = regT4;
833     static const GPRReg returnValueGPR = regT0;
834     static const GPRReg returnValueGPR2 = regT1;
835     static const GPRReg nonPreservedNonReturnGPR = regT2;
836
837     static GPRReg toRegister(unsigned index)
838     {
839         ASSERT(index < numberOfRegisters);
840         static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8, regT9 };
841         return registerForIndex[index];
842     }
843
844     static unsigned toIndex(GPRReg reg)
845     {
846         ASSERT(reg != InvalidGPRReg);
847         ASSERT(reg < 14);
848         static const unsigned indexForRegister[14] = { 0, 1, 4, 5, 6, 7, 2, 3, 8, 9, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
849         unsigned result = indexForRegister[reg];
850         return result;
851     }
852
853     static const char* debugName(GPRReg reg)
854     {
855         ASSERT(reg != InvalidGPRReg);
856         ASSERT(reg < 16);
857         static const char* nameForRegister[16] = {
858             "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
859             "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
860         };
861         return nameForRegister[reg];
862     }
863
864     static const unsigned InvalidIndex = 0xffffffff;
865 };
866
867 #endif // CPU(SH4)
868
869 // The baseline JIT uses "accumulator" style execution with regT0 (for 64-bit)
870 // and regT0 + regT1 (for 32-bit) serving as the accumulator register(s) for
871 // passing results of one opcode to the next. Hence:
872 COMPILE_ASSERT(GPRInfo::regT0 == GPRInfo::returnValueGPR, regT0_must_equal_returnValueGPR);
873 #if USE(JSVALUE32_64)
874 COMPILE_ASSERT(GPRInfo::regT1 == GPRInfo::returnValueGPR2, regT1_must_equal_returnValueGPR2);
875 #endif
876
877 #endif // ENABLE(JIT)
878
879 } // namespace JSC
880
881 namespace WTF {
882
883 inline void printInternal(PrintStream& out, JSC::GPRReg reg)
884 {
885 #if ENABLE(JIT)
886     out.print("%", JSC::GPRInfo::debugName(reg));
887 #else
888     out.printf("%%r%d", reg);
889 #endif
890 }
891
892 } // namespace WTF
893
894 #endif