1198564314e5bedf8d312a30ea13622e05d181c2
[WebKit.git] / Source / JavaScriptCore / b3 / B3Common.h
1 /*
2  * Copyright (C) 2015-2017 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(B3_JIT)
29
30 #include "CPU.h"
31 #include "GPRInfo.h"
32 #include "JSExportMacros.h"
33 #include "Options.h"
34 #include <wtf/Optional.h>
35
36 namespace JSC { namespace B3 {
37
38 enum B3ComplitationMode {
39     B3Mode,
40     AirMode
41 };
42
43 JS_EXPORT_PRIVATE bool shouldDumpIR(B3ComplitationMode);
44 bool shouldDumpIRAtEachPhase(B3ComplitationMode);
45 bool shouldValidateIR();
46 bool shouldValidateIRAtEachPhase();
47 bool shouldSaveIRBeforePhase();
48
49 template<typename BitsType, typename InputType>
50 inline bool isIdentical(InputType left, InputType right)
51 {
52     BitsType leftBits = bitwise_cast<BitsType>(left);
53     BitsType rightBits = bitwise_cast<BitsType>(right);
54     return leftBits == rightBits;
55 }
56
57 inline bool isIdentical(int32_t left, int32_t right)
58 {
59     return isIdentical<int32_t>(left, right);
60 }
61
62 inline bool isIdentical(int64_t left, int64_t right)
63 {
64     return isIdentical<int64_t>(left, right);
65 }
66
67 inline bool isIdentical(double left, double right)
68 {
69     return isIdentical<int64_t>(left, right);
70 }
71
72 inline bool isIdentical(float left, float right)
73 {
74     return isIdentical<int32_t>(left, right);
75 }
76
77 template<typename ResultType, typename InputType, typename BitsType>
78 inline bool isRepresentableAsImpl(InputType originalValue)
79 {
80     // Convert the original value to the desired result type.
81     ResultType result = static_cast<ResultType>(originalValue);
82
83     // Convert the converted value back to the original type. The original value is representable
84     // using the new type if such round-tripping doesn't lose bits.
85     InputType newValue = static_cast<InputType>(result);
86
87     return isIdentical<BitsType>(originalValue, newValue);
88 }
89
90 template<typename ResultType>
91 inline bool isRepresentableAs(int32_t value)
92 {
93     return isRepresentableAsImpl<ResultType, int32_t, int32_t>(value);
94 }
95
96 template<typename ResultType>
97 inline bool isRepresentableAs(int64_t value)
98 {
99     return isRepresentableAsImpl<ResultType, int64_t, int64_t>(value);
100 }
101
102 template<typename ResultType>
103 inline bool isRepresentableAs(size_t value)
104 {
105     return isRepresentableAsImpl<ResultType, size_t, size_t>(value);
106 }
107
108 template<typename ResultType>
109 inline bool isRepresentableAs(double value)
110 {
111     return isRepresentableAsImpl<ResultType, double, int64_t>(value);
112 }
113
114 template<typename IntType>
115 static IntType chillDiv(IntType numerator, IntType denominator)
116 {
117     if (!denominator)
118         return 0;
119     if (denominator == -1 && numerator == std::numeric_limits<IntType>::min())
120         return std::numeric_limits<IntType>::min();
121     return numerator / denominator;
122 }
123
124 template<typename IntType>
125 static IntType chillMod(IntType numerator, IntType denominator)
126 {
127     if (!denominator)
128         return 0;
129     if (denominator == -1 && numerator == std::numeric_limits<IntType>::min())
130         return 0;
131     return numerator % denominator;
132 }
133
134 template<typename IntType>
135 static IntType chillUDiv(IntType numerator, IntType denominator)
136 {
137     typedef typename std::make_unsigned<IntType>::type UnsignedIntType;
138     UnsignedIntType unsignedNumerator = static_cast<UnsignedIntType>(numerator);
139     UnsignedIntType unsignedDenominator = static_cast<UnsignedIntType>(denominator);
140     if (!unsignedDenominator)
141         return 0;
142     return unsignedNumerator / unsignedDenominator;
143 }
144
145 template<typename IntType>
146 static IntType chillUMod(IntType numerator, IntType denominator)
147 {
148     typedef typename std::make_unsigned<IntType>::type UnsignedIntType;
149     UnsignedIntType unsignedNumerator = static_cast<UnsignedIntType>(numerator);
150     UnsignedIntType unsignedDenominator = static_cast<UnsignedIntType>(denominator);
151     if (!unsignedDenominator)
152         return 0;
153     return unsignedNumerator % unsignedDenominator;
154 }
155
156 template<typename IntType>
157 static IntType rotateRight(IntType value, int32_t shift)
158 {
159     typedef typename std::make_unsigned<IntType>::type UnsignedIntType;
160     UnsignedIntType uValue = static_cast<UnsignedIntType>(value);
161     int32_t bits = sizeof(IntType) * 8;
162     int32_t mask = bits - 1;
163     shift &= mask;
164     return (uValue >> shift) | (uValue << ((bits - shift) & mask));
165 }
166
167 template<typename IntType>
168 static IntType rotateLeft(IntType value, int32_t shift)
169 {
170     typedef typename std::make_unsigned<IntType>::type UnsignedIntType;
171     UnsignedIntType uValue = static_cast<UnsignedIntType>(value);
172     int32_t bits = sizeof(IntType) * 8;
173     int32_t mask = bits - 1;
174     shift &= mask;
175     return (uValue << shift) | (uValue >> ((bits - shift) & mask));
176 }
177
178 inline unsigned defaultOptLevel()
179 {
180     // This should almost always return 2, but we allow this default to be lowered for testing. Some
181     // components will deliberately set the optLevel.
182     return Options::defaultB3OptLevel();
183 }
184
185 Optional<GPRReg> pinnedExtendedOffsetAddrRegister();
186
187 } } // namespace JSC::B3
188
189 #endif // ENABLE(B3_JIT)