]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
New file m_compiler.c
authorFlorian Krohm <florian@eich-krohm.de>
Wed, 29 Oct 2014 08:21:18 +0000 (08:21 +0000)
committerFlorian Krohm <florian@eich-krohm.de>
Wed, 29 Oct 2014 08:21:18 +0000 (08:21 +0000)
Provides implementations of __builtin_popcount/clz/ctz which some
older GCCs do not provide.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14673

NEWS
configure.ac
coregrind/Makefile.am
coregrind/m_compiler.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 45197db26b96ed396bc3507e8bdef72bdc8660c5..2e1e0abccb063f6d10cabb6e20964396db0322cd 100644 (file)
--- 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)
index 06b9709329ebeaea4806ec4fb7c262696d732908..55f0b462681bf101267ce583d085501d0b9ebe62 100644 (file)
@@ -1425,7 +1425,6 @@ AC_DEFINE([HAVE_EVENTFD_READ], 1,
 AC_MSG_RESULT([no])
 ])
 
-
 # Check whether compiler can process #include <thread> without errors
 # clang 3.3 cannot process <thread> 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])
index 0d5bec9908cf4f6d29d0849f6634122ffa1b09f0..7fb2618165d365397cf496ead68f14788b467be5 100644 (file)
@@ -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 (file)
index 0000000..f51cd63
--- /dev/null
@@ -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                                                          ---*/
+/*--------------------------------------------------------------------*/
+