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