Home | History | Annotate | Download | only in coregrind
      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 (at) 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
     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
     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
     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
     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
    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
    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 *
    150 __intel_memcpy(void *dest, const void *src, SizeT sz)
    151 {
    152    return VG_(memcpy)( dest, src, sz );
    153 }
    154 
    155 void *
    156 __intel_mic_avx512f_memcpy(void *dest, const void *src, SizeT sz)
    157 {
    158    return VG_(memcpy)( dest, src, sz );
    159 }
    160 
    161 void *
    162 __intel_new_memcpy(void *dest, const void *src, SizeT sz)
    163 {
    164    return VG_(memcpy)( dest, src, sz );
    165 }
    166 
    167 void *
    168 __intel_ssse3_memcpy(void *dest, const void *src, SizeT sz)
    169 {
    170    return VG_(memcpy)( dest, src, sz );
    171 }
    172 
    173 void *
    174 __intel_ssse3_rep_memcpy(void *dest, const void *src, SizeT sz)
    175 {
    176    return VG_(memcpy)( dest, src, sz );
    177 }
    178 
    179 void *
    180 _intel_fast_memcpy(void *dest, const void *src, SizeT sz)
    181 {
    182    return VG_(memcpy)( dest, src, sz );
    183 }
    184 
    185 void *
    186 __intel_lrb_memcpy(void *dest, const void *src, SizeT sz)
    187 {
    188    return VG_(memcpy)( dest, src, sz );
    189 }
    190 
    191 void *
    192 __intel_memset(void *dest, int value, SizeT num)
    193 {
    194    return VG_(memset)( dest, value, num );
    195 }
    196 
    197 void *
    198 __intel_new_memset(void *dest, int value, SizeT num)
    199 {
    200    return VG_(memset)( dest, value, num );
    201 }
    202 
    203 void *
    204 __intel_mic_avx512f_memset(void *dest, int value, SizeT num)
    205 {
    206    return VG_(memset)( dest, value, num );
    207 }
    208 
    209 void *
    210 __intel_lrb_memset(void *dest, int value, SizeT num)
    211 {
    212    return VG_(memset)( dest, value, num );
    213 }
    214 
    215 void *
    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 );
    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 );
    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 );
    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 );
    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 );
    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 );
    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 );
    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 );
    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 );
    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 );
    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