From: Florian Krohm Date: Wed, 29 Oct 2014 08:21:18 +0000 (+0000) Subject: New file m_compiler.c X-Git-Tag: svn/VALGRIND_3_11_0~875 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=489cc7d5e0c0b98aa6136365f86fd99366dc18fe;p=thirdparty%2Fvalgrind.git New file m_compiler.c Provides implementations of __builtin_popcount/clz/ctz which some older GCCs do not provide. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14673 --- diff --git a/NEWS b/NEWS index 45197db26b..2e1e0abccb 100644 --- a/NEWS +++ b/NEWS @@ -53,6 +53,8 @@ where XXXXXX is the bug number as listed below. 340430 Fix some grammatical weirdness in the manual. n-i-bz Old STABS code is still being compiled, but never used. Remove it. n-i-bz Fix compilation on distros with glibc < 2.5 +n-i-bz Provide implementations of certain compiler builtins to support + compilers who may not provide those Release 3.10.0 (10 September 2014) diff --git a/configure.ac b/configure.ac index 06b9709329..55f0b46268 100644 --- a/configure.ac +++ b/configure.ac @@ -1425,7 +1425,6 @@ AC_DEFINE([HAVE_EVENTFD_READ], 1, AC_MSG_RESULT([no]) ]) - # Check whether compiler can process #include without errors # clang 3.3 cannot process from e.g. # gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 @@ -2668,6 +2667,48 @@ CFLAGS=$safe_CFLAGS AM_CONDITIONAL([HAVE_OPENMP], [test x$ac_have_openmp = xyes]) +# Check for __builtin_popcount +AC_MSG_CHECKING([for __builtin_popcount()]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +]], [[ + __builtin_popcount(2); + return 0; +]])], [ +AC_MSG_RESULT([yes]) +AC_DEFINE([HAVE_BUILTIN_POPCOUT], 1, + [Define to 1 if compiler provides __builtin_popcount().]) +], [ +AC_MSG_RESULT([no]) +]) + +# Check for __builtin_clz +AC_MSG_CHECKING([for __builtin_clz()]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +]], [[ + __builtin_clz(2); + return 0; +]])], [ +AC_MSG_RESULT([yes]) +AC_DEFINE([HAVE_BUILTIN_CLZ], 1, + [Define to 1 if compiler provides __builtin_clz().]) +], [ +AC_MSG_RESULT([no]) +]) + +# Check for __builtin_ctz +AC_MSG_CHECKING([for __builtin_ctz()]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +]], [[ + __builtin_ctz(2); + return 0; +]])], [ +AC_MSG_RESULT([yes]) +AC_DEFINE([HAVE_BUILTIN_CTZ], 1, + [Define to 1 if compiler provides __builtin_ctz().]) +], [ +AC_MSG_RESULT([no]) +]) + # does this compiler have built-in functions for atomic memory access for the # primary target ? AC_MSG_CHECKING([if gcc supports __sync_add_and_fetch for the primary target]) diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 0d5bec9908..7fb2618165 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -213,6 +213,7 @@ noinst_HEADERS = \ pub_core_wordfm.h \ pub_core_xarray.h \ m_aspacemgr/priv_aspacemgr.h \ + m_compiler.c \ m_debuginfo/priv_misc.h \ m_debuginfo/priv_storage.h \ m_debuginfo/priv_tytypes.h \ diff --git a/coregrind/m_compiler.c b/coregrind/m_compiler.c new file mode 100644 index 0000000000..f51cd6316f --- /dev/null +++ b/coregrind/m_compiler.c @@ -0,0 +1,144 @@ +/* -*- mode: C; c-basic-offset: 3; -*- */ + +/*--------------------------------------------------------------------*/ +/*--- Compiler specific stuff. m_compiler.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2014-2014 Florian Krohm + florian@eich-krohm.de + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* Currently, this file provides definitions for builtins that not all + compilers or compiler versions provide. + + Missing builtins are rare. Therefore, no attempt has been made to + provide efficient implementations. + */ + +#include "config.h" +#include "pub_core_basics.h" + +#ifndef HAVE_BUILTIN_POPCOUT + +/* From the GCC documentation: + Returns the number of 1-bits in x. */ + +UInt +__builtin_popcount(UInt x) +{ + UInt i, count = 0; + + for (i = 0; i < 32; ++i) { + count += x & 1; + x >>= 1; + } + return count; +} + +UInt +__builtin_popcountll(ULong x) +{ + UInt i, count = 0; + + for (i = 0; i < 64; ++i) { + count += x & 1; + x >>= 1; + } + return count; +} +#endif + +#ifndef HAVE_BUILTIN_CLZ + +/* From the GCC documentation: + Returns the number of leading 0-bits in x, starting at the most + significant position. If x is 0, the result is undefined. */ + +UInt +__builtin_clz(UInt x) +{ + UInt count = 32; + UInt y; + + y = x >> 16; if (y != 0) { count -= 16; x = y; } + y = x >> 8; if (y != 0) { count -= 8; x = y; } + y = x >> 4; if (y != 0) { count -= 4; x = y; } + y = x >> 2; if (y != 0) { count -= 2; x = y; } + y = x >> 1; if (y != 0) return count - 2; + return count - x; +} + +UInt +__builtin_clzll(ULong x) +{ + UInt count = 64; + ULong y; + + y = x >> 32; if (y != 0) { count -= 32; x = y; } + y = x >> 16; if (y != 0) { count -= 16; x = y; } + y = x >> 8; if (y != 0) { count -= 8; x = y; } + y = x >> 4; if (y != 0) { count -= 4; x = y; } + y = x >> 2; if (y != 0) { count -= 2; x = y; } + y = x >> 1; if (y != 0) return count - 2; + return count - x; +} +#endif + +#ifndef HAVE_BUILTIN_CTZ + +/* From the GCC documentation: + Returns the number of trailing 0-bits in x, starting at the least + significant bit position. If x is 0, the result is undefined. */ + +UInt +__builtin_ctz(UInt x) +{ + UInt i, count = 0; + + for (i = 0; i < 32; ++i) { + if (x & 1) break; + ++count; + x >>= 1; + } + return count; +} + +UInt +__builtin_ctzll(ULong x) +{ + UInt i, count = 0; + + for (i = 0; i < 64; ++i) { + if (x & 1) break; + ++count; + x >>= 1; + } + return count; +} +#endif + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ +