Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: src/compiler-intrinsics.h

Issue 170383003: Merge a few A64 utils into the CompilerIntrinsics. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and cleaning Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/utils-a64.cc ('k') | src/compiler-intrinsics.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_COMPILER_INTRINSICS_H_ 28 #ifndef V8_COMPILER_INTRINSICS_H_
29 #define V8_COMPILER_INTRINSICS_H_ 29 #define V8_COMPILER_INTRINSICS_H_
30 30
31 #include "globals.h"
32 #include "checks.h"
33
34
31 namespace v8 { 35 namespace v8 {
32 namespace internal { 36 namespace internal {
33 37
38 // C++ fallback implementations when builtins are not availble.
39 int C_CountRedundantLeadingSignBits(int64_t value, int width);
40 int C_CountSetBits(uint64_t value, int width);
41
34 class CompilerIntrinsics { 42 class CompilerIntrinsics {
35 public: 43 public:
36 // Returns number of zero bits preceding least significant 1 bit. 44 // Returns number of zero bits preceding least significant 1 bit.
37 // Undefined for zero value. 45 // Undefined for zero value.
38 INLINE(static int CountTrailingZeros(uint32_t value)); 46 INLINE(static int CountTrailingZeros(uint32_t value));
47 INLINE(static int CountTrailingZeros(uint64_t value));
39 48
40 // Returns number of zero bits following most significant 1 bit. 49 // Returns number of zero bits following most significant 1 bit.
41 // Undefined for zero value. 50 // Undefined for zero value.
42 INLINE(static int CountLeadingZeros(uint32_t value)); 51 INLINE(static int CountLeadingZeros(uint32_t value));
52 INLINE(static int CountLeadingZeros(uint64_t value));
53
54 // Returns the number of redundant leading sign bits.
55 INLINE(static int CountRedundantLeadingSignBits(int32_t value));
56 INLINE(static int CountRedundantLeadingSignBits(int64_t value));
43 57
44 // Returns the number of bits set. 58 // Returns the number of bits set.
45 INLINE(static int CountSetBits(uint32_t value)); 59 INLINE(static int CountSetBits(uint32_t value));
60 INLINE(static int CountSetBits(uint64_t value));
46 }; 61 };
47 62
48 #ifdef __GNUC__ 63 #ifdef __GNUC__
49 int CompilerIntrinsics::CountTrailingZeros(uint32_t value) { 64 int CompilerIntrinsics::CountTrailingZeros(uint32_t value) {
50 return __builtin_ctz(value); 65 return __builtin_ctz(value);
51 } 66 }
52 67
68 int CompilerIntrinsics::CountTrailingZeros(uint64_t value) {
69 return __builtin_ctzll(value);
70 }
71
53 int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { 72 int CompilerIntrinsics::CountLeadingZeros(uint32_t value) {
54 return __builtin_clz(value); 73 return __builtin_clz(value);
55 } 74 }
56 75
76 int CompilerIntrinsics::CountLeadingZeros(uint64_t value) {
77 return __builtin_clzll(value);
78 }
79
80 // __builtin_clrsb and derivatives are only availble since GCC4.7.0.
81 #define GNUC_AVAILABLE_BUILTIN_CLRSB ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7))
82 int CompilerIntrinsics::CountRedundantLeadingSignBits(int32_t value) {
83 #if GNUC_AVAILABLE_BUILTIN_CLRSB
84 return __builtin_clrsb(value);
85 #else
86 return C_CountRedundantLeadingSignBits(value, 32);
87 #endif
88 }
89
90 int CompilerIntrinsics::CountRedundantLeadingSignBits(int64_t value) {
91 #if GNUC_AVAILABLE_BUILTIN_CLRSB
92 return __builtin_clrsbll(value);
93 #else
94 return C_CountRedundantLeadingSignBits(value, 64);
95 #endif
96 }
97 #undef GNUC_AVAILABLE_BUILTIN_CLRSB
98
57 int CompilerIntrinsics::CountSetBits(uint32_t value) { 99 int CompilerIntrinsics::CountSetBits(uint32_t value) {
58 return __builtin_popcount(value); 100 return __builtin_popcount(value);
59 } 101 }
60 102
103 int CompilerIntrinsics::CountSetBits(uint64_t value) {
104 return __builtin_popcountll(value);
105 }
106
61 #elif defined(_MSC_VER) 107 #elif defined(_MSC_VER)
62 108
63 #pragma intrinsic(_BitScanForward) 109 #pragma intrinsic(_BitScanForward)
64 #pragma intrinsic(_BitScanReverse) 110 #pragma intrinsic(_BitScanReverse)
111 #if V8_TARGET_ARCH_X64
112 #pragma intrinsic(_BitScanForward64)
113 #pragma intrinsic(_BitScanReverse64)
114 #endif
65 115
66 int CompilerIntrinsics::CountTrailingZeros(uint32_t value) { 116 int CompilerIntrinsics::CountTrailingZeros(uint32_t value) {
67 unsigned long result; //NOLINT 117 unsigned long result; //NOLINT
68 _BitScanForward(&result, static_cast<long>(value)); //NOLINT 118 _BitScanForward(&result, static_cast<long>(value)); //NOLINT
69 return static_cast<int>(result); 119 return static_cast<int>(result);
70 } 120 }
71 121
122 int CompilerIntrinsics::CountTrailingZeros(uint64_t value) {
123 #if V8_TARGET_ARCH_X64
124 unsigned long result; //NOLINT
125 _BitScanForward64(&result, static_cast<__int64>(value)); //NOLINT
126 return static_cast<int>(result);
127 #else
128 uint32_t low = value & kMaxUInt32;
129 uint32_t high = value >> 32;
130 if (low == 0) {
131 return 32 + CountTrailingZeros(high);
132 } else {
133 return CountTrailingZeros(low);
134 }
135 #endif
136 }
137
72 int CompilerIntrinsics::CountLeadingZeros(uint32_t value) { 138 int CompilerIntrinsics::CountLeadingZeros(uint32_t value) {
73 unsigned long result; //NOLINT 139 unsigned long result; //NOLINT
74 _BitScanReverse(&result, static_cast<long>(value)); //NOLINT 140 _BitScanReverse(&result, static_cast<long>(value)); //NOLINT
75 return 31 - static_cast<int>(result); 141 return 31 - static_cast<int>(result);
76 } 142 }
77 143
144 int CompilerIntrinsics::CountLeadingZeros(uint64_t value) {
145 #if V8_TARGET_ARCH_X64
146 unsigned long result; //NOLINT
147 _BitScanReverse64(&result, static_cast<__int64>(value)); //NOLINT
148 return 63 - static_cast<int>(result);
149 #else
150 uint32_t low = value & kMaxUInt32;
151 uint32_t high = value >> 32;
152 if (high == 0) {
153 return 32 + CountLeadingZeros(low);
154 } else {
155 return CountLeadingZeros(high);
156 }
157 #endif
158 }
159
160 int CompilerIntrinsics::CountRedundantLeadingSignBits(int32_t value) {
161 uint32_t val = static_cast<uint32_t>((value >= 0) ? value : ~value);
162 return CountLeadingZeros(val, width) - 1;
163 }
164
165 int CompilerIntrinsics::CountRedundantLeadingSignBits(int64_t value) {
166 uint64_t val = static_cast<uint64_t>((value >= 0) ? value : ~value);
167 return CountLeadingZeros(val, width) - 1;
168 }
169
78 int CompilerIntrinsics::CountSetBits(uint32_t value) { 170 int CompilerIntrinsics::CountSetBits(uint32_t value) {
79 // Manually count set bits. 171 return C_CountSetBits(value, 32);
80 value = ((value >> 1) & 0x55555555) + (value & 0x55555555); 172 }
81 value = ((value >> 2) & 0x33333333) + (value & 0x33333333); 173
82 value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f); 174 int CompilerIntrinsics::CountSetBits(uint64_t value) {
83 value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff); 175 return C_CountSetBits(value, 64);
84 value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff);
85 return value;
86 } 176 }
87 177
88 #else 178 #else
89 #error Unsupported compiler 179 #error Unsupported compiler
90 #endif 180 #endif
91 181
182
183 // Inline function helpers use the intrinsics and disambiguate undefined
184 // situations.
185
186 inline int CountTrailingZeros(uint32_t value) {
187 if (value == 0) {
188 // The result of the intrinsics is undefined for 0.
189 return 32;
190 }
191 return CompilerIntrinsics::CountTrailingZeros(value);
192 }
193 inline int CountTrailingZeros(uint64_t value) {
194 if (value == 0) {
195 // The result of the intrinsics is undefined for 0.
196 return 64;
197 }
198 return CompilerIntrinsics::CountTrailingZeros(value);
199 }
200 inline int CountTrailingZeros(uint64_t value, int width) {
201 ASSERT((width == 32) || (width == 64));
202 if (width == 32) {
203 return CountTrailingZeros(static_cast<uint32_t>(value));
204 } else {
205 return CountTrailingZeros(static_cast<uint64_t>(value));
206 }
207 }
208
209 inline int CountLeadingZeros(uint32_t value) {
210 if (value == 0) {
211 // The result of the intrinsics is undefined for 0.
212 return 32;
213 }
214 return CompilerIntrinsics::CountLeadingZeros(value);
215 }
216 inline int CountLeadingZeros(uint64_t value) {
217 if (value == 0) {
218 // The result of the intrinsics is undefined for 0.
219 return 64;
220 }
221 return CompilerIntrinsics::CountLeadingZeros(value);
222 }
223 inline int CountLeadingZeros(uint64_t value, int width) {
224 ASSERT((width == 32) || (width == 64));
225 if (width == 32) {
226 return CountLeadingZeros(static_cast<uint32_t>(value));
227 } else {
228 return CountLeadingZeros(static_cast<uint64_t>(value));
229 }
230 }
231
232 inline int CountRedundantLeadingSignBits(int32_t value) {
233 return CompilerIntrinsics::CountRedundantLeadingSignBits(value);
234 }
235 inline int CountRedundantLeadingSignBits(int64_t value) {
236 return CompilerIntrinsics::CountRedundantLeadingSignBits(value);
237 }
238 inline int CountRedundantLeadingSignBits(int64_t value, int width) {
239 ASSERT((width == 32) || (width == 64));
240 if (width == 32) {
241 return CountRedundantLeadingSignBits(static_cast<int32_t>(value));
242 } else {
243 return CountRedundantLeadingSignBits(static_cast<int64_t>(value));
244 }
245 }
246
247 inline int CountSetBits(uint32_t value) {
248 return CompilerIntrinsics::CountSetBits(value);
249 }
250 inline int CountSetBits(uint64_t value) {
251 return CompilerIntrinsics::CountSetBits(value);
252 }
253 inline int CountSetBits(uint64_t value, int width) {
254 ASSERT((width == 32) || (width == 64));
255 if (width == 32) {
256 return CountSetBits(static_cast<uint32_t>(value));
257 } else {
258 return CountSetBits(static_cast<uint64_t>(value));
259 }
260 }
261
262
92 } } // namespace v8::internal 263 } } // namespace v8::internal
93 264
94 #endif // V8_COMPILER_INTRINSICS_H_ 265 #endif // V8_COMPILER_INTRINSICS_H_
OLDNEW
« no previous file with comments | « src/a64/utils-a64.cc ('k') | src/compiler-intrinsics.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698