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
50UInt
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
62UInt
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
81UInt
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
95UInt
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
117UInt
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
130UInt
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
149void *
150__intel_memcpy(void *dest, const void *src, SizeT sz)
151{
152   return VG_(memcpy)( dest, src, sz );
153}
154
155void *
156__intel_mic_avx512f_memcpy(void *dest, const void *src, SizeT sz)
157{
158   return VG_(memcpy)( dest, src, sz );
159}
160
161void *
162__intel_new_memcpy(void *dest, const void *src, SizeT sz)
163{
164   return VG_(memcpy)( dest, src, sz );
165}
166
167void *
168__intel_ssse3_memcpy(void *dest, const void *src, SizeT sz)
169{
170   return VG_(memcpy)( dest, src, sz );
171}
172
173void *
174__intel_ssse3_rep_memcpy(void *dest, const void *src, SizeT sz)
175{
176   return VG_(memcpy)( dest, src, sz );
177}
178
179void *
180_intel_fast_memcpy(void *dest, const void *src, SizeT sz)
181{
182   return VG_(memcpy)( dest, src, sz );
183}
184
185void *
186__intel_lrb_memcpy(void *dest, const void *src, SizeT sz)
187{
188   return VG_(memcpy)( dest, src, sz );
189}
190
191void *
192__intel_memset(void *dest, int value, SizeT num)
193{
194   return VG_(memset)( dest, value, num );
195}
196
197void *
198__intel_new_memset(void *dest, int value, SizeT num)
199{
200   return VG_(memset)( dest, value, num );
201}
202
203void *
204__intel_mic_avx512f_memset(void *dest, int value, SizeT num)
205{
206   return VG_(memset)( dest, value, num );
207}
208
209void *
210__intel_lrb_memset(void *dest, int value, SizeT num)
211{
212   return VG_(memset)( dest, value, num );
213}
214
215void *
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
228void __ubsan_handle_type_mismatch ( void );
229void __ubsan_handle_type_mismatch ( void )
230{
231   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
232   vg_assert(0);
233}
234
235void __ubsan_handle_mul_overflow ( void );
236void __ubsan_handle_mul_overflow ( void )
237{
238   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
239   vg_assert(0);
240}
241
242void __ubsan_handle_add_overflow ( void );
243void __ubsan_handle_add_overflow ( void )
244{
245   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
246   vg_assert(0);
247}
248
249void __ubsan_handle_sub_overflow ( void );
250void __ubsan_handle_sub_overflow ( void )
251{
252   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
253   vg_assert(0);
254}
255
256void __ubsan_handle_divrem_overflow ( void );
257void __ubsan_handle_divrem_overflow ( void )
258{
259   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
260   vg_assert(0);
261}
262
263void __ubsan_handle_negate_overflow ( void );
264void __ubsan_handle_negate_overflow ( void )
265{
266   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
267   vg_assert(0);
268}
269
270void __ubsan_handle_out_of_bounds ( void );
271void __ubsan_handle_out_of_bounds ( void )
272{
273   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
274   vg_assert(0);
275}
276
277void __ubsan_handle_shift_out_of_bounds ( void );
278void __ubsan_handle_shift_out_of_bounds ( void )
279{
280   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
281   vg_assert(0);
282}
283
284void __ubsan_handle_vla_bound_not_positive ( void );
285void __ubsan_handle_vla_bound_not_positive ( void )
286{
287   VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
288   vg_assert(0);
289}
290
291void __ubsan_handle_nonnull_arg ( void );
292void __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