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 "B3ConstDoubleValue.h"
28
29#if ENABLE(B3_JIT)
30
31#include "B3ConstFloatValue.h"
32#include "B3ProcedureInlines.h"
33#include "B3ValueInlines.h"
34
35namespace JSC { namespace B3 {
36
37ConstDoubleValue::~ConstDoubleValue()
38{
39}
40
41Value* ConstDoubleValue::negConstant(Procedure& proc) const
42{
43 return proc.add<ConstDoubleValue>(origin(), -m_value);
44}
45
46Value* ConstDoubleValue::addConstant(Procedure& proc, int32_t other) const
47{
48 return proc.add<ConstDoubleValue>(origin(), m_value + static_cast<double>(other));
49}
50
51Value* ConstDoubleValue::addConstant(Procedure& proc, const Value* other) const
52{
53 if (!other->hasDouble())
54 return nullptr;
55 return proc.add<ConstDoubleValue>(origin(), m_value + other->asDouble());
56}
57
58Value* ConstDoubleValue::subConstant(Procedure& proc, const Value* other) const
59{
60 if (!other->hasDouble())
61 return nullptr;
62 return proc.add<ConstDoubleValue>(origin(), m_value - other->asDouble());
63}
64
65Value* ConstDoubleValue::mulConstant(Procedure& proc, const Value* other) const
66{
67 if (!other->hasDouble())
68 return nullptr;
69 return proc.add<ConstDoubleValue>(origin(), m_value * other->asDouble());
70}
71
72Value* ConstDoubleValue::bitAndConstant(Procedure& proc, const Value* other) const
73{
74 if (!other->hasDouble())
75 return nullptr;
76 double result = bitwise_cast<double>(bitwise_cast<uint64_t>(m_value) & bitwise_cast<uint64_t>(other->asDouble()));
77 return proc.add<ConstDoubleValue>(origin(), result);
78}
79
80Value* ConstDoubleValue::bitOrConstant(Procedure& proc, const Value* other) const
81{
82 if (!other->hasDouble())
83 return nullptr;
84 double result = bitwise_cast<double>(bitwise_cast<uint64_t>(m_value) | bitwise_cast<uint64_t>(other->asDouble()));
85 return proc.add<ConstDoubleValue>(origin(), result);
86}
87
88Value* ConstDoubleValue::bitXorConstant(Procedure& proc, const Value* other) const
89{
90 if (!other->hasDouble())
91 return nullptr;
92 double result = bitwise_cast<double>(bitwise_cast<uint64_t>(m_value) ^ bitwise_cast<uint64_t>(other->asDouble()));
93 return proc.add<ConstDoubleValue>(origin(), result);
94}
95
96
97Value* ConstDoubleValue::bitwiseCastConstant(Procedure& proc) const
98{
99 return proc.add<Const64Value>(origin(), bitwise_cast<int64_t>(m_value));
100}
101
102Value* ConstDoubleValue::doubleToFloatConstant(Procedure& proc) const
103{
104 return proc.add<ConstFloatValue>(origin(), static_cast<float>(m_value));
105}
106
107Value* ConstDoubleValue::absConstant(Procedure& proc) const
108{
109 return proc.add<ConstDoubleValue>(origin(), fabs(m_value));
110}
111
112Value* ConstDoubleValue::ceilConstant(Procedure& proc) const
113{
114 return proc.add<ConstDoubleValue>(origin(), ceil(m_value));
115}
116
117Value* ConstDoubleValue::floorConstant(Procedure& proc) const
118{
119 return proc.add<ConstDoubleValue>(origin(), floor(m_value));
120}
121
122Value* ConstDoubleValue::sqrtConstant(Procedure& proc) const
123{
124 return proc.add<ConstDoubleValue>(origin(), sqrt(m_value));
125}
126
127Value* ConstDoubleValue::divConstant(Procedure& proc, const Value* other) const
128{
129 if (!other->hasDouble())
130 return nullptr;
131 return proc.add<ConstDoubleValue>(origin(), m_value / other->asDouble());
132}
133
134Value* ConstDoubleValue::modConstant(Procedure& proc, const Value* other) const
135{
136 if (!other->hasDouble())
137 return nullptr;
138 return proc.add<ConstDoubleValue>(origin(), fmod(m_value, other->asDouble()));
139}
140
141TriState ConstDoubleValue::equalConstant(const Value* other) const
142{
143 if (!other->hasDouble())
144 return MixedTriState;
145 return triState(m_value == other->asDouble());
146}
147
148TriState ConstDoubleValue::notEqualConstant(const Value* other) const
149{
150 if (!other->hasDouble())
151 return MixedTriState;
152 return triState(m_value != other->asDouble());
153}
154
155TriState ConstDoubleValue::lessThanConstant(const Value* other) const
156{
157 if (!other->hasDouble())
158 return MixedTriState;
159 return triState(m_value < other->asDouble());
160}
161
162TriState ConstDoubleValue::greaterThanConstant(const Value* other) const
163{
164 if (!other->hasDouble())
165 return MixedTriState;
166 return triState(m_value > other->asDouble());
167}
168
169TriState ConstDoubleValue::lessEqualConstant(const Value* other) const
170{
171 if (!other->hasDouble())
172 return MixedTriState;
173 return triState(m_value <= other->asDouble());
174}
175
176TriState ConstDoubleValue::greaterEqualConstant(const Value* other) const
177{
178 if (!other->hasDouble())
179 return MixedTriState;
180 return triState(m_value >= other->asDouble());
181}
182
183TriState ConstDoubleValue::equalOrUnorderedConstant(const Value* other) const
184{
185 if (std::isnan(m_value))
186 return TrueTriState;
187
188 if (!other->hasDouble())
189 return MixedTriState;
190 double otherValue = other->asDouble();
191 return triState(std::isunordered(m_value, otherValue) || m_value == otherValue);
192}
193
194void ConstDoubleValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
195{
196 out.print(comma);
197 out.printf("%le", m_value);
198}
199
200} } // namespace JSC::B3
201
202#endif // ENABLE(B3_JIT)
203