]>
Commit | Line | Data |
---|---|---|
14957cd0 A |
1 | /* |
2 | * Copyright (C) 2011 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 DFGGPRInfo_h | |
27 | #define DFGGPRInfo_h | |
28 | ||
93a37866 A |
29 | #include <wtf/Platform.h> |
30 | ||
14957cd0 A |
31 | #if ENABLE(DFG_JIT) |
32 | ||
93a37866 A |
33 | #include "DFGRegisterBank.h" |
34 | #include "MacroAssembler.h" | |
14957cd0 A |
35 | |
36 | namespace JSC { namespace DFG { | |
37 | ||
38 | typedef MacroAssembler::RegisterID GPRReg; | |
39 | #define InvalidGPRReg ((GPRReg)-1) | |
40 | ||
6fe7ccc8 A |
41 | #if USE(JSVALUE64) |
42 | class JSValueRegs { | |
43 | public: | |
44 | JSValueRegs() | |
45 | : m_gpr(InvalidGPRReg) | |
46 | { | |
47 | } | |
48 | ||
49 | explicit JSValueRegs(GPRReg gpr) | |
50 | : m_gpr(gpr) | |
51 | { | |
52 | } | |
53 | ||
54 | bool operator!() const { return m_gpr == InvalidGPRReg; } | |
55 | ||
56 | GPRReg gpr() const { return m_gpr; } | |
57 | ||
58 | private: | |
59 | GPRReg m_gpr; | |
60 | }; | |
61 | ||
62 | class JSValueSource { | |
63 | public: | |
64 | JSValueSource() | |
65 | : m_offset(notAddress()) | |
66 | , m_base(InvalidGPRReg) | |
67 | { | |
68 | } | |
69 | ||
70 | JSValueSource(JSValueRegs regs) | |
71 | : m_offset(notAddress()) | |
72 | , m_base(regs.gpr()) | |
73 | { | |
74 | } | |
75 | ||
76 | explicit JSValueSource(GPRReg gpr) | |
77 | : m_offset(notAddress()) | |
78 | , m_base(gpr) | |
79 | { | |
80 | } | |
81 | ||
82 | JSValueSource(MacroAssembler::Address address) | |
83 | : m_offset(address.offset) | |
84 | , m_base(address.base) | |
85 | { | |
86 | ASSERT(m_offset != notAddress()); | |
87 | ASSERT(m_base != InvalidGPRReg); | |
88 | } | |
89 | ||
90 | static JSValueSource unboxedCell(GPRReg payloadGPR) | |
91 | { | |
92 | return JSValueSource(payloadGPR); | |
93 | } | |
94 | ||
95 | bool operator!() const { return m_base == InvalidGPRReg; } | |
96 | ||
97 | bool isAddress() const { return m_offset != notAddress(); } | |
98 | ||
99 | int32_t offset() const | |
100 | { | |
101 | ASSERT(isAddress()); | |
102 | return m_offset; | |
103 | } | |
104 | ||
105 | GPRReg base() const | |
106 | { | |
107 | ASSERT(isAddress()); | |
108 | return m_base; | |
109 | } | |
110 | ||
111 | GPRReg gpr() const | |
112 | { | |
113 | ASSERT(!isAddress()); | |
114 | return m_base; | |
115 | } | |
116 | ||
117 | MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); } | |
118 | ||
119 | private: | |
120 | static inline int32_t notAddress() { return 0x80000000; } | |
121 | ||
122 | int32_t m_offset; | |
123 | GPRReg m_base; | |
124 | }; | |
125 | #endif | |
126 | ||
127 | #if USE(JSVALUE32_64) | |
128 | class JSValueRegs { | |
129 | public: | |
130 | JSValueRegs() | |
131 | : m_tagGPR(static_cast<int8_t>(InvalidGPRReg)) | |
132 | , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg)) | |
133 | { | |
134 | } | |
135 | ||
136 | JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR) | |
137 | : m_tagGPR(tagGPR) | |
138 | , m_payloadGPR(payloadGPR) | |
139 | { | |
140 | ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg)); | |
141 | } | |
142 | ||
143 | bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; } | |
144 | ||
145 | GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); } | |
146 | GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); } | |
147 | ||
148 | private: | |
149 | int8_t m_tagGPR; | |
150 | int8_t m_payloadGPR; | |
151 | }; | |
152 | ||
153 | class JSValueSource { | |
154 | public: | |
155 | JSValueSource() | |
156 | : m_offset(notAddress()) | |
157 | , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg)) | |
158 | , m_payload(static_cast<int8_t>(InvalidGPRReg)) | |
159 | , m_tagType(0) | |
160 | { | |
161 | } | |
162 | ||
163 | JSValueSource(JSValueRegs regs) | |
164 | : m_offset(notAddress()) | |
165 | , m_baseOrTag(regs.tagGPR()) | |
166 | , m_payload(regs.payloadGPR()) | |
167 | , m_tagType(0) | |
168 | { | |
169 | } | |
170 | ||
171 | JSValueSource(GPRReg tagGPR, GPRReg payloadGPR) | |
172 | : m_offset(notAddress()) | |
173 | , m_baseOrTag(static_cast<int8_t>(tagGPR)) | |
174 | , m_payload(static_cast<int8_t>(payloadGPR)) | |
175 | , m_tagType(0) | |
176 | { | |
177 | } | |
178 | ||
179 | JSValueSource(MacroAssembler::Address address) | |
180 | : m_offset(address.offset) | |
181 | , m_baseOrTag(static_cast<int8_t>(address.base)) | |
182 | , m_payload(static_cast<int8_t>(InvalidGPRReg)) | |
183 | , m_tagType(0) | |
184 | { | |
185 | ASSERT(m_offset != notAddress()); | |
186 | ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg); | |
187 | } | |
188 | ||
189 | static JSValueSource unboxedCell(GPRReg payloadGPR) | |
190 | { | |
191 | JSValueSource result; | |
192 | result.m_offset = notAddress(); | |
193 | result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg); | |
194 | result.m_payload = static_cast<int8_t>(payloadGPR); | |
195 | result.m_tagType = static_cast<int8_t>(JSValue::CellTag); | |
196 | return result; | |
197 | } | |
198 | ||
199 | bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; } | |
200 | ||
201 | bool isAddress() const | |
202 | { | |
203 | ASSERT(!!*this); | |
204 | return m_offset != notAddress(); | |
205 | } | |
206 | ||
207 | int32_t offset() const | |
208 | { | |
209 | ASSERT(isAddress()); | |
210 | return m_offset; | |
211 | } | |
212 | ||
213 | GPRReg base() const | |
214 | { | |
215 | ASSERT(isAddress()); | |
216 | return static_cast<GPRReg>(m_baseOrTag); | |
217 | } | |
218 | ||
219 | GPRReg tagGPR() const | |
220 | { | |
93a37866 | 221 | ASSERT(!isAddress() && static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg); |
6fe7ccc8 A |
222 | return static_cast<GPRReg>(m_baseOrTag); |
223 | } | |
224 | ||
225 | GPRReg payloadGPR() const | |
226 | { | |
227 | ASSERT(!isAddress()); | |
228 | return static_cast<GPRReg>(m_payload); | |
229 | } | |
230 | ||
231 | bool hasKnownTag() const | |
232 | { | |
233 | ASSERT(!!*this); | |
234 | ASSERT(!isAddress()); | |
235 | return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg; | |
236 | } | |
237 | ||
238 | uint32_t tag() const | |
239 | { | |
240 | return static_cast<int32_t>(m_tagType); | |
241 | } | |
242 | ||
243 | MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); } | |
244 | ||
245 | private: | |
246 | static inline int32_t notAddress() { return 0x80000000; } | |
247 | ||
248 | int32_t m_offset; | |
249 | int8_t m_baseOrTag; | |
250 | int8_t m_payload; | |
251 | int8_t m_tagType; // Contains the low bits of the tag. | |
252 | }; | |
253 | #endif | |
254 | ||
255 | #if CPU(X86) | |
256 | #define NUMBER_OF_ARGUMENT_REGISTERS 0 | |
257 | ||
258 | class GPRInfo { | |
259 | public: | |
260 | typedef GPRReg RegisterType; | |
261 | static const unsigned numberOfRegisters = 5; | |
262 | ||
263 | // Temporary registers. | |
264 | static const GPRReg regT0 = X86Registers::eax; | |
265 | static const GPRReg regT1 = X86Registers::edx; | |
266 | static const GPRReg regT2 = X86Registers::ecx; | |
267 | static const GPRReg regT3 = X86Registers::ebx; | |
268 | static const GPRReg regT4 = X86Registers::esi; | |
269 | // These registers match the baseline JIT. | |
270 | static const GPRReg cachedResultRegister = regT0; | |
271 | static const GPRReg cachedResultRegister2 = regT1; | |
272 | static const GPRReg callFrameRegister = X86Registers::edi; | |
273 | // These constants provide the names for the general purpose argument & return value registers. | |
274 | static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2 | |
275 | static const GPRReg argumentGPR1 = X86Registers::edx; // regT1 | |
93a37866 A |
276 | static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0 |
277 | static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3 | |
278 | static const GPRReg nonArgGPR2 = X86Registers::esi; // regT4 | |
6fe7ccc8 A |
279 | static const GPRReg returnValueGPR = X86Registers::eax; // regT0 |
280 | static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 | |
281 | static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx; | |
282 | ||
283 | static GPRReg toRegister(unsigned index) | |
284 | { | |
285 | ASSERT(index < numberOfRegisters); | |
286 | static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4 }; | |
287 | return registerForIndex[index]; | |
288 | } | |
289 | ||
290 | static unsigned toIndex(GPRReg reg) | |
291 | { | |
292 | ASSERT(reg != InvalidGPRReg); | |
93a37866 | 293 | ASSERT(static_cast<int>(reg) < 8); |
6fe7ccc8 A |
294 | static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, InvalidIndex }; |
295 | unsigned result = indexForRegister[reg]; | |
296 | ASSERT(result != InvalidIndex); | |
297 | return result; | |
298 | } | |
299 | ||
300 | static const char* debugName(GPRReg reg) | |
301 | { | |
302 | ASSERT(reg != InvalidGPRReg); | |
93a37866 | 303 | ASSERT(static_cast<int>(reg) < 8); |
6fe7ccc8 A |
304 | static const char* nameForRegister[8] = { |
305 | "eax", "ecx", "edx", "ebx", | |
306 | "esp", "ebp", "esi", "edi", | |
307 | }; | |
308 | return nameForRegister[reg]; | |
309 | } | |
310 | private: | |
311 | ||
312 | static const unsigned InvalidIndex = 0xffffffff; | |
313 | }; | |
314 | ||
315 | #endif | |
316 | ||
317 | #if CPU(X86_64) | |
318 | #define NUMBER_OF_ARGUMENT_REGISTERS 6 | |
319 | ||
14957cd0 A |
320 | class GPRInfo { |
321 | public: | |
322 | typedef GPRReg RegisterType; | |
323 | static const unsigned numberOfRegisters = 9; | |
324 | ||
6fe7ccc8 A |
325 | // These registers match the baseline JIT. |
326 | static const GPRReg cachedResultRegister = X86Registers::eax; | |
14957cd0 A |
327 | static const GPRReg callFrameRegister = X86Registers::r13; |
328 | static const GPRReg tagTypeNumberRegister = X86Registers::r14; | |
329 | static const GPRReg tagMaskRegister = X86Registers::r15; | |
330 | // Temporary registers. | |
331 | static const GPRReg regT0 = X86Registers::eax; | |
332 | static const GPRReg regT1 = X86Registers::edx; | |
333 | static const GPRReg regT2 = X86Registers::ecx; | |
334 | static const GPRReg regT3 = X86Registers::ebx; | |
335 | static const GPRReg regT4 = X86Registers::edi; | |
336 | static const GPRReg regT5 = X86Registers::esi; | |
337 | static const GPRReg regT6 = X86Registers::r8; | |
338 | static const GPRReg regT7 = X86Registers::r9; | |
339 | static const GPRReg regT8 = X86Registers::r10; | |
340 | // These constants provide the names for the general purpose argument & return value registers. | |
341 | static const GPRReg argumentGPR0 = X86Registers::edi; // regT4 | |
342 | static const GPRReg argumentGPR1 = X86Registers::esi; // regT5 | |
343 | static const GPRReg argumentGPR2 = X86Registers::edx; // regT1 | |
344 | static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2 | |
6fe7ccc8 A |
345 | static const GPRReg argumentGPR4 = X86Registers::r8; // regT6 |
346 | static const GPRReg argumentGPR5 = X86Registers::r9; // regT7 | |
93a37866 A |
347 | static const GPRReg nonArgGPR0 = X86Registers::eax; // regT0 |
348 | static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3 | |
349 | static const GPRReg nonArgGPR2 = X86Registers::r10; // regT8 | |
14957cd0 A |
350 | static const GPRReg returnValueGPR = X86Registers::eax; // regT0 |
351 | static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 | |
6fe7ccc8 | 352 | static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi; |
14957cd0 A |
353 | |
354 | static GPRReg toRegister(unsigned index) | |
355 | { | |
356 | ASSERT(index < numberOfRegisters); | |
357 | static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8 }; | |
358 | return registerForIndex[index]; | |
359 | } | |
360 | ||
361 | static unsigned toIndex(GPRReg reg) | |
362 | { | |
363 | ASSERT(reg != InvalidGPRReg); | |
93a37866 | 364 | ASSERT(static_cast<int>(reg) < 16); |
14957cd0 A |
365 | static const unsigned indexForRegister[16] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4, 6, 7, 8, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex }; |
366 | unsigned result = indexForRegister[reg]; | |
367 | ASSERT(result != InvalidIndex); | |
368 | return result; | |
369 | } | |
370 | ||
14957cd0 A |
371 | static const char* debugName(GPRReg reg) |
372 | { | |
373 | ASSERT(reg != InvalidGPRReg); | |
93a37866 | 374 | ASSERT(static_cast<int>(reg) < 16); |
14957cd0 A |
375 | static const char* nameForRegister[16] = { |
376 | "rax", "rcx", "rdx", "rbx", | |
377 | "rsp", "rbp", "rsi", "rdi", | |
378 | "r8", "r9", "r10", "r11", | |
379 | "r12", "r13", "r14", "r15" | |
380 | }; | |
381 | return nameForRegister[reg]; | |
382 | } | |
6fe7ccc8 A |
383 | private: |
384 | ||
385 | static const unsigned InvalidIndex = 0xffffffff; | |
386 | }; | |
387 | ||
14957cd0 | 388 | #endif |
6fe7ccc8 | 389 | |
93a37866 | 390 | #if CPU(ARM) |
6fe7ccc8 A |
391 | #define NUMBER_OF_ARGUMENT_REGISTERS 4 |
392 | ||
393 | class GPRInfo { | |
394 | public: | |
395 | typedef GPRReg RegisterType; | |
396 | static const unsigned numberOfRegisters = 8; | |
397 | ||
398 | // Temporary registers. | |
399 | static const GPRReg regT0 = ARMRegisters::r0; | |
400 | static const GPRReg regT1 = ARMRegisters::r1; | |
401 | static const GPRReg regT2 = ARMRegisters::r2; | |
402 | static const GPRReg regT3 = ARMRegisters::r4; | |
403 | static const GPRReg regT4 = ARMRegisters::r8; | |
404 | static const GPRReg regT5 = ARMRegisters::r9; | |
405 | static const GPRReg regT6 = ARMRegisters::r10; | |
406 | static const GPRReg regT7 = ARMRegisters::r11; | |
407 | // These registers match the baseline JIT. | |
408 | static const GPRReg cachedResultRegister = regT0; | |
409 | static const GPRReg cachedResultRegister2 = regT1; | |
410 | static const GPRReg callFrameRegister = ARMRegisters::r5; | |
411 | // These constants provide the names for the general purpose argument & return value registers. | |
412 | static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0 | |
413 | static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1 | |
414 | static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2 | |
415 | // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems | |
93a37866 | 416 | // This could threoretically be a problem if this is used in code generation |
6fe7ccc8 A |
417 | // between the arguments being set up, and the call being made. That said, |
418 | // any change introducing a problem here is likely to be immediately apparent! | |
419 | static const GPRReg argumentGPR3 = ARMRegisters::r3; // FIXME! | |
93a37866 A |
420 | static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT3 |
421 | static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4 | |
422 | static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5 | |
6fe7ccc8 A |
423 | static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0 |
424 | static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1 | |
425 | static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2; | |
426 | ||
427 | static GPRReg toRegister(unsigned index) | |
428 | { | |
429 | ASSERT(index < numberOfRegisters); | |
430 | static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 }; | |
431 | return registerForIndex[index]; | |
432 | } | |
433 | ||
434 | static unsigned toIndex(GPRReg reg) | |
435 | { | |
93a37866 A |
436 | ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg); |
437 | ASSERT(static_cast<unsigned>(reg) < 16); | |
6fe7ccc8 A |
438 | static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex }; |
439 | unsigned result = indexForRegister[reg]; | |
440 | ASSERT(result != InvalidIndex); | |
441 | return result; | |
442 | } | |
443 | ||
444 | static const char* debugName(GPRReg reg) | |
445 | { | |
93a37866 A |
446 | ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg); |
447 | ASSERT(static_cast<unsigned>(reg) < 16); | |
6fe7ccc8 A |
448 | static const char* nameForRegister[16] = { |
449 | "r0", "r1", "r2", "r3", | |
450 | "r4", "r5", "r6", "r7", | |
451 | "r8", "r9", "r10", "r11", | |
452 | "r12", "r13", "r14", "r15" | |
453 | }; | |
454 | return nameForRegister[reg]; | |
455 | } | |
14957cd0 A |
456 | private: |
457 | ||
458 | static const unsigned InvalidIndex = 0xffffffff; | |
459 | }; | |
460 | ||
6fe7ccc8 A |
461 | #endif |
462 | ||
93a37866 A |
463 | #if CPU(ARM64) |
464 | #define NUMBER_OF_ARGUMENT_REGISTERS 8 | |
465 | ||
466 | class GPRInfo { | |
467 | public: | |
468 | typedef GPRReg RegisterType; | |
469 | static const unsigned numberOfRegisters = 16; | |
470 | ||
471 | // These registers match the baseline JIT. | |
472 | static const GPRReg cachedResultRegister = ARM64Registers::x0; | |
473 | static const GPRReg timeoutCheckRegister = ARM64Registers::x26; | |
474 | static const GPRReg callFrameRegister = ARM64Registers::x25; | |
475 | static const GPRReg tagTypeNumberRegister = ARM64Registers::x27; | |
476 | static const GPRReg tagMaskRegister = ARM64Registers::x28; | |
477 | // Temporary registers. | |
478 | static const GPRReg regT0 = ARM64Registers::x0; | |
479 | static const GPRReg regT1 = ARM64Registers::x1; | |
480 | static const GPRReg regT2 = ARM64Registers::x2; | |
481 | static const GPRReg regT3 = ARM64Registers::x3; | |
482 | static const GPRReg regT4 = ARM64Registers::x4; | |
483 | static const GPRReg regT5 = ARM64Registers::x5; | |
484 | static const GPRReg regT6 = ARM64Registers::x6; | |
485 | static const GPRReg regT7 = ARM64Registers::x7; | |
486 | static const GPRReg regT8 = ARM64Registers::x8; | |
487 | static const GPRReg regT9 = ARM64Registers::x9; | |
488 | static const GPRReg regT10 = ARM64Registers::x10; | |
489 | static const GPRReg regT11 = ARM64Registers::x11; | |
490 | static const GPRReg regT12 = ARM64Registers::x12; | |
491 | static const GPRReg regT13 = ARM64Registers::x13; | |
492 | static const GPRReg regT14 = ARM64Registers::x14; | |
493 | static const GPRReg regT15 = ARM64Registers::x15; | |
494 | // These constants provide the names for the general purpose argument & return value registers. | |
495 | static const GPRReg argumentGPR0 = ARM64Registers::x0; // regT0 | |
496 | static const GPRReg argumentGPR1 = ARM64Registers::x1; // regT1 | |
497 | static const GPRReg argumentGPR2 = ARM64Registers::x2; // regT2 | |
498 | static const GPRReg argumentGPR3 = ARM64Registers::x3; // regT3 | |
499 | static const GPRReg argumentGPR4 = ARM64Registers::x4; // regT4 | |
500 | static const GPRReg argumentGPR5 = ARM64Registers::x5; // regT5 | |
501 | static const GPRReg argumentGPR6 = ARM64Registers::x6; // regT6 | |
502 | static const GPRReg argumentGPR7 = ARM64Registers::x7; // regT7 | |
503 | static const GPRReg nonArgGPR0 = ARM64Registers::x8; // regT8 | |
504 | static const GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9 | |
505 | static const GPRReg nonArgGPR2 = ARM64Registers::x10; // regT10 | |
506 | static const GPRReg returnValueGPR = ARM64Registers::x0; // regT0 | |
507 | static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1 | |
508 | static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2; | |
509 | ||
510 | // GPRReg mapping is direct, the machine regsiter numbers can | |
511 | // be used directly as indices into the GPR RegisterBank. | |
512 | COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0); | |
513 | COMPILE_ASSERT(ARM64Registers::q1 == 1, q1_is_1); | |
514 | COMPILE_ASSERT(ARM64Registers::q2 == 2, q2_is_2); | |
515 | COMPILE_ASSERT(ARM64Registers::q3 == 3, q3_is_3); | |
516 | COMPILE_ASSERT(ARM64Registers::q4 == 4, q4_is_4); | |
517 | COMPILE_ASSERT(ARM64Registers::q5 == 5, q5_is_5); | |
518 | COMPILE_ASSERT(ARM64Registers::q6 == 6, q6_is_6); | |
519 | COMPILE_ASSERT(ARM64Registers::q7 == 7, q7_is_7); | |
520 | COMPILE_ASSERT(ARM64Registers::q8 == 8, q8_is_8); | |
521 | COMPILE_ASSERT(ARM64Registers::q9 == 9, q9_is_9); | |
522 | COMPILE_ASSERT(ARM64Registers::q10 == 10, q10_is_10); | |
523 | COMPILE_ASSERT(ARM64Registers::q11 == 11, q11_is_11); | |
524 | COMPILE_ASSERT(ARM64Registers::q12 == 12, q12_is_12); | |
525 | COMPILE_ASSERT(ARM64Registers::q13 == 13, q13_is_13); | |
526 | COMPILE_ASSERT(ARM64Registers::q14 == 14, q14_is_14); | |
527 | COMPILE_ASSERT(ARM64Registers::q15 == 15, q15_is_15); | |
528 | static GPRReg toRegister(unsigned index) | |
529 | { | |
530 | return (GPRReg)index; | |
531 | } | |
532 | static unsigned toIndex(GPRReg reg) | |
533 | { | |
534 | return (unsigned)reg; | |
535 | } | |
536 | ||
537 | static const char* debugName(GPRReg reg) | |
538 | { | |
539 | ASSERT(static_cast<unsigned>(reg) != InvalidGPRReg); | |
540 | ASSERT(static_cast<unsigned>(reg) < 32); | |
541 | static const char* nameForRegister[32] = { | |
542 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", | |
543 | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", | |
544 | "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", | |
545 | "r24", "r25", "r26", "r27", "r28", "fp", "lr", "sp" | |
546 | }; | |
547 | return nameForRegister[reg]; | |
548 | } | |
549 | private: | |
550 | ||
551 | static const unsigned InvalidIndex = 0xffffffff; | |
552 | }; | |
553 | ||
554 | #endif | |
555 | ||
556 | #if CPU(MIPS) | |
557 | #define NUMBER_OF_ARGUMENT_REGISTERS 4 | |
558 | ||
559 | class GPRInfo { | |
560 | public: | |
561 | typedef GPRReg RegisterType; | |
562 | static const unsigned numberOfRegisters = 6; | |
563 | ||
564 | // Temporary registers. | |
565 | static const GPRReg regT0 = MIPSRegisters::v0; | |
566 | static const GPRReg regT1 = MIPSRegisters::v1; | |
567 | static const GPRReg regT2 = MIPSRegisters::t4; | |
568 | static const GPRReg regT3 = MIPSRegisters::t5; | |
569 | static const GPRReg regT4 = MIPSRegisters::t6; | |
570 | static const GPRReg regT5 = MIPSRegisters::t7; | |
571 | // These registers match the baseline JIT. | |
572 | static const GPRReg cachedResultRegister = regT0; | |
573 | static const GPRReg cachedResultRegister2 = regT1; | |
574 | static const GPRReg callFrameRegister = MIPSRegisters::s0; | |
575 | // These constants provide the names for the general purpose argument & return value registers. | |
576 | static const GPRReg argumentGPR0 = MIPSRegisters::a0; | |
577 | static const GPRReg argumentGPR1 = MIPSRegisters::a1; | |
578 | static const GPRReg argumentGPR2 = MIPSRegisters::a2; | |
579 | static const GPRReg argumentGPR3 = MIPSRegisters::a3; | |
580 | static const GPRReg nonArgGPR0 = regT2; | |
581 | static const GPRReg nonArgGPR1 = regT3; | |
582 | static const GPRReg nonArgGPR2 = regT4; | |
583 | static const GPRReg returnValueGPR = regT0; | |
584 | static const GPRReg returnValueGPR2 = regT1; | |
585 | static const GPRReg nonPreservedNonReturnGPR = regT5; | |
586 | ||
587 | static GPRReg toRegister(unsigned index) | |
588 | { | |
589 | ASSERT(index < numberOfRegisters); | |
590 | static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 }; | |
591 | return registerForIndex[index]; | |
592 | } | |
593 | ||
594 | static unsigned toIndex(GPRReg reg) | |
595 | { | |
596 | ASSERT(reg != InvalidGPRReg); | |
597 | ASSERT(reg < 16); | |
598 | static const unsigned indexForRegister[16] = { InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, 2, 3, 4, 5 }; | |
599 | unsigned result = indexForRegister[reg]; | |
600 | ASSERT(result != InvalidIndex); | |
601 | return result; | |
602 | } | |
603 | ||
604 | static const char* debugName(GPRReg reg) | |
605 | { | |
606 | ASSERT(reg != InvalidGPRReg); | |
607 | ASSERT(reg < 16); | |
608 | static const char* nameForRegister[16] = { | |
609 | "zero", "at", "v0", "v1", | |
610 | "a0", "a1", "a2", "a3", | |
611 | "t0", "t1", "t2", "t3", | |
612 | "t4", "t5", "t6", "t7" | |
613 | }; | |
614 | return nameForRegister[reg]; | |
615 | } | |
616 | private: | |
617 | ||
618 | static const unsigned InvalidIndex = 0xffffffff; | |
619 | }; | |
620 | ||
621 | #endif | |
622 | ||
14957cd0 A |
623 | typedef RegisterBank<GPRInfo>::iterator gpr_iterator; |
624 | ||
625 | } } // namespace JSC::DFG | |
626 | ||
627 | #endif | |
628 | #endif |