]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGFPRInfo.h
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / dfg / DFGFPRInfo.h
CommitLineData
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 DFGFPRInfo_h
27#define DFGFPRInfo_h
28
29#if ENABLE(DFG_JIT)
30
93a37866
A
31#include "DFGRegisterBank.h"
32#include "MacroAssembler.h"
14957cd0
A
33
34namespace JSC { namespace DFG {
35
36typedef MacroAssembler::FPRegisterID FPRReg;
37#define InvalidFPRReg ((FPRReg)-1)
38
6fe7ccc8
A
39#if CPU(X86) || CPU(X86_64)
40
14957cd0
A
41class FPRInfo {
42public:
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;
6fe7ccc8
A
53#if CPU(X86_64)
54 // Only X86_64 passes aguments in xmm registers
14957cd0
A
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
6fe7ccc8
A
59#endif
60 // On X86 the return will actually be on the x87 stack,
61 // so we'll copy to xmm0 for sanity!
14957cd0
A
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 return (unsigned)reg;
79 }
80
14957cd0
A
81 static const char* debugName(FPRReg reg)
82 {
83 ASSERT(reg != InvalidFPRReg);
6fe7ccc8 84#if CPU(X86_64)
93a37866 85 ASSERT(static_cast<int>(reg) < 16);
14957cd0
A
86 static const char* nameForRegister[16] = {
87 "xmm0", "xmm1", "xmm2", "xmm3",
88 "xmm4", "xmm5", "xmm6", "xmm7",
89 "xmm8", "xmm9", "xmm10", "xmm11",
90 "xmm12", "xmm13", "xmm14", "xmm15"
91 };
6fe7ccc8 92#elif CPU(X86)
93a37866 93 ASSERT(static_cast<int>(reg) < 8);
6fe7ccc8
A
94 static const char* nameForRegister[8] = {
95 "xmm0", "xmm1", "xmm2", "xmm3",
96 "xmm4", "xmm5", "xmm6", "xmm7"
97 };
98#endif
14957cd0
A
99 return nameForRegister[reg];
100 }
6fe7ccc8
A
101};
102
14957cd0 103#endif
6fe7ccc8 104
93a37866 105#if CPU(ARM)
6fe7ccc8
A
106
107class FPRInfo {
108public:
109 typedef FPRReg RegisterType;
110 static const unsigned numberOfRegisters = 6;
111
112 // Temporary registers.
113 // d7 is use by the MacroAssembler as fpTempRegister.
114 static const FPRReg fpRegT0 = ARMRegisters::d0;
115 static const FPRReg fpRegT1 = ARMRegisters::d1;
116 static const FPRReg fpRegT2 = ARMRegisters::d2;
117 static const FPRReg fpRegT3 = ARMRegisters::d3;
118 static const FPRReg fpRegT4 = ARMRegisters::d4;
119 static const FPRReg fpRegT5 = ARMRegisters::d5;
120 // ARMv7 doesn't pass arguments in fp registers. The return
121 // value is also actually in integer registers, for now
122 // we'll return in d0 for simplicity.
123 static const FPRReg returnValueFPR = ARMRegisters::d0; // fpRegT0
124
93a37866
A
125#if CPU(ARM_HARDFP)
126 static const FPRReg argumentFPR0 = ARMRegisters::d0; // fpRegT0
127 static const FPRReg argumentFPR1 = ARMRegisters::d1; // fpRegT1
128#endif
129
6fe7ccc8
A
130 // FPRReg mapping is direct, the machine regsiter numbers can
131 // be used directly as indices into the FPR RegisterBank.
132 COMPILE_ASSERT(ARMRegisters::d0 == 0, d0_is_0);
133 COMPILE_ASSERT(ARMRegisters::d1 == 1, d1_is_1);
134 COMPILE_ASSERT(ARMRegisters::d2 == 2, d2_is_2);
135 COMPILE_ASSERT(ARMRegisters::d3 == 3, d3_is_3);
136 COMPILE_ASSERT(ARMRegisters::d4 == 4, d4_is_4);
137 COMPILE_ASSERT(ARMRegisters::d5 == 5, d5_is_5);
138 static FPRReg toRegister(unsigned index)
139 {
140 return (FPRReg)index;
141 }
142 static unsigned toIndex(FPRReg reg)
143 {
144 return (unsigned)reg;
145 }
146
147 static const char* debugName(FPRReg reg)
148 {
149 ASSERT(reg != InvalidFPRReg);
93a37866 150 ASSERT(static_cast<int>(reg) < 32);
6fe7ccc8
A
151 static const char* nameForRegister[32] = {
152 "d0", "d1", "d2", "d3",
153 "d4", "d5", "d6", "d7",
154 "d8", "d9", "d10", "d11",
93a37866
A
155 "d12", "d13", "d14", "d15",
156 "d16", "d17", "d18", "d19",
157 "d20", "d21", "d22", "d23",
158 "d24", "d25", "d26", "d27",
6fe7ccc8
A
159 "d28", "d29", "d30", "d31"
160 };
161 return nameForRegister[reg];
162 }
14957cd0
A
163};
164
6fe7ccc8
A
165#endif
166
93a37866
A
167#if CPU(ARM64)
168
169class FPRInfo {
170public:
171 typedef FPRReg RegisterType;
172 static const unsigned numberOfRegisters = 23;
173
174 // Temporary registers.
175 // q8-q15 are callee saved, q31 is use by the MacroAssembler as fpTempRegister.
176 static const FPRReg fpRegT0 = ARM64Registers::q0;
177 static const FPRReg fpRegT1 = ARM64Registers::q1;
178 static const FPRReg fpRegT2 = ARM64Registers::q2;
179 static const FPRReg fpRegT3 = ARM64Registers::q3;
180 static const FPRReg fpRegT4 = ARM64Registers::q4;
181 static const FPRReg fpRegT5 = ARM64Registers::q5;
182 static const FPRReg fpRegT6 = ARM64Registers::q6;
183 static const FPRReg fpRegT7 = ARM64Registers::q7;
184 static const FPRReg fpRegT8 = ARM64Registers::q16;
185 static const FPRReg fpRegT9 = ARM64Registers::q17;
186 static const FPRReg fpRegT10 = ARM64Registers::q18;
187 static const FPRReg fpRegT11 = ARM64Registers::q19;
188 static const FPRReg fpRegT12 = ARM64Registers::q20;
189 static const FPRReg fpRegT13 = ARM64Registers::q21;
190 static const FPRReg fpRegT14 = ARM64Registers::q22;
191 static const FPRReg fpRegT15 = ARM64Registers::q23;
192 static const FPRReg fpRegT16 = ARM64Registers::q24;
193 static const FPRReg fpRegT17 = ARM64Registers::q25;
194 static const FPRReg fpRegT18 = ARM64Registers::q26;
195 static const FPRReg fpRegT19 = ARM64Registers::q27;
196 static const FPRReg fpRegT20 = ARM64Registers::q28;
197 static const FPRReg fpRegT21 = ARM64Registers::q29;
198 static const FPRReg fpRegT22 = ARM64Registers::q30;
199
200 static const FPRReg argumentFPR0 = ARM64Registers::q0; // fpRegT0
201 static const FPRReg argumentFPR1 = ARM64Registers::q1; // fpRegT1
202 static const FPRReg argumentFPR2 = ARM64Registers::q2; // fpRegT2
203 static const FPRReg argumentFPR3 = ARM64Registers::q3; // fpRegT3
204 static const FPRReg argumentFPR4 = ARM64Registers::q4; // fpRegT4
205 static const FPRReg argumentFPR5 = ARM64Registers::q5; // fpRegT5
206 static const FPRReg argumentFPR6 = ARM64Registers::q6; // fpRegT6
207 static const FPRReg argumentFPR7 = ARM64Registers::q7; // fpRegT7
208
209 static const FPRReg returnValueFPR = ARM64Registers::q0; // fpRegT0
210
211 static FPRReg toRegister(unsigned index)
212 {
213 ASSERT(index < numberOfRegisters);
214 static const FPRReg registerForIndex[numberOfRegisters] = {
215 fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5, fpRegT6, fpRegT7,
216 fpRegT8, fpRegT9, fpRegT10, fpRegT11, fpRegT12, fpRegT13, fpRegT14, fpRegT15,
217 fpRegT16, fpRegT17, fpRegT18, fpRegT19, fpRegT20, fpRegT21, fpRegT22
218 };
219 return registerForIndex[index];
220 }
221
222 static unsigned toIndex(FPRReg reg)
223 {
224 ASSERT(reg != InvalidFPRReg);
225 ASSERT(static_cast<int>(reg) < 32);
226 static const unsigned indexForRegister[32] = {
227 0, 1, 2, 3, 4, 5, 6, 7,
228 InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
229 8, 9, 10, 11, 12, 13, 14, 15,
230 16, 17, 18, 19, 20, 21, 22, InvalidIndex
231 };
232 unsigned result = indexForRegister[reg];
233 ASSERT(result != InvalidIndex);
234 return result;
235 }
236
237 static const char* debugName(FPRReg reg)
238 {
239 ASSERT(reg != InvalidFPRReg);
240 ASSERT(static_cast<int>(reg) < 32);
241 static const char* nameForRegister[32] = {
242 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
243 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
244 "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
245 "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
246 };
247 return nameForRegister[reg];
248 }
249
250private:
251 static const unsigned InvalidIndex = 0xffffffff;
252};
253
254#endif
255
256#if CPU(MIPS)
257
258class FPRInfo {
259public:
260 typedef FPRReg RegisterType;
261 static const unsigned numberOfRegisters = 6;
262
263 // Temporary registers.
264 static const FPRReg fpRegT0 = MIPSRegisters::f0;
265 static const FPRReg fpRegT1 = MIPSRegisters::f4;
266 static const FPRReg fpRegT2 = MIPSRegisters::f6;
267 static const FPRReg fpRegT3 = MIPSRegisters::f8;
268 static const FPRReg fpRegT4 = MIPSRegisters::f10;
269 static const FPRReg fpRegT5 = MIPSRegisters::f18;
270
271 static const FPRReg returnValueFPR = MIPSRegisters::f0;
272
273 static const FPRReg argumentFPR0 = MIPSRegisters::f12;
274 static const FPRReg argumentFPR1 = MIPSRegisters::f14;
275
276 static FPRReg toRegister(unsigned index)
277 {
278 static const FPRReg registerForIndex[numberOfRegisters] = {
279 fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
280
281 ASSERT(index < numberOfRegisters);
282 return registerForIndex[index];
283 }
284
285 static unsigned toIndex(FPRReg reg)
286 {
287 ASSERT(reg != InvalidFPRReg);
288 ASSERT(reg < 20);
289 static const unsigned indexForRegister[20] = {
290 0, InvalidIndex, InvalidIndex, InvalidIndex,
291 1, InvalidIndex, 2, InvalidIndex,
292 3, InvalidIndex, 4, InvalidIndex,
293 InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
294 InvalidIndex, InvalidIndex, 5, InvalidIndex,
295 };
296 unsigned result = indexForRegister[reg];
297 ASSERT(result != InvalidIndex);
298 return result;
299 }
300
301 static const char* debugName(FPRReg reg)
302 {
303 ASSERT(reg != InvalidFPRReg);
304 ASSERT(reg < 32);
305 static const char* nameForRegister[32] = {
306 "f0", "f1", "f2", "f3",
307 "f4", "f5", "f6", "f7",
308 "f8", "f9", "f10", "f11",
309 "f12", "f13", "f14", "f15"
310 "f16", "f17", "f18", "f19"
311 "f20", "f21", "f22", "f23"
312 "f24", "f25", "f26", "f27"
313 "f28", "f29", "f30", "f31"
314 };
315 return nameForRegister[reg];
316 }
317private:
318
319 static const unsigned InvalidIndex = 0xffffffff;
320};
321
322#endif
323
14957cd0
A
324typedef RegisterBank<FPRInfo>::iterator fpr_iterator;
325
326} } // namespace JSC::DFG
327
328#endif
329#endif