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