2 * Copyright (C) 2011 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.
31 #include <assembler/MacroAssembler.h>
32 #include <dfg/DFGRegisterBank.h>
34 namespace JSC
{ namespace DFG
{
36 typedef MacroAssembler::RegisterID GPRReg
;
37 #define InvalidGPRReg ((GPRReg)-1)
43 : m_gpr(InvalidGPRReg
)
47 explicit JSValueRegs(GPRReg gpr
)
52 bool operator!() const { return m_gpr
== InvalidGPRReg
; }
54 GPRReg
gpr() const { return m_gpr
; }
63 : m_offset(notAddress())
64 , m_base(InvalidGPRReg
)
68 JSValueSource(JSValueRegs regs
)
69 : m_offset(notAddress())
74 explicit JSValueSource(GPRReg gpr
)
75 : m_offset(notAddress())
80 JSValueSource(MacroAssembler::Address address
)
81 : m_offset(address
.offset
)
82 , m_base(address
.base
)
84 ASSERT(m_offset
!= notAddress());
85 ASSERT(m_base
!= InvalidGPRReg
);
88 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
90 return JSValueSource(payloadGPR
);
93 bool operator!() const { return m_base
== InvalidGPRReg
; }
95 bool isAddress() const { return m_offset
!= notAddress(); }
97 int32_t offset() const
111 ASSERT(!isAddress());
115 MacroAssembler::Address
asAddress() const { return MacroAssembler::Address(base(), offset()); }
118 static inline int32_t notAddress() { return 0x80000000; }
125 #if USE(JSVALUE32_64)
129 : m_tagGPR(static_cast<int8_t>(InvalidGPRReg
))
130 , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg
))
134 JSValueRegs(GPRReg tagGPR
, GPRReg payloadGPR
)
136 , m_payloadGPR(payloadGPR
)
138 ASSERT((static_cast<GPRReg
>(m_tagGPR
) == InvalidGPRReg
) == (static_cast<GPRReg
>(payloadGPR
) == InvalidGPRReg
));
141 bool operator!() const { return static_cast<GPRReg
>(m_tagGPR
) == InvalidGPRReg
; }
143 GPRReg
tagGPR() const { return static_cast<GPRReg
>(m_tagGPR
); }
144 GPRReg
payloadGPR() const { return static_cast<GPRReg
>(m_payloadGPR
); }
151 class JSValueSource
{
154 : m_offset(notAddress())
155 , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg
))
156 , m_payload(static_cast<int8_t>(InvalidGPRReg
))
161 JSValueSource(JSValueRegs regs
)
162 : m_offset(notAddress())
163 , m_baseOrTag(regs
.tagGPR())
164 , m_payload(regs
.payloadGPR())
169 JSValueSource(GPRReg tagGPR
, GPRReg payloadGPR
)
170 : m_offset(notAddress())
171 , m_baseOrTag(static_cast<int8_t>(tagGPR
))
172 , m_payload(static_cast<int8_t>(payloadGPR
))
177 JSValueSource(MacroAssembler::Address address
)
178 : m_offset(address
.offset
)
179 , m_baseOrTag(static_cast<int8_t>(address
.base
))
180 , m_payload(static_cast<int8_t>(InvalidGPRReg
))
183 ASSERT(m_offset
!= notAddress());
184 ASSERT(static_cast<GPRReg
>(m_baseOrTag
) != InvalidGPRReg
);
187 static JSValueSource
unboxedCell(GPRReg payloadGPR
)
189 JSValueSource result
;
190 result
.m_offset
= notAddress();
191 result
.m_baseOrTag
= static_cast<int8_t>(InvalidGPRReg
);
192 result
.m_payload
= static_cast<int8_t>(payloadGPR
);
193 result
.m_tagType
= static_cast<int8_t>(JSValue::CellTag
);
197 bool operator!() const { return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
&& static_cast<GPRReg
>(m_payload
) == InvalidGPRReg
; }
199 bool isAddress() const
202 return m_offset
!= notAddress();
205 int32_t offset() const
214 return static_cast<GPRReg
>(m_baseOrTag
);
217 GPRReg
tagGPR() const
219 ASSERT(!isAddress() && m_baseOrTag
!= InvalidGPRReg
);
220 return static_cast<GPRReg
>(m_baseOrTag
);
223 GPRReg
payloadGPR() const
225 ASSERT(!isAddress());
226 return static_cast<GPRReg
>(m_payload
);
229 bool hasKnownTag() const
232 ASSERT(!isAddress());
233 return static_cast<GPRReg
>(m_baseOrTag
) == InvalidGPRReg
;
238 return static_cast<int32_t>(m_tagType
);
241 MacroAssembler::Address
asAddress(unsigned additionalOffset
= 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset
); }
244 static inline int32_t notAddress() { return 0x80000000; }
249 int8_t m_tagType
; // Contains the low bits of the tag.
254 #define NUMBER_OF_ARGUMENT_REGISTERS 0
258 typedef GPRReg RegisterType
;
259 static const unsigned numberOfRegisters
= 5;
261 // Temporary registers.
262 static const GPRReg regT0
= X86Registers::eax
;
263 static const GPRReg regT1
= X86Registers::edx
;
264 static const GPRReg regT2
= X86Registers::ecx
;
265 static const GPRReg regT3
= X86Registers::ebx
;
266 static const GPRReg regT4
= X86Registers::esi
;
267 // These registers match the baseline JIT.
268 static const GPRReg cachedResultRegister
= regT0
;
269 static const GPRReg cachedResultRegister2
= regT1
;
270 static const GPRReg callFrameRegister
= X86Registers::edi
;
271 // These constants provide the names for the general purpose argument & return value registers.
272 static const GPRReg argumentGPR0
= X86Registers::ecx
; // regT2
273 static const GPRReg argumentGPR1
= X86Registers::edx
; // regT1
274 static const GPRReg returnValueGPR
= X86Registers::eax
; // regT0
275 static const GPRReg returnValueGPR2
= X86Registers::edx
; // regT1
276 static const GPRReg nonPreservedNonReturnGPR
= X86Registers::ecx
;
278 static GPRReg
toRegister(unsigned index
)
280 ASSERT(index
< numberOfRegisters
);
281 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
};
282 return registerForIndex
[index
];
285 static unsigned toIndex(GPRReg reg
)
287 ASSERT(reg
!= InvalidGPRReg
);
289 static const unsigned indexForRegister
[8] = { 0, 2, 1, 3, InvalidIndex
, InvalidIndex
, 4, InvalidIndex
};
290 unsigned result
= indexForRegister
[reg
];
291 ASSERT(result
!= InvalidIndex
);
295 static const char* debugName(GPRReg reg
)
297 ASSERT(reg
!= InvalidGPRReg
);
299 static const char* nameForRegister
[8] = {
300 "eax", "ecx", "edx", "ebx",
301 "esp", "ebp", "esi", "edi",
303 return nameForRegister
[reg
];
307 static const unsigned InvalidIndex
= 0xffffffff;
313 #define NUMBER_OF_ARGUMENT_REGISTERS 6
317 typedef GPRReg RegisterType
;
318 static const unsigned numberOfRegisters
= 9;
320 // These registers match the baseline JIT.
321 static const GPRReg cachedResultRegister
= X86Registers::eax
;
322 static const GPRReg timeoutCheckRegister
= X86Registers::r12
;
323 static const GPRReg callFrameRegister
= X86Registers::r13
;
324 static const GPRReg tagTypeNumberRegister
= X86Registers::r14
;
325 static const GPRReg tagMaskRegister
= X86Registers::r15
;
326 // Temporary registers.
327 static const GPRReg regT0
= X86Registers::eax
;
328 static const GPRReg regT1
= X86Registers::edx
;
329 static const GPRReg regT2
= X86Registers::ecx
;
330 static const GPRReg regT3
= X86Registers::ebx
;
331 static const GPRReg regT4
= X86Registers::edi
;
332 static const GPRReg regT5
= X86Registers::esi
;
333 static const GPRReg regT6
= X86Registers::r8
;
334 static const GPRReg regT7
= X86Registers::r9
;
335 static const GPRReg regT8
= X86Registers::r10
;
336 // These constants provide the names for the general purpose argument & return value registers.
337 static const GPRReg argumentGPR0
= X86Registers::edi
; // regT4
338 static const GPRReg argumentGPR1
= X86Registers::esi
; // regT5
339 static const GPRReg argumentGPR2
= X86Registers::edx
; // regT1
340 static const GPRReg argumentGPR3
= X86Registers::ecx
; // regT2
341 static const GPRReg argumentGPR4
= X86Registers::r8
; // regT6
342 static const GPRReg argumentGPR5
= X86Registers::r9
; // regT7
343 static const GPRReg returnValueGPR
= X86Registers::eax
; // regT0
344 static const GPRReg returnValueGPR2
= X86Registers::edx
; // regT1
345 static const GPRReg nonPreservedNonReturnGPR
= X86Registers::esi
;
347 static GPRReg
toRegister(unsigned index
)
349 ASSERT(index
< numberOfRegisters
);
350 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
, regT8
};
351 return registerForIndex
[index
];
354 static unsigned toIndex(GPRReg reg
)
356 ASSERT(reg
!= InvalidGPRReg
);
358 static const unsigned indexForRegister
[16] = { 0, 2, 1, 3, InvalidIndex
, InvalidIndex
, 5, 4, 6, 7, 8, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
359 unsigned result
= indexForRegister
[reg
];
360 ASSERT(result
!= InvalidIndex
);
364 static const char* debugName(GPRReg reg
)
366 ASSERT(reg
!= InvalidGPRReg
);
368 static const char* nameForRegister
[16] = {
369 "rax", "rcx", "rdx", "rbx",
370 "rsp", "rbp", "rsi", "rdi",
371 "r8", "r9", "r10", "r11",
372 "r12", "r13", "r14", "r15"
374 return nameForRegister
[reg
];
378 static const unsigned InvalidIndex
= 0xffffffff;
384 #define NUMBER_OF_ARGUMENT_REGISTERS 4
388 typedef GPRReg RegisterType
;
389 static const unsigned numberOfRegisters
= 8;
391 // Temporary registers.
392 static const GPRReg regT0
= ARMRegisters::r0
;
393 static const GPRReg regT1
= ARMRegisters::r1
;
394 static const GPRReg regT2
= ARMRegisters::r2
;
395 static const GPRReg regT3
= ARMRegisters::r4
;
396 static const GPRReg regT4
= ARMRegisters::r8
;
397 static const GPRReg regT5
= ARMRegisters::r9
;
398 static const GPRReg regT6
= ARMRegisters::r10
;
399 static const GPRReg regT7
= ARMRegisters::r11
;
400 // These registers match the baseline JIT.
401 static const GPRReg cachedResultRegister
= regT0
;
402 static const GPRReg cachedResultRegister2
= regT1
;
403 static const GPRReg callFrameRegister
= ARMRegisters::r5
;
404 // These constants provide the names for the general purpose argument & return value registers.
405 static const GPRReg argumentGPR0
= ARMRegisters::r0
; // regT0
406 static const GPRReg argumentGPR1
= ARMRegisters::r1
; // regT1
407 static const GPRReg argumentGPR2
= ARMRegisters::r2
; // regT2
408 // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems
409 // This could threoretically be a problem if theis is used in code generation
410 // between the arguments being set up, and the call being made. That said,
411 // any change introducing a problem here is likely to be immediately apparent!
412 static const GPRReg argumentGPR3
= ARMRegisters::r3
; // FIXME!
413 static const GPRReg returnValueGPR
= ARMRegisters::r0
; // regT0
414 static const GPRReg returnValueGPR2
= ARMRegisters::r1
; // regT1
415 static const GPRReg nonPreservedNonReturnGPR
= ARMRegisters::r2
;
417 static GPRReg
toRegister(unsigned index
)
419 ASSERT(index
< numberOfRegisters
);
420 static const GPRReg registerForIndex
[numberOfRegisters
] = { regT0
, regT1
, regT2
, regT3
, regT4
, regT5
, regT6
, regT7
};
421 return registerForIndex
[index
];
424 static unsigned toIndex(GPRReg reg
)
426 ASSERT(reg
!= InvalidGPRReg
);
428 static const unsigned indexForRegister
[16] = { 0, 1, 2, InvalidIndex
, 3, InvalidIndex
, InvalidIndex
, InvalidIndex
, 4, 5, 6, 7, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
};
429 unsigned result
= indexForRegister
[reg
];
430 ASSERT(result
!= InvalidIndex
);
434 static const char* debugName(GPRReg reg
)
436 ASSERT(reg
!= InvalidGPRReg
);
438 static const char* nameForRegister
[16] = {
439 "r0", "r1", "r2", "r3",
440 "r4", "r5", "r6", "r7",
441 "r8", "r9", "r10", "r11",
442 "r12", "r13", "r14", "r15"
444 return nameForRegister
[reg
];
448 static const unsigned InvalidIndex
= 0xffffffff;
453 typedef RegisterBank
<GPRInfo
>::iterator gpr_iterator
;
455 } } // namespace JSC::DFG