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
34namespace JSC { namespace B3 {
35
36Const32Value::~Const32Value()
37{
38}
39
40Value* Const32Value::negConstant(Procedure& proc) const
41{
42 return proc.add<Const32Value>(origin(), -m_value);
43}
44
45Value* Const32Value::addConstant(Procedure& proc, int32_t other) const
46{
47 return proc.add<Const32Value>(origin(), m_value + other);
48}
49
50Value* 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
57Value* 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
64Value* 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
71Value* 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
81Value* 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
91Value* 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
101Value* Const32Value::checkNegConstant(Procedure& proc) const
102{
103 if (m_value == -m_value)
104 return nullptr;
105 return negConstant(proc);
106}
107
108Value* 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
115Value* 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
122Value* 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
129Value* 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
136Value* 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
143Value* 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
150Value* 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
157Value* 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
164Value* 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
171Value* 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
178Value* 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
185Value* 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
192Value* Const32Value::bitwiseCastConstant(Procedure& proc) const
193{
194 return proc.add<ConstFloatValue>(origin(), bitwise_cast<float>(m_value));
195}
196
197Value* Const32Value::iToDConstant(Procedure& proc) const
198{
199 return proc.add<ConstDoubleValue>(origin(), static_cast<double>(m_value));
200}
201
202Value* Const32Value::iToFConstant(Procedure& proc) const
203{
204 return proc.add<ConstFloatValue>(origin(), static_cast<float>(m_value));
205}
206
207TriState Const32Value::equalConstant(const Value* other) const
208{
209 if (!other->hasInt32())
210 return MixedTriState;
211 return triState(m_value == other->asInt32());
212}
213
214TriState Const32Value::notEqualConstant(const Value* other) const
215{
216 if (!other->hasInt32())
217 return MixedTriState;
218 return triState(m_value != other->asInt32());
219}
220
221TriState 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
231TriState 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
241TriState 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
251TriState 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
261TriState 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
271TriState 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
281TriState 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
291TriState 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
301void 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