1 | /* |
2 | * Copyright (C) 2015-2016 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 "B3Const32Value.h" |
28 | |
29 | #if ENABLE(B3_JIT) |
30 | |
31 | #include "B3ProcedureInlines.h" |
32 | #include "B3ValueInlines.h" |
33 | |
34 | namespace JSC { namespace B3 { |
35 | |
36 | Const32Value::~Const32Value() |
37 | { |
38 | } |
39 | |
40 | Value* Const32Value::negConstant(Procedure& proc) const |
41 | { |
42 | return proc.add<Const32Value>(origin(), -m_value); |
43 | } |
44 | |
45 | Value* Const32Value::addConstant(Procedure& proc, int32_t other) const |
46 | { |
47 | return proc.add<Const32Value>(origin(), m_value + other); |
48 | } |
49 | |
50 | Value* Const32Value::addConstant(Procedure& proc, const Value* other) const |
51 | { |
52 | if (!other->hasInt32()) |
53 | return nullptr; |
54 | return proc.add<Const32Value>(origin(), m_value + other->asInt32()); |
55 | } |
56 | |
57 | Value* Const32Value::subConstant(Procedure& proc, const Value* other) const |
58 | { |
59 | if (!other->hasInt32()) |
60 | return nullptr; |
61 | return proc.add<Const32Value>(origin(), m_value - other->asInt32()); |
62 | } |
63 | |
64 | Value* Const32Value::mulConstant(Procedure& proc, const Value* other) const |
65 | { |
66 | if (!other->hasInt32()) |
67 | return nullptr; |
68 | return proc.add<Const32Value>(origin(), m_value * other->asInt32()); |
69 | } |
70 | |
71 | Value* Const32Value::checkAddConstant(Procedure& proc, const Value* other) const |
72 | { |
73 | if (!other->hasInt32()) |
74 | return nullptr; |
75 | CheckedInt32 result = CheckedInt32(m_value) + CheckedInt32(other->asInt32()); |
76 | if (result.hasOverflowed()) |
77 | return nullptr; |
78 | return proc.add<Const32Value>(origin(), result.unsafeGet()); |
79 | } |
80 | |
81 | Value* Const32Value::checkSubConstant(Procedure& proc, const Value* other) const |
82 | { |
83 | if (!other->hasInt32()) |
84 | return nullptr; |
85 | CheckedInt32 result = CheckedInt32(m_value) - CheckedInt32(other->asInt32()); |
86 | if (result.hasOverflowed()) |
87 | return nullptr; |
88 | return proc.add<Const32Value>(origin(), result.unsafeGet()); |
89 | } |
90 | |
91 | Value* Const32Value::checkMulConstant(Procedure& proc, const Value* other) const |
92 | { |
93 | if (!other->hasInt32()) |
94 | return nullptr; |
95 | CheckedInt32 result = CheckedInt32(m_value) * CheckedInt32(other->asInt32()); |
96 | if (result.hasOverflowed()) |
97 | return nullptr; |
98 | return proc.add<Const32Value>(origin(), result.unsafeGet()); |
99 | } |
100 | |
101 | Value* Const32Value::checkNegConstant(Procedure& proc) const |
102 | { |
103 | if (m_value == -m_value) |
104 | return nullptr; |
105 | return negConstant(proc); |
106 | } |
107 | |
108 | Value* Const32Value::divConstant(Procedure& proc, const Value* other) const |
109 | { |
110 | if (!other->hasInt32()) |
111 | return nullptr; |
112 | return proc.add<Const32Value>(origin(), chillDiv(m_value, other->asInt32())); |
113 | } |
114 | |
115 | Value* Const32Value::uDivConstant(Procedure& proc, const Value* other) const |
116 | { |
117 | if (!other->hasInt32()) |
118 | return nullptr; |
119 | return proc.add<Const32Value>(origin(), chillUDiv(m_value, other->asInt32())); |
120 | } |
121 | |
122 | Value* Const32Value::modConstant(Procedure& proc, const Value* other) const |
123 | { |
124 | if (!other->hasInt32()) |
125 | return nullptr; |
126 | return proc.add<Const32Value>(origin(), chillMod(m_value, other->asInt32())); |
127 | } |
128 | |
129 | Value* Const32Value::uModConstant(Procedure& proc, const Value* other) const |
130 | { |
131 | if (!other->hasInt32()) |
132 | return nullptr; |
133 | return proc.add<Const32Value>(origin(), chillUMod(m_value, other->asInt32())); |
134 | } |
135 | |
136 | Value* Const32Value::bitAndConstant(Procedure& proc, const Value* other) const |
137 | { |
138 | if (!other->hasInt32()) |
139 | return nullptr; |
140 | return proc.add<Const32Value>(origin(), m_value & other->asInt32()); |
141 | } |
142 | |
143 | Value* Const32Value::bitOrConstant(Procedure& proc, const Value* other) const |
144 | { |
145 | if (!other->hasInt32()) |
146 | return nullptr; |
147 | return proc.add<Const32Value>(origin(), m_value | other->asInt32()); |
148 | } |
149 | |
150 | Value* Const32Value::bitXorConstant(Procedure& proc, const Value* other) const |
151 | { |
152 | if (!other->hasInt32()) |
153 | return nullptr; |
154 | return proc.add<Const32Value>(origin(), m_value ^ other->asInt32()); |
155 | } |
156 | |
157 | Value* Const32Value::shlConstant(Procedure& proc, const Value* other) const |
158 | { |
159 | if (!other->hasInt32()) |
160 | return nullptr; |
161 | return proc.add<Const32Value>(origin(), m_value << (other->asInt32() & 31)); |
162 | } |
163 | |
164 | Value* Const32Value::sShrConstant(Procedure& proc, const Value* other) const |
165 | { |
166 | if (!other->hasInt32()) |
167 | return nullptr; |
168 | return proc.add<Const32Value>(origin(), m_value >> (other->asInt32() & 31)); |
169 | } |
170 | |
171 | Value* Const32Value::zShrConstant(Procedure& proc, const Value* other) const |
172 | { |
173 | if (!other->hasInt32()) |
174 | return nullptr; |
175 | return proc.add<Const32Value>(origin(), static_cast<int32_t>(static_cast<uint32_t>(m_value) >> (other->asInt32() & 31))); |
176 | } |
177 | |
178 | Value* Const32Value::rotRConstant(Procedure& proc, const Value* other) const |
179 | { |
180 | if (!other->hasInt32()) |
181 | return nullptr; |
182 | return proc.add<Const32Value>(origin(), rotateRight(m_value, other->asInt32())); |
183 | } |
184 | |
185 | Value* Const32Value::rotLConstant(Procedure& proc, const Value* other) const |
186 | { |
187 | if (!other->hasInt32()) |
188 | return nullptr; |
189 | return proc.add<Const32Value>(origin(), rotateLeft(m_value, other->asInt32())); |
190 | } |
191 | |
192 | Value* Const32Value::bitwiseCastConstant(Procedure& proc) const |
193 | { |
194 | return proc.add<ConstFloatValue>(origin(), bitwise_cast<float>(m_value)); |
195 | } |
196 | |
197 | Value* Const32Value::iToDConstant(Procedure& proc) const |
198 | { |
199 | return proc.add<ConstDoubleValue>(origin(), static_cast<double>(m_value)); |
200 | } |
201 | |
202 | Value* Const32Value::iToFConstant(Procedure& proc) const |
203 | { |
204 | return proc.add<ConstFloatValue>(origin(), static_cast<float>(m_value)); |
205 | } |
206 | |
207 | TriState Const32Value::equalConstant(const Value* other) const |
208 | { |
209 | if (!other->hasInt32()) |
210 | return MixedTriState; |
211 | return triState(m_value == other->asInt32()); |
212 | } |
213 | |
214 | TriState Const32Value::notEqualConstant(const Value* other) const |
215 | { |
216 | if (!other->hasInt32()) |
217 | return MixedTriState; |
218 | return triState(m_value != other->asInt32()); |
219 | } |
220 | |
221 | TriState Const32Value::lessThanConstant(const Value* other) const |
222 | { |
223 | // INT32_MAX < x is always false. |
224 | if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::max()) |
225 | return FalseTriState; |
226 | if (!other->hasInt32()) |
227 | return MixedTriState; |
228 | return triState(m_value < other->asInt32()); |
229 | } |
230 | |
231 | TriState Const32Value::greaterThanConstant(const Value* other) const |
232 | { |
233 | // INT32_MIN > x is always false. |
234 | if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::min()) |
235 | return FalseTriState; |
236 | if (!other->hasInt32()) |
237 | return MixedTriState; |
238 | return triState(m_value > other->asInt32()); |
239 | } |
240 | |
241 | TriState Const32Value::lessEqualConstant(const Value* other) const |
242 | { |
243 | // INT32_MIN <= x is always true. |
244 | if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::min()) |
245 | return TrueTriState; |
246 | if (!other->hasInt32()) |
247 | return MixedTriState; |
248 | return triState(m_value <= other->asInt32()); |
249 | } |
250 | |
251 | TriState Const32Value::greaterEqualConstant(const Value* other) const |
252 | { |
253 | // INT32_MAX >= x is always true. |
254 | if (static_cast<int32_t>(m_value) == std::numeric_limits<int32_t>::max()) |
255 | return TrueTriState; |
256 | if (!other->hasInt32()) |
257 | return MixedTriState; |
258 | return triState(m_value >= other->asInt32()); |
259 | } |
260 | |
261 | TriState Const32Value::aboveConstant(const Value* other) const |
262 | { |
263 | // UINT32_MIN > x is always false. |
264 | if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::min()) |
265 | return FalseTriState; |
266 | if (!other->hasInt32()) |
267 | return MixedTriState; |
268 | return triState(static_cast<uint32_t>(m_value) > static_cast<uint32_t>(other->asInt32())); |
269 | } |
270 | |
271 | TriState Const32Value::belowConstant(const Value* other) const |
272 | { |
273 | // UINT32_MAX < x is always false. |
274 | if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::max()) |
275 | return FalseTriState; |
276 | if (!other->hasInt32()) |
277 | return MixedTriState; |
278 | return triState(static_cast<uint32_t>(m_value) < static_cast<uint32_t>(other->asInt32())); |
279 | } |
280 | |
281 | TriState Const32Value::aboveEqualConstant(const Value* other) const |
282 | { |
283 | // UINT32_MAX >= x is always true. |
284 | if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::max()) |
285 | return TrueTriState; |
286 | if (!other->hasInt32()) |
287 | return MixedTriState; |
288 | return triState(static_cast<uint32_t>(m_value) >= static_cast<uint32_t>(other->asInt32())); |
289 | } |
290 | |
291 | TriState Const32Value::belowEqualConstant(const Value* other) const |
292 | { |
293 | // UINT32_MIN <= x is always true. |
294 | if (static_cast<uint32_t>(m_value) == std::numeric_limits<uint32_t>::min()) |
295 | return TrueTriState; |
296 | if (!other->hasInt32()) |
297 | return MixedTriState; |
298 | return triState(static_cast<uint32_t>(m_value) <= static_cast<uint32_t>(other->asInt32())); |
299 | } |
300 | |
301 | void Const32Value::dumpMeta(CommaPrinter& comma, PrintStream& out) const |
302 | { |
303 | out.print(comma, m_value); |
304 | } |
305 | |
306 | } } // namespace JSC::B3 |
307 | |
308 | #endif // ENABLE(B3_JIT) |
309 | |