]> git.saurik.com Git - apple/javascriptcore.git/blob - jit/FPRInfo.h
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / jit / FPRInfo.h
1 /*
2 * Copyright (C) 2011, 2013 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 FPRInfo_h
27 #define FPRInfo_h
28
29 #include "MacroAssembler.h"
30 #include <wtf/PrintStream.h>
31
32 namespace JSC {
33
34 typedef MacroAssembler::FPRegisterID FPRReg;
35 #define InvalidFPRReg ((::JSC::FPRReg)-1)
36
37 #if ENABLE(JIT)
38
39 #if CPU(X86) || CPU(X86_64)
40
41 class FPRInfo {
42 public:
43 typedef FPRReg RegisterType;
44 static const unsigned numberOfRegisters = 6;
45
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;
53 #if CPU(X86_64)
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
59 #endif
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
63
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)
73 {
74 return (FPRReg)index;
75 }
76 static unsigned toIndex(FPRReg reg)
77 {
78 unsigned result = (unsigned)reg;
79 if (result >= numberOfRegisters)
80 return InvalidIndex;
81 return result;
82 }
83
84 static FPRReg toArgumentRegister(unsigned index)
85 {
86 return (FPRReg)index;
87 }
88
89 static const char* debugName(FPRReg reg)
90 {
91 ASSERT(reg != InvalidFPRReg);
92 #if CPU(X86_64)
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"
99 };
100 #elif CPU(X86)
101 ASSERT(static_cast<int>(reg) < 8);
102 static const char* nameForRegister[8] = {
103 "xmm0", "xmm1", "xmm2", "xmm3",
104 "xmm4", "xmm5", "xmm6", "xmm7"
105 };
106 #endif
107 return nameForRegister[reg];
108 }
109
110 static const unsigned InvalidIndex = 0xffffffff;
111 };
112
113 #endif // CPU(X86) || CPU(X86_64)
114
115 #if CPU(ARM)
116
117 class FPRInfo {
118 public:
119 typedef FPRReg RegisterType;
120 static const unsigned numberOfRegisters = 6;
121
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
134
135 #if CPU(ARM_HARDFP)
136 static const FPRReg argumentFPR0 = ARMRegisters::d0; // fpRegT0
137 static const FPRReg argumentFPR1 = ARMRegisters::d1; // fpRegT1
138 #endif
139
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)
149 {
150 return (FPRReg)index;
151 }
152 static unsigned toIndex(FPRReg reg)
153 {
154 return (unsigned)reg;
155 }
156
157 static const char* debugName(FPRReg reg)
158 {
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"
170 };
171 return nameForRegister[reg];
172 }
173
174 static const unsigned InvalidIndex = 0xffffffff;
175 };
176
177 #endif // CPU(ARM)
178
179 #if CPU(ARM64)
180
181 class FPRInfo {
182 public:
183 typedef FPRReg RegisterType;
184 static const unsigned numberOfRegisters = 23;
185
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;
211
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
220
221 static const FPRReg returnValueFPR = ARM64Registers::q0; // fpRegT0
222
223 static FPRReg toRegister(unsigned index)
224 {
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
230 };
231 return registerForIndex[index];
232 }
233
234 static unsigned toIndex(FPRReg reg)
235 {
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
243 };
244 unsigned result = indexForRegister[reg];
245 return result;
246 }
247
248 static const char* debugName(FPRReg reg)
249 {
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"
257 };
258 return nameForRegister[reg];
259 }
260
261 static const unsigned InvalidIndex = 0xffffffff;
262 };
263
264 #endif // CPU(ARM64)
265
266 #if CPU(MIPS)
267
268 class FPRInfo {
269 public:
270 typedef FPRReg RegisterType;
271 static const unsigned numberOfRegisters = 6;
272
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;
280
281 static const FPRReg returnValueFPR = MIPSRegisters::f0;
282
283 static const FPRReg argumentFPR0 = MIPSRegisters::f12;
284 static const FPRReg argumentFPR1 = MIPSRegisters::f14;
285
286 static FPRReg toRegister(unsigned index)
287 {
288 static const FPRReg registerForIndex[numberOfRegisters] = {
289 fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
290
291 ASSERT(index < numberOfRegisters);
292 return registerForIndex[index];
293 }
294
295 static unsigned toIndex(FPRReg reg)
296 {
297 ASSERT(reg != InvalidFPRReg);
298 ASSERT(reg < 20);
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,
305 };
306 unsigned result = indexForRegister[reg];
307 return result;
308 }
309
310 static const char* debugName(FPRReg reg)
311 {
312 ASSERT(reg != InvalidFPRReg);
313 ASSERT(reg < 32);
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"
323 };
324 return nameForRegister[reg];
325 }
326
327 static const unsigned InvalidIndex = 0xffffffff;
328 };
329
330 #endif // CPU(MIPS)
331
332 #if CPU(SH4)
333
334 class FPRInfo {
335 public:
336 typedef FPRReg RegisterType;
337 static const unsigned numberOfRegisters = 6;
338
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;
346
347 static const FPRReg returnValueFPR = SH4Registers::dr0;
348
349 static const FPRReg argumentFPR0 = SH4Registers::dr4;
350 static const FPRReg argumentFPR1 = SH4Registers::dr6;
351
352 static FPRReg toRegister(unsigned index)
353 {
354 static const FPRReg registerForIndex[numberOfRegisters] = {
355 fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
356
357 ASSERT(index < numberOfRegisters);
358 return registerForIndex[index];
359 }
360
361 static unsigned toIndex(FPRReg reg)
362 {
363 ASSERT(reg != InvalidFPRReg);
364 ASSERT(reg < 16);
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
370 };
371 unsigned result = indexForRegister[reg];
372 return result;
373 }
374
375 static const char* debugName(FPRReg reg)
376 {
377 ASSERT(reg != InvalidFPRReg);
378 ASSERT(reg < 16);
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"
384 };
385 return nameForRegister[reg];
386 }
387
388 static const unsigned InvalidIndex = 0xffffffff;
389 };
390
391 #endif // CPU(SH4)
392
393 #endif // ENABLE(JIT)
394
395 } // namespace JSC
396
397 namespace WTF {
398
399 inline void printInternal(PrintStream& out, JSC::FPRReg reg)
400 {
401 #if ENABLE(JIT)
402 out.print("%", JSC::FPRInfo::debugName(reg));
403 #else
404 out.printf("%%fr%d", reg);
405 #endif
406 }
407
408 } // namespace WTF
409
410 #endif