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