Use constexpr instead of const in symbol definitions that are obviously constexpr.
[WebKit-https.git] / Source / JavaScriptCore / jit / RegisterSet.h
1 /*
2  * Copyright (C) 2013-2019 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 #pragma once
27
28 #if !ENABLE(C_LOOP)
29
30 #include "GPRInfo.h"
31 #include "MacroAssembler.h"
32 #include "Reg.h"
33 #include "TempRegisterSet.h"
34 #include <wtf/Bitmap.h>
35
36 namespace JSC {
37
38 typedef Bitmap<MacroAssembler::numGPRs + MacroAssembler::numFPRs + 1> RegisterBitmap;
39 class RegisterAtOffsetList;
40
41 class RegisterSet {
42 public:
43     constexpr RegisterSet() { }
44
45     template<typename... Regs>
46     constexpr explicit RegisterSet(Regs... regs)
47     {
48         setMany(regs...);
49     }
50     
51     JS_EXPORT_PRIVATE static RegisterSet stackRegisters();
52     JS_EXPORT_PRIVATE static RegisterSet reservedHardwareRegisters();
53     static RegisterSet runtimeTagRegisters();
54     static RegisterSet specialRegisters(); // The union of stack, reserved hardware, and runtime registers.
55     JS_EXPORT_PRIVATE static RegisterSet calleeSaveRegisters();
56     static RegisterSet vmCalleeSaveRegisters(); // Callee save registers that might be saved and used by any tier.
57     static RegisterAtOffsetList* vmCalleeSaveRegisterOffsets();
58     static RegisterSet llintBaselineCalleeSaveRegisters(); // Registers saved and used by the LLInt.
59     static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
60     static RegisterSet ftlCalleeSaveRegisters(); // Registers that might be saved and used by the FTL JIT.
61 #if ENABLE(WEBASSEMBLY)
62     static RegisterSet webAssemblyCalleeSaveRegisters(); // Registers saved and used by the WebAssembly JIT.
63 #endif
64     static RegisterSet volatileRegistersForJSCall();
65     static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
66     JS_EXPORT_PRIVATE static RegisterSet macroScratchRegisters();
67     JS_EXPORT_PRIVATE static RegisterSet allGPRs();
68     JS_EXPORT_PRIVATE static RegisterSet allFPRs();
69     static RegisterSet allRegisters();
70     JS_EXPORT_PRIVATE static RegisterSet argumentGPRS();
71
72     static RegisterSet registersToNotSaveForJSCall();
73     static RegisterSet registersToNotSaveForCCall();
74     
75     void set(Reg reg, bool value = true)
76     {
77         ASSERT(!!reg);
78         m_bits.set(reg.index(), value);
79     }
80     
81     void set(JSValueRegs regs, bool value = true)
82     {
83         if (regs.tagGPR() != InvalidGPRReg)
84             set(regs.tagGPR(), value);
85         set(regs.payloadGPR(), value);
86     }
87
88     void set(const RegisterSet& other, bool value = true) { value ? merge(other) : exclude(other); }
89
90     void clear(Reg reg)
91     {
92         ASSERT(!!reg);
93         set(reg, false);
94     }
95     
96     bool get(Reg reg) const
97     {
98         ASSERT(!!reg);
99         return m_bits.get(reg.index());
100     }
101     
102     template<typename Iterable>
103     void setAll(const Iterable& iterable)
104     {
105         for (Reg reg : iterable)
106             set(reg);
107     }
108     
109     // Also allow add/remove/contains terminology, which means the same thing as set/clear/get.
110     bool add(Reg reg)
111     {
112         ASSERT(!!reg);
113         return !m_bits.testAndSet(reg.index());
114     }
115     bool remove(Reg reg)
116     {
117         ASSERT(!!reg);
118         return m_bits.testAndClear(reg.index());
119     }
120     bool contains(Reg reg) const { return get(reg); }
121     
122     void merge(const RegisterSet& other) { m_bits.merge(other.m_bits); }
123     void filter(const RegisterSet& other) { m_bits.filter(other.m_bits); }
124     void exclude(const RegisterSet& other) { m_bits.exclude(other.m_bits); }
125     
126     bool subsumes(const RegisterSet& other) const { return m_bits.subsumes(other.m_bits); }
127     
128     size_t numberOfSetGPRs() const;
129     size_t numberOfSetFPRs() const;
130     size_t numberOfSetRegisters() const { return m_bits.count(); }
131     
132     bool isEmpty() const { return m_bits.isEmpty(); }
133     
134     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
135     
136     enum EmptyValueTag { EmptyValue };
137     enum DeletedValueTag { DeletedValue };
138     
139     RegisterSet(EmptyValueTag)
140     {
141         m_bits.set(hashSpecialBitIndex);
142     }
143     
144     RegisterSet(DeletedValueTag)
145     {
146         m_bits.set(hashSpecialBitIndex);
147         m_bits.set(deletedBitIndex);
148     }
149     
150     bool isEmptyValue() const
151     {
152         return m_bits.get(hashSpecialBitIndex) && !m_bits.get(deletedBitIndex);
153     }
154     
155     bool isDeletedValue() const
156     {
157         return m_bits.get(hashSpecialBitIndex) && m_bits.get(deletedBitIndex);
158     }
159     
160     bool operator==(const RegisterSet& other) const { return m_bits == other.m_bits; }
161     bool operator!=(const RegisterSet& other) const { return m_bits != other.m_bits; }
162     
163     unsigned hash() const { return m_bits.hash(); }
164     
165     template<typename Func>
166     void forEach(const Func& func) const
167     {
168         m_bits.forEachSetBit(
169             [&] (size_t index) {
170                 func(Reg::fromIndex(index));
171             });
172     }
173     
174     class iterator {
175     public:
176         iterator()
177         {
178         }
179         
180         iterator(const RegisterBitmap::iterator& iter)
181             : m_iter(iter)
182         {
183         }
184         
185         Reg operator*() const { return Reg::fromIndex(*m_iter); }
186         
187         iterator& operator++()
188         {
189             ++m_iter;
190             return *this;
191         }
192         
193         bool operator==(const iterator& other)
194         {
195             return m_iter == other.m_iter;
196         }
197         
198         bool operator!=(const iterator& other)
199         {
200             return !(*this == other);
201         }
202         
203     private:
204         RegisterBitmap::iterator m_iter;
205     };
206     
207     iterator begin() const { return iterator(m_bits.begin()); }
208     iterator end() const { return iterator(m_bits.end()); }
209     
210 private:
211     void setAny(Reg reg) { set(reg); }
212     void setAny(JSValueRegs regs) { set(regs); }
213     void setAny(const RegisterSet& set) { merge(set); }
214     void setMany() { }
215     template<typename RegType, typename... Regs>
216     void setMany(RegType reg, Regs... regs)
217     {
218         setAny(reg);
219         setMany(regs...);
220     }
221
222     // These offsets mirror the logic in Reg.h.
223     static constexpr unsigned gprOffset = 0;
224     static constexpr unsigned fprOffset = gprOffset + MacroAssembler::numGPRs;
225     static constexpr unsigned hashSpecialBitIndex = fprOffset + MacroAssembler::numFPRs;
226     static constexpr unsigned deletedBitIndex = 0;
227     
228     RegisterBitmap m_bits;
229 };
230
231 struct RegisterSetHash {
232     static unsigned hash(const RegisterSet& set) { return set.hash(); }
233     static bool equal(const RegisterSet& a, const RegisterSet& b) { return a == b; }
234     static constexpr bool safeToCompareToEmptyOrDeleted = false;
235 };
236
237 } // namespace JSC
238
239 namespace WTF {
240
241 template<typename T> struct DefaultHash;
242 template<> struct DefaultHash<JSC::RegisterSet> {
243     typedef JSC::RegisterSetHash Hash;
244 };
245
246 template<typename T> struct HashTraits;
247 template<> struct HashTraits<JSC::RegisterSet> : public CustomHashTraits<JSC::RegisterSet> { };
248
249 } // namespace WTF
250
251 #endif // !ENABLE(C_LOOP)