becopyheur4: Clean up co_mst_irn_init().
[libfirm] / ir / adt / bitfiddle.h
index 29f042a..b3f1f1c 100644 (file)
@@ -1,20 +1,6 @@
 /*
- * Copyrigth (C) 1995-2007 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
  * @date    28.9.2004
  * @brief   Functions from hackers delight.
  * @author  Sebastian Hack, Matthias Braun
- * @version $Id$
  */
 #ifndef FIRM_ADT_BITFIDDLE_H
 #define FIRM_ADT_BITFIDDLE_H
 
+#include "compiler.h"
+
 #include <limits.h>
 #include <assert.h>
-#include "util.h"
 
 /* some functions here assume ints are 32 bit wide */
 #define HACKDEL_WORDSIZE 32
@@ -44,8 +30,7 @@ COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
  *
  * @note See hacker's delight, page 27.
  */
-static INLINE __attribute__((const))
-int add_saturated(int x, int y)
+static inline int add_saturated(int x, int y)
 {
        int sum      = x + y;
        /*
@@ -73,14 +58,18 @@ int add_saturated(int x, int y)
  * @param x A 32-bit word.
  * @return The number of bits set in x.
  */
-static INLINE __attribute__((const))
-unsigned popcnt(unsigned x) {
+static inline unsigned popcount(unsigned x)
+{
+#if defined(__GNUC__) && __GNUC__ >= 4
+       return __builtin_popcount(x);
+#else
        x -= ((x >> 1) & 0x55555555);
        x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
        x = (x + (x >> 4)) & 0x0f0f0f0f;
        x += x >> 8;
        x += x >> 16;
        return x & 0x3f;
+#endif
 }
 
 /**
@@ -88,24 +77,22 @@ unsigned popcnt(unsigned x) {
  * @param x The word.
  * @return The number of leading (from the most significant bit) zeros.
  */
-static INLINE __attribute__((const))
-unsigned nlz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
-       unsigned res;
+static inline unsigned nlz(unsigned x)
+{
+#if defined(__GNUC__) && __GNUC__ >= 4
        if(x == 0)
                return 32;
-
-       __asm__("bsrl %1,%0"
-                       : "=r" (res)
-                       : "r" (x));
-       return 31 - res;
+       return __builtin_clz(x);
 #else
-       x |= x >> 1;
-       x |= x >> 2;
-       x |= x >> 4;
-       x |= x >> 8;
-       x |= x >> 16;
-       return popcnt(~x);
+   unsigned y;
+   int n = 32;
+
+   y = x >>16;  if (y != 0) { n -= 16;  x = y; }
+   y = x >> 8;  if (y != 0) { n -=  8;  x = y; }
+   y = x >> 4;  if (y != 0) { n -=  4;  x = y; }
+   y = x >> 2;  if (y != 0) { n -=  2;  x = y; }
+   y = x >> 1;  if (y != 0) return n - 2;
+   return n - x;
 #endif
 }
 
@@ -114,17 +101,12 @@ unsigned nlz(unsigned x) {
  * @param x The word.
  * @return The number of trailing zeros.
  */
-static INLINE __attribute__((const))
-unsigned ntz(unsigned x) {
-#ifdef USE_X86_ASSEMBLY
-       unsigned res;
+static inline unsigned ntz(unsigned x)
+{
+#if defined(__GNUC__) && __GNUC__ >= 4
        if(x == 0)
                return 32;
-
-       __asm__("bsfl %1,%0"
-                       : "=r" (res)
-                       : "r" (x));
-       return  res;
+       return __builtin_ctz(x);
 #else
        return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
 #endif
@@ -158,10 +140,9 @@ unsigned ntz(unsigned x) {
  * Returns the biggest power of 2 that is equal or smaller than @p x
  * (see hackers delight power-of-2 boundaries, page 48)
  */
-static INLINE __attribute__((const))
-unsigned floor_po2(unsigned x)
+static inline unsigned floor_po2(unsigned x)
 {
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+#if defined(__GNUC__) && __GNUC__ >= 4 // in this case nlz is fast
        if(x == 0)
                return 0;
        // note that x != 0 here, so nlz(x) < 32!
@@ -181,14 +162,13 @@ unsigned floor_po2(unsigned x)
  * @remark x has to be <= 0x8000000 of course
  * @note see hackers delight power-of-2 boundaries, page 48
  */
-static INLINE __attribute__((const))
-unsigned ceil_po2(unsigned x)
+static inline unsigned ceil_po2(unsigned x)
 {
        if(x == 0)
                return 0;
        assert(x < (1U << 31));
 
-#ifdef USE_X86_ASSEMBLY // in this case nlz is fast
+#if defined(__GNUC__) && __GNUC__ >= 4 // in this case nlz is fast
        // note that x != 0 here!
        return 0x80000000U >> (nlz(x-1) - 1);
 #else
@@ -205,8 +185,7 @@ unsigned ceil_po2(unsigned x)
 /**
  * Tests whether @p x is a power of 2
  */
-static INLINE __attribute__((const))
-int is_po2(unsigned x)
+static inline int is_po2(unsigned x)
 {
        return (x & (x-1)) == 0;
 }