1 /* -*- mode: C; c-basic-offset: 3; -*- */
2
3 /*--------------------------------------------------------------------*/
4 /*--- Compiler specific stuff. m_compiler.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2014-2017 Florian Krohm
12 florian@eich-krohm.de
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30 */
31
32 /* Currently, this file provides definitions for builtins that not all
33 compilers or compiler versions provide.
34
35 Missing builtins are rare. Therefore, no attempt has been made to
36 provide efficient implementations.
37 */
38
39 #include "config.h"
40 #include "pub_core_basics.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_debuglog.h"
44
45 #ifndef HAVE_BUILTIN_POPCOUT
46
47 /* From the GCC documentation:
48 Returns the number of 1-bits in x. */
49
50 UInt
__builtin_popcount(UInt x)51 __builtin_popcount(UInt x)
52 {
53 UInt i, count = 0;
54
55 for (i = 0; i < 32; ++i) {
56 count += x & 1;
57 x >>= 1;
58 }
59 return count;
60 }
61
62 UInt
__builtin_popcountll(ULong x)63 __builtin_popcountll(ULong x)
64 {
65 UInt i, count = 0;
66
67 for (i = 0; i < 64; ++i) {
68 count += x & 1;
69 x >>= 1;
70 }
71 return count;
72 }
73 #endif
74
75 #ifndef HAVE_BUILTIN_CLZ
76
77 /* From the GCC documentation:
78 Returns the number of leading 0-bits in x, starting at the most
79 significant position. If x is 0, the result is undefined. */
80
81 UInt
__builtin_clz(UInt x)82 __builtin_clz(UInt x)
83 {
84 UInt count = 32;
85 UInt y;
86
87 y = x >> 16; if (y != 0) { count -= 16; x = y; }
88 y = x >> 8; if (y != 0) { count -= 8; x = y; }
89 y = x >> 4; if (y != 0) { count -= 4; x = y; }
90 y = x >> 2; if (y != 0) { count -= 2; x = y; }
91 y = x >> 1; if (y != 0) return count - 2;
92 return count - x;
93 }
94
95 UInt
__builtin_clzll(ULong x)96 __builtin_clzll(ULong x)
97 {
98 UInt count = 64;
99 ULong y;
100
101 y = x >> 32; if (y != 0) { count -= 32; x = y; }
102 y = x >> 16; if (y != 0) { count -= 16; x = y; }
103 y = x >> 8; if (y != 0) { count -= 8; x = y; }
104 y = x >> 4; if (y != 0) { count -= 4; x = y; }
105 y = x >> 2; if (y != 0) { count -= 2; x = y; }
106 y = x >> 1; if (y != 0) return count - 2;
107 return count - x;
108 }
109 #endif
110
111 #ifndef HAVE_BUILTIN_CTZ
112
113 /* From the GCC documentation:
114 Returns the number of trailing 0-bits in x, starting at the least
115 significant bit position. If x is 0, the result is undefined. */
116
117 UInt
__builtin_ctz(UInt x)118 __builtin_ctz(UInt x)
119 {
120 UInt i, count = 0;
121
122 for (i = 0; i < 32; ++i) {
123 if (x & 1) break;
124 ++count;
125 x >>= 1;
126 }
127 return count;
128 }
129
130 UInt
__builtin_ctzll(ULong x)131 __builtin_ctzll(ULong x)
132 {
133 UInt i, count = 0;
134
135 for (i = 0; i < 64; ++i) {
136 if (x & 1) break;
137 ++count;
138 x >>= 1;
139 }
140 return count;
141 }
142 #endif
143
144
145 #ifdef __INTEL_COMPILER
146
147 /* Provide certain functions Intel's ICC compiler expects to be defined. */
148
149 void *
__intel_memcpy(void * dest,const void * src,SizeT sz)150 __intel_memcpy(void *dest, const void *src, SizeT sz)
151 {
152 return VG_(memcpy)( dest, src, sz );
153 }
154
155 void *
__intel_mic_avx512f_memcpy(void * dest,const void * src,SizeT sz)156 __intel_mic_avx512f_memcpy(void *dest, const void *src, SizeT sz)
157 {
158 return VG_(memcpy)( dest, src, sz );
159 }
160
161 void *
__intel_new_memcpy(void * dest,const void * src,SizeT sz)162 __intel_new_memcpy(void *dest, const void *src, SizeT sz)
163 {
164 return VG_(memcpy)( dest, src, sz );
165 }
166
167 void *
__intel_ssse3_memcpy(void * dest,const void * src,SizeT sz)168 __intel_ssse3_memcpy(void *dest, const void *src, SizeT sz)
169 {
170 return VG_(memcpy)( dest, src, sz );
171 }
172
173 void *
__intel_ssse3_rep_memcpy(void * dest,const void * src,SizeT sz)174 __intel_ssse3_rep_memcpy(void *dest, const void *src, SizeT sz)
175 {
176 return VG_(memcpy)( dest, src, sz );
177 }
178
179 void *
_intel_fast_memcpy(void * dest,const void * src,SizeT sz)180 _intel_fast_memcpy(void *dest, const void *src, SizeT sz)
181 {
182 return VG_(memcpy)( dest, src, sz );
183 }
184
185 void *
__intel_lrb_memcpy(void * dest,const void * src,SizeT sz)186 __intel_lrb_memcpy(void *dest, const void *src, SizeT sz)
187 {
188 return VG_(memcpy)( dest, src, sz );
189 }
190
191 void *
__intel_memset(void * dest,int value,SizeT num)192 __intel_memset(void *dest, int value, SizeT num)
193 {
194 return VG_(memset)( dest, value, num );
195 }
196
197 void *
__intel_new_memset(void * dest,int value,SizeT num)198 __intel_new_memset(void *dest, int value, SizeT num)
199 {
200 return VG_(memset)( dest, value, num );
201 }
202
203 void *
__intel_mic_avx512f_memset(void * dest,int value,SizeT num)204 __intel_mic_avx512f_memset(void *dest, int value, SizeT num)
205 {
206 return VG_(memset)( dest, value, num );
207 }
208
209 void *
__intel_lrb_memset(void * dest,int value,SizeT num)210 __intel_lrb_memset(void *dest, int value, SizeT num)
211 {
212 return VG_(memset)( dest, value, num );
213 }
214
215 void *
_intel_fast_memset(void * dest,int value,SizeT num)216 _intel_fast_memset(void *dest, int value, SizeT num)
217 {
218 return VG_(memset)( dest, value, num );
219 }
220
221 #endif
222
223
224 /*====================================================================*/
225 /*=== gcc -fsanitize=undefined helper function support ===*/
226 /*====================================================================*/
227
228 void __ubsan_handle_type_mismatch ( void );
__ubsan_handle_type_mismatch(void)229 void __ubsan_handle_type_mismatch ( void )
230 {
231 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
232 vg_assert(0);
233 }
234
235 void __ubsan_handle_mul_overflow ( void );
__ubsan_handle_mul_overflow(void)236 void __ubsan_handle_mul_overflow ( void )
237 {
238 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
239 vg_assert(0);
240 }
241
242 void __ubsan_handle_add_overflow ( void );
__ubsan_handle_add_overflow(void)243 void __ubsan_handle_add_overflow ( void )
244 {
245 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
246 vg_assert(0);
247 }
248
249 void __ubsan_handle_sub_overflow ( void );
__ubsan_handle_sub_overflow(void)250 void __ubsan_handle_sub_overflow ( void )
251 {
252 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
253 vg_assert(0);
254 }
255
256 void __ubsan_handle_divrem_overflow ( void );
__ubsan_handle_divrem_overflow(void)257 void __ubsan_handle_divrem_overflow ( void )
258 {
259 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
260 vg_assert(0);
261 }
262
263 void __ubsan_handle_negate_overflow ( void );
__ubsan_handle_negate_overflow(void)264 void __ubsan_handle_negate_overflow ( void )
265 {
266 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
267 vg_assert(0);
268 }
269
270 void __ubsan_handle_out_of_bounds ( void );
__ubsan_handle_out_of_bounds(void)271 void __ubsan_handle_out_of_bounds ( void )
272 {
273 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
274 vg_assert(0);
275 }
276
277 void __ubsan_handle_shift_out_of_bounds ( void );
__ubsan_handle_shift_out_of_bounds(void)278 void __ubsan_handle_shift_out_of_bounds ( void )
279 {
280 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
281 vg_assert(0);
282 }
283
284 void __ubsan_handle_vla_bound_not_positive ( void );
__ubsan_handle_vla_bound_not_positive(void)285 void __ubsan_handle_vla_bound_not_positive ( void )
286 {
287 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
288 vg_assert(0);
289 }
290
291 void __ubsan_handle_nonnull_arg ( void );
__ubsan_handle_nonnull_arg(void)292 void __ubsan_handle_nonnull_arg ( void )
293 {
294 VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
295 vg_assert(0);
296 }
297
298 /*--------------------------------------------------------------------*/
299 /*--- end ---*/
300 /*--------------------------------------------------------------------*/
301