2 * Copyright (C) 2011, 2013, 2014 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 bool operator!() const { return m_gpr
== InvalidGPRReg
; }
59 GPRReg
gpr() const { return m_gpr
; }
60 GPRReg
tagGPR() const { return InvalidGPRReg
; }
61 GPRReg
payloadGPR() const { return m_gpr
; }
70 : m_offset(notAddress())
71 , m_base(InvalidGPRReg
)
75 JSValueSource(JSValueRegs regs
)
76 : m_offset(notAddress())
81 explicit JSValueSource(GPRReg gpr
)
82 : m_offset(notAddress())
87 JSValueSource(MacroAssembler::Address address
)
88 : m_offset(address
.offset
)
89 , m_base(address
.base
)
91 ASSERT(m_offset
!= notAddress());
92 ASSERT(m_base
!= InvalidGPRReg
);
95 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
97 return JSValueSource(payloadGPR
);
100 bool operator!() const { return m_base
== InvalidGPRReg
; }
102 bool isAddress() const { return m_offset
!= notAddress(); }
104 int32_t offset() const
118 ASSERT(!isAddress());
122 MacroAssembler::Address
asAddress() const { return MacroAssembler::Address(base(), offset()); }
125 static inline int32_t notAddress() { return 0x80000000; }
130 #endif // USE(JSVALUE64)
132 #if USE(JSVALUE32_64)
136 : m_tagGPR(static_cast<int8_t>(InvalidGPRReg
))
137 , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg
))
141 JSValueRegs(GPRReg tagGPR
, GPRReg payloadGPR
)
143 , m_payloadGPR(payloadGPR
)
147 static JSValueRegs
payloadOnly(GPRReg gpr
)
149 return JSValueRegs(InvalidGPRReg
, gpr
);
152 bool operator!() const
154 return static_cast<GPRReg
>(m_tagGPR
) == InvalidGPRReg
155 && static_cast<GPRReg
>(m_payloadGPR
) == InvalidGPRReg
;
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
168 ASSERT_NOT_REACHED();
177 class JSValueSource
{
180 : m_offset(notAddress())
181 , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg
))
182 , m_payload(static_cast<int8_t>(InvalidGPRReg
))
187 JSValueSource(JSValueRegs regs
)
188 : m_offset(notAddress())
189 , m_baseOrTag(regs
.tagGPR())
190 , m_payload(regs
.payloadGPR())
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
))
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
))
209 ASSERT(m_offset
!= notAddress());
210 ASSERT(static_cast<GPRReg
>(m_baseOrTag
) != InvalidGPRReg
);
213 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
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
);
223 bool operator!() const
225 return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
226 && static_cast<GPRReg
>(m_payload
) == InvalidGPRReg
;
229 bool isAddress() const
232 return m_offset
!= notAddress();
235 int32_t offset() const
244 return static_cast<GPRReg
>(m_baseOrTag
);
247 GPRReg
tagGPR() const
249 ASSERT(!isAddress() && static_cast<GPRReg
>(m_baseOrTag
) != InvalidGPRReg
);
250 return static_cast<GPRReg
>(m_baseOrTag
);
253 GPRReg
payloadGPR() const
255 ASSERT(!isAddress());
256 return static_cast<GPRReg
>(m_payload
);
259 bool hasKnownTag() const
262 ASSERT(!isAddress());
263 return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
;
268 return static_cast<int32_t>(m_tagType
);
271 MacroAssembler::Address
asAddress(unsigned additionalOffset
= 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset
); }
274 static inline int32_t notAddress() { return 0x80000000; }
279 int8_t m_tagType
; // Contains the low bits of the tag.
281 #endif // USE(JSVALUE32_64)
283 // The baseline JIT requires that regT3 be callee-preserved.
286 #define NUMBER_OF_ARGUMENT_REGISTERS 0u
290 typedef GPRReg RegisterType
;
291 static const unsigned numberOfRegisters
= 6;
292 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
294 // Note: regT3 is required to be callee-preserved.
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
;
317 static GPRReg
toRegister(unsigned index
)
319 ASSERT(index
< numberOfRegisters
);
320 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
};
321 return registerForIndex
[index
];
324 static unsigned toIndex(GPRReg reg
)
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
];
333 static const char* debugName(GPRReg reg
)
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",
341 return nameForRegister
[reg
];
344 static const unsigned InvalidIndex
= 0xffffffff;
351 #define NUMBER_OF_ARGUMENT_REGISTERS 6u
353 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
358 typedef GPRReg RegisterType
;
359 static const unsigned numberOfRegisters
= 11;
360 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
362 // Note: regT3 is required to be callee-preserved.
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.
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
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
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
;
403 static GPRReg
toRegister(unsigned index
)
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
];
410 static GPRReg
toArgumentRegister(unsigned index
)
412 ASSERT(index
< numberOfArgumentRegisters
);
414 static const GPRReg registerForIndex
[numberOfArgumentRegisters
] = { argumentGPR0
, argumentGPR1
, argumentGPR2
, argumentGPR3
, argumentGPR4
, argumentGPR5
};
416 static const GPRReg registerForIndex
[numberOfArgumentRegisters
] = { argumentGPR0
, argumentGPR1
, argumentGPR2
, argumentGPR3
};
418 return registerForIndex
[index
];
421 static unsigned toIndex(GPRReg reg
)
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
];
429 static const char* debugName(GPRReg reg
)
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"
439 return nameForRegister
[reg
];
442 static const unsigned InvalidIndex
= 0xffffffff;
445 #endif // CPU(X86_64)
448 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
452 typedef GPRReg RegisterType
;
453 static const unsigned numberOfRegisters
= 9;
454 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
456 // Note: regT3 is required to be callee-preserved.
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
;
467 static const GPRReg regT7
= ARMRegisters::r11
;
469 static const GPRReg regT7
= ARMRegisters::r7
;
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
488 static GPRReg
toRegister(unsigned index
)
490 ASSERT(index
< numberOfRegisters
);
491 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
, regT8
};
492 return registerForIndex
[index
];
495 static unsigned toIndex(GPRReg reg
)
497 ASSERT(reg
!= InvalidGPRReg
);
498 ASSERT(static_cast<int>(reg
) < 16);
499 static const unsigned indexForRegister
[16] =
501 { 0, 1, 2, 8, 3, 9, InvalidIndex
, InvalidIndex
, 4, 5, 6, 7, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
503 { 0, 1, 2, 8, 3, 9, InvalidIndex
, 7, 4, 5, 6, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
505 unsigned result
= indexForRegister
[reg
];
509 static const char* debugName(GPRReg reg
)
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"
519 return nameForRegister
[reg
];
522 static const unsigned InvalidIndex
= 0xffffffff;
528 #define NUMBER_OF_ARGUMENT_REGISTERS 8u
532 typedef GPRReg RegisterType
;
533 static const unsigned numberOfRegisters
= 16;
534 static const unsigned numberOfArgumentRegisters
= 8;
536 // Note: regT3 is required to be callee-preserved.
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
;
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
)
598 return (GPRReg
)index
;
600 static unsigned toIndex(GPRReg reg
)
604 return (unsigned)reg
;
607 static GPRReg
toArgumentRegister(unsigned index
)
609 ASSERT(index
< numberOfArgumentRegisters
);
610 return toRegister(index
);
613 static const char* debugName(GPRReg reg
)
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"
623 return nameForRegister
[reg
];
626 static const unsigned InvalidIndex
= 0xffffffff;
632 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
636 typedef GPRReg RegisterType
;
637 static const unsigned numberOfRegisters
= 7;
638 static const unsigned numberOfArgumentRegisters
= NUMBER_OF_ARGUMENT_REGISTERS
;
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.
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
;
668 static GPRReg
toRegister(unsigned index
)
670 ASSERT(index
< numberOfRegisters
);
671 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
};
672 return registerForIndex
[index
];
675 static unsigned toIndex(GPRReg reg
)
677 ASSERT(reg
!= InvalidGPRReg
);
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
684 unsigned result
= indexForRegister
[reg
];
688 static const char* debugName(GPRReg reg
)
690 ASSERT(reg
!= InvalidGPRReg
);
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"
698 return nameForRegister
[reg
];
701 static const unsigned InvalidIndex
= 0xffffffff;
707 #define NUMBER_OF_ARGUMENT_REGISTERS 4u
711 typedef GPRReg RegisterType
;
712 static const unsigned numberOfRegisters
= 10;
714 // Note: regT3 is required to be callee-preserved.
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
;
743 static GPRReg
toRegister(unsigned index
)
745 ASSERT(index
< numberOfRegisters
);
746 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
, regT8
, regT9
};
747 return registerForIndex
[index
];
750 static unsigned toIndex(GPRReg reg
)
752 ASSERT(reg
!= InvalidGPRReg
);
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
];
759 static const char* debugName(GPRReg reg
)
761 ASSERT(reg
!= InvalidGPRReg
);
763 static const char* nameForRegister
[16] = {
764 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
765 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
767 return nameForRegister
[reg
];
770 static const unsigned InvalidIndex
= 0xffffffff;
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
);
783 #endif // ENABLE(JIT)
789 inline void printInternal(PrintStream
& out
, JSC::GPRReg reg
)
792 out
.print("%", JSC::GPRInfo::debugName(reg
));
794 out
.printf("%%r%d", reg
);