2 * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "MacroAssembler.h"
30 #include <wtf/PrintStream.h>
34 typedef MacroAssembler::RegisterID GPRReg
;
35 #define InvalidGPRReg ((::JSC::GPRReg)-1)
43 : m_gpr(InvalidGPRReg
)
47 explicit JSValueRegs(GPRReg gpr
)
52 static JSValueRegs
payloadOnly(GPRReg gpr
)
54 return JSValueRegs(gpr
);
57 static JSValueRegs
withTwoAvailableRegs(GPRReg gpr
, GPRReg
)
59 return JSValueRegs(gpr
);
62 bool operator!() const { return m_gpr
== InvalidGPRReg
; }
64 GPRReg
gpr() const { return m_gpr
; }
65 GPRReg
tagGPR() const { return InvalidGPRReg
; }
66 GPRReg
payloadGPR() const { return m_gpr
; }
68 bool uses(GPRReg gpr
) const { return m_gpr
== gpr
; }
77 : m_offset(notAddress())
78 , m_base(InvalidGPRReg
)
82 JSValueSource(JSValueRegs regs
)
83 : m_offset(notAddress())
88 explicit JSValueSource(GPRReg gpr
)
89 : m_offset(notAddress())
94 JSValueSource(MacroAssembler::Address address
)
95 : m_offset(address
.offset
)
96 , m_base(address
.base
)
98 ASSERT(m_offset
!= notAddress());
99 ASSERT(m_base
!= InvalidGPRReg
);
102 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
104 return JSValueSource(payloadGPR
);
107 bool operator!() const { return m_base
== InvalidGPRReg
; }
109 bool isAddress() const { return m_offset
!= notAddress(); }
111 int32_t offset() const
125 ASSERT(!isAddress());
129 MacroAssembler::Address
asAddress() const { return MacroAssembler::Address(base(), offset()); }
132 static inline int32_t notAddress() { return 0x80000000; }
137 #endif // USE(JSVALUE64)
139 #if USE(JSVALUE32_64)
143 : m_tagGPR(static_cast<int8_t>(InvalidGPRReg
))
144 , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg
))
148 JSValueRegs(GPRReg tagGPR
, GPRReg payloadGPR
)
150 , m_payloadGPR(payloadGPR
)
154 static JSValueRegs
withTwoAvailableRegs(GPRReg gpr1
, GPRReg gpr2
)
156 return JSValueRegs(gpr1
, gpr2
);
159 static JSValueRegs
payloadOnly(GPRReg gpr
)
161 return JSValueRegs(InvalidGPRReg
, gpr
);
164 bool operator!() const
166 return static_cast<GPRReg
>(m_tagGPR
) == InvalidGPRReg
167 && static_cast<GPRReg
>(m_payloadGPR
) == InvalidGPRReg
;
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
180 ASSERT_NOT_REACHED();
184 bool uses(GPRReg gpr
) const { return m_tagGPR
== gpr
|| m_payloadGPR
== gpr
; }
191 class JSValueSource
{
194 : m_offset(notAddress())
195 , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg
))
196 , m_payload(static_cast<int8_t>(InvalidGPRReg
))
201 JSValueSource(JSValueRegs regs
)
202 : m_offset(notAddress())
203 , m_baseOrTag(regs
.tagGPR())
204 , m_payload(regs
.payloadGPR())
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
))
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
))
223 ASSERT(m_offset
!= notAddress());
224 ASSERT(static_cast<GPRReg
>(m_baseOrTag
) != InvalidGPRReg
);
227 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
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
);
237 bool operator!() const
239 return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
240 && static_cast<GPRReg
>(m_payload
) == InvalidGPRReg
;
243 bool isAddress() const
246 return m_offset
!= notAddress();
249 int32_t offset() const
258 return static_cast<GPRReg
>(m_baseOrTag
);
261 GPRReg
tagGPR() const
263 ASSERT(!isAddress() && static_cast<GPRReg
>(m_baseOrTag
) != InvalidGPRReg
);
264 return static_cast<GPRReg
>(m_baseOrTag
);
267 GPRReg
payloadGPR() const
269 ASSERT(!isAddress());
270 return static_cast<GPRReg
>(m_payload
);
273 bool hasKnownTag() const
276 ASSERT(!isAddress());
277 return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
;
282 return static_cast<int32_t>(m_tagType
);
285 MacroAssembler::Address
asAddress(unsigned additionalOffset
= 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset
); }
288 static inline int32_t notAddress() { return 0x80000000; }
293 int8_t m_tagType
; // Contains the low bits of the tag.
295 #endif // USE(JSVALUE32_64)
297 // The baseline JIT requires that regT3 be callee-preserved.
300 #define NUMBER_OF_ARGUMENT_REGISTERS 0u
304 typedef GPRReg RegisterType
;
305 static const unsigned numberOfRegisters
= 6;
306 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
308 // Note: regT3 is required to be callee-preserved.
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
;
331 static GPRReg
toRegister(unsigned index
)
333 ASSERT(index
< numberOfRegisters
);
334 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
};
335 return registerForIndex
[index
];
338 static GPRReg
toArgumentRegister(unsigned)
340 UNREACHABLE_FOR_PLATFORM();
341 return InvalidGPRReg
;
344 static unsigned toIndex(GPRReg reg
)
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
];
353 static const char* debugName(GPRReg reg
)
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",
361 return nameForRegister
[reg
];
364 static const unsigned InvalidIndex
= 0xffffffff;
371 #define NUMBER_OF_ARGUMENT_REGISTERS 6u
373 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
378 typedef GPRReg RegisterType
;
379 static const unsigned numberOfRegisters
= 11;
380 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
382 // Note: regT3 is required to be callee-preserved.
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.
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
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
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
;
424 static GPRReg
toRegister(unsigned index
)
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
];
431 static GPRReg
toArgumentRegister(unsigned index
)
433 ASSERT(index
< numberOfArgumentRegisters
);
435 static const GPRReg registerForIndex
[numberOfArgumentRegisters
] = { argumentGPR0
, argumentGPR1
, argumentGPR2
, argumentGPR3
, argumentGPR4
, argumentGPR5
};
437 static const GPRReg registerForIndex
[numberOfArgumentRegisters
] = { argumentGPR0
, argumentGPR1
, argumentGPR2
, argumentGPR3
};
439 return registerForIndex
[index
];
442 static unsigned toIndex(GPRReg reg
)
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
];
450 static const char* debugName(GPRReg reg
)
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"
460 return nameForRegister
[reg
];
463 static const unsigned InvalidIndex
= 0xffffffff;
466 #endif // CPU(X86_64)
469 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
473 typedef GPRReg RegisterType
;
474 static const unsigned numberOfRegisters
= 9;
475 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
477 // Note: regT3 is required to be callee-preserved.
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
;
488 static const GPRReg regT7
= ARMRegisters::r11
;
490 static const GPRReg regT7
= ARMRegisters::r7
;
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
509 static GPRReg
toRegister(unsigned index
)
511 ASSERT(index
< numberOfRegisters
);
512 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
, regT8
};
513 return registerForIndex
[index
];
516 static GPRReg
toArgumentRegister(unsigned index
)
518 ASSERT(index
< numberOfArgumentRegisters
);
519 static const GPRReg registerForIndex
[numberOfArgumentRegisters
] = { argumentGPR0
, argumentGPR1
, argumentGPR2
, argumentGPR3
};
520 return registerForIndex
[index
];
523 static unsigned toIndex(GPRReg reg
)
525 ASSERT(reg
!= InvalidGPRReg
);
526 ASSERT(static_cast<int>(reg
) < 16);
527 static const unsigned indexForRegister
[16] =
529 { 0, 1, 2, 8, 3, 9, InvalidIndex
, InvalidIndex
, 4, 5, 6, 7, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
531 { 0, 1, 2, 8, 3, 9, InvalidIndex
, 7, 4, 5, 6, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
533 unsigned result
= indexForRegister
[reg
];
537 static const char* debugName(GPRReg reg
)
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"
547 return nameForRegister
[reg
];
550 static const unsigned InvalidIndex
= 0xffffffff;
556 #define NUMBER_OF_ARGUMENT_REGISTERS 8u
560 typedef GPRReg RegisterType
;
561 static const unsigned numberOfRegisters
= 16;
562 static const unsigned numberOfArgumentRegisters
= 8;
564 // Note: regT3 is required to be callee-preserved.
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
;
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
)
627 return (GPRReg
)index
;
629 static unsigned toIndex(GPRReg reg
)
633 return (unsigned)reg
;
636 static GPRReg
toArgumentRegister(unsigned index
)
638 ASSERT(index
< numberOfArgumentRegisters
);
639 return toRegister(index
);
642 static const char* debugName(GPRReg reg
)
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"
652 return nameForRegister
[reg
];
655 static const unsigned InvalidIndex
= 0xffffffff;
661 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
665 typedef GPRReg RegisterType
;
666 static const unsigned numberOfRegisters
= 7;
667 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
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.
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
;
697 static GPRReg
toRegister(unsigned index
)
699 ASSERT(index
< numberOfRegisters
);
700 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
};
701 return registerForIndex
[index
];
704 static unsigned toIndex(GPRReg reg
)
706 ASSERT(reg
!= InvalidGPRReg
);
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
713 unsigned result
= indexForRegister
[reg
];
717 static const char* debugName(GPRReg reg
)
719 ASSERT(reg
!= InvalidGPRReg
);
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"
727 return nameForRegister
[reg
];
730 static const unsigned InvalidIndex
= 0xffffffff;
736 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
740 typedef GPRReg RegisterType
;
741 static const unsigned numberOfRegisters
= 10;
743 // Note: regT3 is required to be callee-preserved.
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
;
772 static GPRReg
toRegister(unsigned index
)
774 ASSERT(index
< numberOfRegisters
);
775 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
, regT8
, regT9
};
776 return registerForIndex
[index
];
779 static unsigned toIndex(GPRReg reg
)
781 ASSERT(reg
!= InvalidGPRReg
);
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
];
788 static const char* debugName(GPRReg reg
)
790 ASSERT(reg
!= InvalidGPRReg
);
792 static const char* nameForRegister
[16] = {
793 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
794 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
796 return nameForRegister
[reg
];
799 static const unsigned InvalidIndex
= 0xffffffff;
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
);
812 #endif // ENABLE(JIT)
818 inline void printInternal(PrintStream
& out
, JSC::GPRReg reg
)
821 out
.print("%", JSC::GPRInfo::debugName(reg
));
823 out
.printf("%%r%d", reg
);