be4c68b6c43561491486f251ac21516b59b3e2e3
[WebKit-https.git] / Source / JavaScriptCore / jit / RegisterSet.cpp
1 /*
2  * Copyright (C) 2013, 2014 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 #include "config.h"
27 #include "RegisterSet.h"
28
29 #if ENABLE(JIT)
30
31 #include "GPRInfo.h"
32 #include "MacroAssembler.h"
33 #include "JSCInlines.h"
34 #include <wtf/CommaPrinter.h>
35
36 namespace JSC {
37
38 RegisterSet RegisterSet::stackRegisters()
39 {
40     return RegisterSet(
41         MacroAssembler::stackPointerRegister,
42         MacroAssembler::framePointerRegister);
43 }
44
45 RegisterSet RegisterSet::reservedHardwareRegisters()
46 {
47 #if CPU(ARM64)
48     return RegisterSet(ARM64Registers::lr);
49 #else
50     return RegisterSet();
51 #endif
52 }
53
54 RegisterSet RegisterSet::runtimeRegisters()
55 {
56 #if USE(JSVALUE64)
57     return RegisterSet(GPRInfo::tagTypeNumberRegister, GPRInfo::tagMaskRegister);
58 #else
59     return RegisterSet();
60 #endif
61 }
62
63 RegisterSet RegisterSet::specialRegisters()
64 {
65     return RegisterSet(
66         stackRegisters(), reservedHardwareRegisters(), runtimeRegisters());
67 }
68
69 RegisterSet RegisterSet::stubUnavailableRegisters()
70 {
71     return RegisterSet(specialRegisters(), vmCalleeSaveRegisters());
72 }
73
74 RegisterSet RegisterSet::calleeSaveRegisters()
75 {
76     RegisterSet result;
77 #if CPU(X86)
78     result.set(X86Registers::ebx);
79     result.set(X86Registers::ebp);
80     result.set(X86Registers::edi);
81     result.set(X86Registers::esi);
82 #elif CPU(X86_64)
83     result.set(X86Registers::ebx);
84     result.set(X86Registers::ebp);
85     result.set(X86Registers::r12);
86     result.set(X86Registers::r13);
87     result.set(X86Registers::r14);
88     result.set(X86Registers::r15);
89 #elif CPU(ARM_THUMB2)
90     result.set(ARMRegisters::r4);
91     result.set(ARMRegisters::r5);
92     result.set(ARMRegisters::r6);
93     result.set(ARMRegisters::r8);
94 #if !PLATFORM(IOS)
95     result.set(ARMRegisters::r9);
96 #endif
97     result.set(ARMRegisters::r10);
98     result.set(ARMRegisters::r11);
99 #elif CPU(ARM_TRADITIONAL)
100     result.set(ARMRegisters::r4);
101     result.set(ARMRegisters::r5);
102     result.set(ARMRegisters::r6);
103     result.set(ARMRegisters::r7);
104     result.set(ARMRegisters::r8);
105     result.set(ARMRegisters::r9);
106     result.set(ARMRegisters::r10);
107     result.set(ARMRegisters::r11);
108 #elif CPU(ARM64)
109     // We don't include LR in the set of callee-save registers even though it technically belongs
110     // there. This is because we use this set to describe the set of registers that need to be saved
111     // beyond what you would save by the platform-agnostic "preserve return address" and "restore
112     // return address" operations in CCallHelpers.
113     for (
114         ARM64Registers::RegisterID reg = ARM64Registers::x19;
115         reg <= ARM64Registers::x28;
116         reg = static_cast<ARM64Registers::RegisterID>(reg + 1))
117         result.set(reg);
118     result.set(ARM64Registers::fp);
119     for (
120         ARM64Registers::FPRegisterID reg = ARM64Registers::q8;
121         reg <= ARM64Registers::q15;
122         reg = static_cast<ARM64Registers::FPRegisterID>(reg + 1))
123         result.set(reg);
124 #else
125     UNREACHABLE_FOR_PLATFORM();
126 #endif
127     return result;
128 }
129
130 RegisterSet RegisterSet::vmCalleeSaveRegisters()
131 {
132     RegisterSet result;
133 #if CPU(X86_64)
134     result.set(GPRInfo::regCS0);
135     result.set(GPRInfo::regCS1);
136     result.set(GPRInfo::regCS2);
137     result.set(GPRInfo::regCS3);
138     result.set(GPRInfo::regCS4);
139 #if OS(WINDOWS)
140     result.set(GPRInfo::regCS5);
141     result.set(GPRInfo::regCS6);
142 #endif
143 #elif CPU(ARM64)
144     result.set(GPRInfo::regCS0);
145     result.set(GPRInfo::regCS1);
146     result.set(GPRInfo::regCS2);
147     result.set(GPRInfo::regCS3);
148     result.set(GPRInfo::regCS4);
149     result.set(GPRInfo::regCS5);
150     result.set(GPRInfo::regCS6);
151     result.set(GPRInfo::regCS7);
152     result.set(GPRInfo::regCS8);
153     result.set(GPRInfo::regCS9);
154     result.set(FPRInfo::fpRegCS0);
155     result.set(FPRInfo::fpRegCS1);
156     result.set(FPRInfo::fpRegCS2);
157     result.set(FPRInfo::fpRegCS3);
158     result.set(FPRInfo::fpRegCS4);
159     result.set(FPRInfo::fpRegCS5);
160     result.set(FPRInfo::fpRegCS6);
161     result.set(FPRInfo::fpRegCS7);
162 #endif
163     return result;
164 }
165
166 RegisterSet RegisterSet::llintBaselineCalleeSaveRegisters()
167 {
168     RegisterSet result;
169 #if CPU(X86)
170 #elif CPU(X86_64)
171 #if !OS(WINDOWS)
172     result.set(GPRInfo::regCS2);
173     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
174     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
175     result.set(GPRInfo::regCS3);
176     result.set(GPRInfo::regCS4);
177 #else
178     result.set(GPRInfo::regCS4);
179     ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
180     ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
181     result.set(GPRInfo::regCS5);
182     result.set(GPRInfo::regCS6);
183 #endif
184 #elif CPU(ARM_THUMB2)
185 #elif CPU(ARM_TRADITIONAL)
186 #elif CPU(ARM64)
187     result.set(GPRInfo::regCS7);
188     ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
189     ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
190     result.set(GPRInfo::regCS8);
191     result.set(GPRInfo::regCS9);
192 #elif CPU(MIPS)
193 #elif CPU(SH4)
194 #else
195     UNREACHABLE_FOR_PLATFORM();
196 #endif
197     return result;
198 }
199
200 RegisterSet RegisterSet::dfgCalleeSaveRegisters()
201 {
202     RegisterSet result;
203 #if CPU(X86)
204 #elif CPU(X86_64)
205     result.set(GPRInfo::regCS0);
206     result.set(GPRInfo::regCS1);
207     result.set(GPRInfo::regCS2);
208 #if !OS(WINDOWS)
209     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
210     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
211     result.set(GPRInfo::regCS3);
212     result.set(GPRInfo::regCS4);
213 #else
214     result.set(GPRInfo::regCS3);
215     result.set(GPRInfo::regCS4);
216     ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
217     ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
218     result.set(GPRInfo::regCS5);
219     result.set(GPRInfo::regCS6);
220 #endif
221 #elif CPU(ARM_THUMB2)
222 #elif CPU(ARM_TRADITIONAL)
223 #elif CPU(ARM64)
224     ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
225     ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
226     result.set(GPRInfo::regCS8);
227     result.set(GPRInfo::regCS9);
228 #elif CPU(MIPS)
229 #elif CPU(SH4)
230 #else
231     UNREACHABLE_FOR_PLATFORM();
232 #endif
233     return result;
234 }
235
236 RegisterSet RegisterSet::ftlCalleeSaveRegisters()
237 {
238     RegisterSet result;
239 #if ENABLE(FTL_JIT)
240 #if CPU(X86_64) && !OS(WINDOWS)
241     result.set(GPRInfo::regCS0);
242     result.set(GPRInfo::regCS1);
243     result.set(GPRInfo::regCS2);
244     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
245     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
246     result.set(GPRInfo::regCS3);
247     result.set(GPRInfo::regCS4);
248 #elif CPU(ARM64)
249     // LLVM might save and use all ARM64 callee saves specified in the ABI.
250     result.set(GPRInfo::regCS0);
251     result.set(GPRInfo::regCS1);
252     result.set(GPRInfo::regCS2);
253     result.set(GPRInfo::regCS3);
254     result.set(GPRInfo::regCS4);
255     result.set(GPRInfo::regCS5);
256     result.set(GPRInfo::regCS6);
257     result.set(GPRInfo::regCS7);
258     ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
259     ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
260     result.set(GPRInfo::regCS8);
261     result.set(GPRInfo::regCS9);
262     result.set(FPRInfo::fpRegCS0);
263     result.set(FPRInfo::fpRegCS1);
264     result.set(FPRInfo::fpRegCS2);
265     result.set(FPRInfo::fpRegCS3);
266     result.set(FPRInfo::fpRegCS4);
267     result.set(FPRInfo::fpRegCS5);
268     result.set(FPRInfo::fpRegCS6);
269     result.set(FPRInfo::fpRegCS7);
270 #else
271     UNREACHABLE_FOR_PLATFORM();
272 #endif
273 #endif
274     return result;
275 }
276
277 #if ENABLE(WEBASSEMBLY)
278 RegisterSet RegisterSet::webAssemblyCalleeSaveRegisters()
279 {
280     RegisterSet result;
281 #if CPU(X86)
282 #elif CPU(X86_64)
283 #if !OS(WINDOWS)
284     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
285     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
286     result.set(GPRInfo::regCS3);
287     result.set(GPRInfo::regCS4);
288 #else
289     ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
290     ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
291     result.set(GPRInfo::regCS5);
292     result.set(GPRInfo::regCS6);
293 #endif
294 #elif CPU(ARM_THUMB2)
295 #elif CPU(ARM_TRADITIONAL)
296 #elif CPU(ARM64)
297     ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
298     ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
299     result.set(GPRInfo::regCS8);
300     result.set(GPRInfo::regCS9);
301 #elif CPU(MIPS)
302 #elif CPU(SH4)
303 #else
304     UNREACHABLE_FOR_PLATFORM();
305 #endif
306     return result;
307 }
308 #endif
309
310 RegisterSet RegisterSet::allGPRs()
311 {
312     RegisterSet result;
313     for (MacroAssembler::RegisterID reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = static_cast<MacroAssembler::RegisterID>(reg + 1))
314         result.set(reg);
315     return result;
316 }
317
318 RegisterSet RegisterSet::allFPRs()
319 {
320     RegisterSet result;
321     for (MacroAssembler::FPRegisterID reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = static_cast<MacroAssembler::FPRegisterID>(reg + 1))
322         result.set(reg);
323     return result;
324 }
325
326 RegisterSet RegisterSet::allRegisters()
327 {
328     RegisterSet result;
329     result.merge(allGPRs());
330     result.merge(allFPRs());
331     return result;
332 }
333
334 size_t RegisterSet::numberOfSetGPRs() const
335 {
336     RegisterSet temp = *this;
337     temp.filter(allGPRs());
338     return temp.numberOfSetRegisters();
339 }
340
341 size_t RegisterSet::numberOfSetFPRs() const
342 {
343     RegisterSet temp = *this;
344     temp.filter(allFPRs());
345     return temp.numberOfSetRegisters();
346 }
347
348 void RegisterSet::dump(PrintStream& out) const
349 {
350     CommaPrinter comma;
351     out.print("[");
352     for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
353         if (get(reg))
354             out.print(comma, reg);
355     }
356     out.print("]");
357 }
358
359 } // namespace JSC
360
361 #endif // ENABLE(JIT)
362