]>
git.saurik.com Git - apple/javascriptcore.git/blob - jit/FPRInfo.h
2 * Copyright (C) 2011, 2013 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::FPRegisterID FPRReg
;
35 #define InvalidFPRReg ((::JSC::FPRReg)-1)
39 #if CPU(X86) || CPU(X86_64)
43 typedef FPRReg RegisterType
;
44 static const unsigned numberOfRegisters
= 6;
46 // Temporary registers.
47 static const FPRReg fpRegT0
= X86Registers::xmm0
;
48 static const FPRReg fpRegT1
= X86Registers::xmm1
;
49 static const FPRReg fpRegT2
= X86Registers::xmm2
;
50 static const FPRReg fpRegT3
= X86Registers::xmm3
;
51 static const FPRReg fpRegT4
= X86Registers::xmm4
;
52 static const FPRReg fpRegT5
= X86Registers::xmm5
;
54 // Only X86_64 passes aguments in xmm registers
55 static const FPRReg argumentFPR0
= X86Registers::xmm0
; // fpRegT0
56 static const FPRReg argumentFPR1
= X86Registers::xmm1
; // fpRegT1
57 static const FPRReg argumentFPR2
= X86Registers::xmm2
; // fpRegT2
58 static const FPRReg argumentFPR3
= X86Registers::xmm3
; // fpRegT3
60 // On X86 the return will actually be on the x87 stack,
61 // so we'll copy to xmm0 for sanity!
62 static const FPRReg returnValueFPR
= X86Registers::xmm0
; // fpRegT0
64 // FPRReg mapping is direct, the machine regsiter numbers can
65 // be used directly as indices into the FPR RegisterBank.
66 COMPILE_ASSERT(X86Registers::xmm0
== 0, xmm0_is_0
);
67 COMPILE_ASSERT(X86Registers::xmm1
== 1, xmm1_is_1
);
68 COMPILE_ASSERT(X86Registers::xmm2
== 2, xmm2_is_2
);
69 COMPILE_ASSERT(X86Registers::xmm3
== 3, xmm3_is_3
);
70 COMPILE_ASSERT(X86Registers::xmm4
== 4, xmm4_is_4
);
71 COMPILE_ASSERT(X86Registers::xmm5
== 5, xmm5_is_5
);
72 static FPRReg
toRegister(unsigned index
)
76 static unsigned toIndex(FPRReg reg
)
78 unsigned result
= (unsigned)reg
;
79 if (result
>= numberOfRegisters
)
84 static FPRReg
toArgumentRegister(unsigned index
)
89 static const char* debugName(FPRReg reg
)
91 ASSERT(reg
!= InvalidFPRReg
);
93 ASSERT(static_cast<int>(reg
) < 16);
94 static const char* nameForRegister
[16] = {
95 "xmm0", "xmm1", "xmm2", "xmm3",
96 "xmm4", "xmm5", "xmm6", "xmm7",
97 "xmm8", "xmm9", "xmm10", "xmm11",
98 "xmm12", "xmm13", "xmm14", "xmm15"
101 ASSERT(static_cast<int>(reg
) < 8);
102 static const char* nameForRegister
[8] = {
103 "xmm0", "xmm1", "xmm2", "xmm3",
104 "xmm4", "xmm5", "xmm6", "xmm7"
107 return nameForRegister
[reg
];
110 static const unsigned InvalidIndex
= 0xffffffff;
113 #endif // CPU(X86) || CPU(X86_64)
119 typedef FPRReg RegisterType
;
120 static const unsigned numberOfRegisters
= 6;
122 // Temporary registers.
123 // d7 is use by the MacroAssembler as fpTempRegister.
124 static const FPRReg fpRegT0
= ARMRegisters::d0
;
125 static const FPRReg fpRegT1
= ARMRegisters::d1
;
126 static const FPRReg fpRegT2
= ARMRegisters::d2
;
127 static const FPRReg fpRegT3
= ARMRegisters::d3
;
128 static const FPRReg fpRegT4
= ARMRegisters::d4
;
129 static const FPRReg fpRegT5
= ARMRegisters::d5
;
130 // ARMv7 doesn't pass arguments in fp registers. The return
131 // value is also actually in integer registers, for now
132 // we'll return in d0 for simplicity.
133 static const FPRReg returnValueFPR
= ARMRegisters::d0
; // fpRegT0
136 static const FPRReg argumentFPR0
= ARMRegisters::d0
; // fpRegT0
137 static const FPRReg argumentFPR1
= ARMRegisters::d1
; // fpRegT1
140 // FPRReg mapping is direct, the machine regsiter numbers can
141 // be used directly as indices into the FPR RegisterBank.
142 COMPILE_ASSERT(ARMRegisters::d0
== 0, d0_is_0
);
143 COMPILE_ASSERT(ARMRegisters::d1
== 1, d1_is_1
);
144 COMPILE_ASSERT(ARMRegisters::d2
== 2, d2_is_2
);
145 COMPILE_ASSERT(ARMRegisters::d3
== 3, d3_is_3
);
146 COMPILE_ASSERT(ARMRegisters::d4
== 4, d4_is_4
);
147 COMPILE_ASSERT(ARMRegisters::d5
== 5, d5_is_5
);
148 static FPRReg
toRegister(unsigned index
)
150 return (FPRReg
)index
;
152 static unsigned toIndex(FPRReg reg
)
154 return (unsigned)reg
;
157 static const char* debugName(FPRReg reg
)
159 ASSERT(reg
!= InvalidFPRReg
);
160 ASSERT(static_cast<int>(reg
) < 32);
161 static const char* nameForRegister
[32] = {
162 "d0", "d1", "d2", "d3",
163 "d4", "d5", "d6", "d7",
164 "d8", "d9", "d10", "d11",
165 "d12", "d13", "d14", "d15",
166 "d16", "d17", "d18", "d19",
167 "d20", "d21", "d22", "d23",
168 "d24", "d25", "d26", "d27",
169 "d28", "d29", "d30", "d31"
171 return nameForRegister
[reg
];
174 static const unsigned InvalidIndex
= 0xffffffff;
183 typedef FPRReg RegisterType
;
184 static const unsigned numberOfRegisters
= 23;
186 // Temporary registers.
187 // q8-q15 are callee saved, q31 is use by the MacroAssembler as fpTempRegister.
188 static const FPRReg fpRegT0
= ARM64Registers::q0
;
189 static const FPRReg fpRegT1
= ARM64Registers::q1
;
190 static const FPRReg fpRegT2
= ARM64Registers::q2
;
191 static const FPRReg fpRegT3
= ARM64Registers::q3
;
192 static const FPRReg fpRegT4
= ARM64Registers::q4
;
193 static const FPRReg fpRegT5
= ARM64Registers::q5
;
194 static const FPRReg fpRegT6
= ARM64Registers::q6
;
195 static const FPRReg fpRegT7
= ARM64Registers::q7
;
196 static const FPRReg fpRegT8
= ARM64Registers::q16
;
197 static const FPRReg fpRegT9
= ARM64Registers::q17
;
198 static const FPRReg fpRegT10
= ARM64Registers::q18
;
199 static const FPRReg fpRegT11
= ARM64Registers::q19
;
200 static const FPRReg fpRegT12
= ARM64Registers::q20
;
201 static const FPRReg fpRegT13
= ARM64Registers::q21
;
202 static const FPRReg fpRegT14
= ARM64Registers::q22
;
203 static const FPRReg fpRegT15
= ARM64Registers::q23
;
204 static const FPRReg fpRegT16
= ARM64Registers::q24
;
205 static const FPRReg fpRegT17
= ARM64Registers::q25
;
206 static const FPRReg fpRegT18
= ARM64Registers::q26
;
207 static const FPRReg fpRegT19
= ARM64Registers::q27
;
208 static const FPRReg fpRegT20
= ARM64Registers::q28
;
209 static const FPRReg fpRegT21
= ARM64Registers::q29
;
210 static const FPRReg fpRegT22
= ARM64Registers::q30
;
212 static const FPRReg argumentFPR0
= ARM64Registers::q0
; // fpRegT0
213 static const FPRReg argumentFPR1
= ARM64Registers::q1
; // fpRegT1
214 static const FPRReg argumentFPR2
= ARM64Registers::q2
; // fpRegT2
215 static const FPRReg argumentFPR3
= ARM64Registers::q3
; // fpRegT3
216 static const FPRReg argumentFPR4
= ARM64Registers::q4
; // fpRegT4
217 static const FPRReg argumentFPR5
= ARM64Registers::q5
; // fpRegT5
218 static const FPRReg argumentFPR6
= ARM64Registers::q6
; // fpRegT6
219 static const FPRReg argumentFPR7
= ARM64Registers::q7
; // fpRegT7
221 static const FPRReg returnValueFPR
= ARM64Registers::q0
; // fpRegT0
223 static FPRReg
toRegister(unsigned index
)
225 ASSERT(index
< numberOfRegisters
);
226 static const FPRReg registerForIndex
[numberOfRegisters
] = {
227 fpRegT0
, fpRegT1
, fpRegT2
, fpRegT3
, fpRegT4
, fpRegT5
, fpRegT6
, fpRegT7
,
228 fpRegT8
, fpRegT9
, fpRegT10
, fpRegT11
, fpRegT12
, fpRegT13
, fpRegT14
, fpRegT15
,
229 fpRegT16
, fpRegT17
, fpRegT18
, fpRegT19
, fpRegT20
, fpRegT21
, fpRegT22
231 return registerForIndex
[index
];
234 static unsigned toIndex(FPRReg reg
)
236 ASSERT(reg
!= InvalidFPRReg
);
237 ASSERT(static_cast<int>(reg
) < 32);
238 static const unsigned indexForRegister
[32] = {
239 0, 1, 2, 3, 4, 5, 6, 7,
240 InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
,
241 8, 9, 10, 11, 12, 13, 14, 15,
242 16, 17, 18, 19, 20, 21, 22, InvalidIndex
244 unsigned result
= indexForRegister
[reg
];
248 static const char* debugName(FPRReg reg
)
250 ASSERT(reg
!= InvalidFPRReg
);
251 ASSERT(static_cast<int>(reg
) < 32);
252 static const char* nameForRegister
[32] = {
253 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
254 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
255 "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
256 "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
258 return nameForRegister
[reg
];
261 static const unsigned InvalidIndex
= 0xffffffff;
270 typedef FPRReg RegisterType
;
271 static const unsigned numberOfRegisters
= 6;
273 // Temporary registers.
274 static const FPRReg fpRegT0
= MIPSRegisters::f0
;
275 static const FPRReg fpRegT1
= MIPSRegisters::f4
;
276 static const FPRReg fpRegT2
= MIPSRegisters::f6
;
277 static const FPRReg fpRegT3
= MIPSRegisters::f8
;
278 static const FPRReg fpRegT4
= MIPSRegisters::f10
;
279 static const FPRReg fpRegT5
= MIPSRegisters::f18
;
281 static const FPRReg returnValueFPR
= MIPSRegisters::f0
;
283 static const FPRReg argumentFPR0
= MIPSRegisters::f12
;
284 static const FPRReg argumentFPR1
= MIPSRegisters::f14
;
286 static FPRReg
toRegister(unsigned index
)
288 static const FPRReg registerForIndex
[numberOfRegisters
] = {
289 fpRegT0
, fpRegT1
, fpRegT2
, fpRegT3
, fpRegT4
, fpRegT5
};
291 ASSERT(index
< numberOfRegisters
);
292 return registerForIndex
[index
];
295 static unsigned toIndex(FPRReg reg
)
297 ASSERT(reg
!= InvalidFPRReg
);
299 static const unsigned indexForRegister
[20] = {
300 0, InvalidIndex
, InvalidIndex
, InvalidIndex
,
301 1, InvalidIndex
, 2, InvalidIndex
,
302 3, InvalidIndex
, 4, InvalidIndex
,
303 InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
,
304 InvalidIndex
, InvalidIndex
, 5, InvalidIndex
,
306 unsigned result
= indexForRegister
[reg
];
310 static const char* debugName(FPRReg reg
)
312 ASSERT(reg
!= InvalidFPRReg
);
314 static const char* nameForRegister
[32] = {
315 "f0", "f1", "f2", "f3",
316 "f4", "f5", "f6", "f7",
317 "f8", "f9", "f10", "f11",
318 "f12", "f13", "f14", "f15"
319 "f16", "f17", "f18", "f19"
320 "f20", "f21", "f22", "f23"
321 "f24", "f25", "f26", "f27"
322 "f28", "f29", "f30", "f31"
324 return nameForRegister
[reg
];
327 static const unsigned InvalidIndex
= 0xffffffff;
336 typedef FPRReg RegisterType
;
337 static const unsigned numberOfRegisters
= 6;
339 // Temporary registers.
340 static const FPRReg fpRegT0
= SH4Registers::dr0
;
341 static const FPRReg fpRegT1
= SH4Registers::dr2
;
342 static const FPRReg fpRegT2
= SH4Registers::dr4
;
343 static const FPRReg fpRegT3
= SH4Registers::dr6
;
344 static const FPRReg fpRegT4
= SH4Registers::dr8
;
345 static const FPRReg fpRegT5
= SH4Registers::dr10
;
347 static const FPRReg returnValueFPR
= SH4Registers::dr0
;
349 static const FPRReg argumentFPR0
= SH4Registers::dr4
;
350 static const FPRReg argumentFPR1
= SH4Registers::dr6
;
352 static FPRReg
toRegister(unsigned index
)
354 static const FPRReg registerForIndex
[numberOfRegisters
] = {
355 fpRegT0
, fpRegT1
, fpRegT2
, fpRegT3
, fpRegT4
, fpRegT5
};
357 ASSERT(index
< numberOfRegisters
);
358 return registerForIndex
[index
];
361 static unsigned toIndex(FPRReg reg
)
363 ASSERT(reg
!= InvalidFPRReg
);
365 static const unsigned indexForRegister
[16] = {
366 0, InvalidIndex
, 1, InvalidIndex
,
367 2, InvalidIndex
, 3, InvalidIndex
,
368 4, InvalidIndex
, 5, InvalidIndex
,
369 InvalidIndex
, InvalidIndex
, InvalidIndex
, InvalidIndex
371 unsigned result
= indexForRegister
[reg
];
375 static const char* debugName(FPRReg reg
)
377 ASSERT(reg
!= InvalidFPRReg
);
379 static const char* nameForRegister
[16] = {
380 "dr0", "fr1", "dr2", "fr3",
381 "dr4", "fr5", "dr6", "fr7",
382 "dr8", "fr9", "dr10", "fr11",
383 "dr12", "fr13", "dr14", "fr15"
385 return nameForRegister
[reg
];
388 static const unsigned InvalidIndex
= 0xffffffff;
393 #endif // ENABLE(JIT)
399 inline void printInternal(PrintStream
& out
, JSC::FPRReg reg
)
402 out
.print("%", JSC::FPRInfo::debugName(reg
));
404 out
.printf("%%fr%d", reg
);