removed double include
[libfirm] / ir / adt / bitfiddle.h
index bae8524..e01eea3 100644 (file)
 #ifndef __FIRM_HACKDEL_H
 #define __FIRM_HACKDEL_H
 
-#include "config.h"
+#include <limits.h>
+
+#include "firm_config.h"
 
 #define HACKDEL_WORDSIZE 32
 
+/**
+ * Add saturated.
+ * @param x Summand 1.
+ * @param y Summand 2.
+ * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
+ *
+ * @note See hacker's delight, page 27.
+ */
+static INLINE int add_saturated(int x, int y)
+{
+       int sum      = x + y;
+       /*
+               An overflow occurs, if the sign of the both summands is equal
+               and the one of the sum is different from the summand's one.
+               The sign bit is 1, if an overflow occurred, 0 otherwise.
+               int overflow = ~(x ^ y) & (sum ^ x);
+       */
+       int overflow = (x ^ sum) & (y ^ sum);
+
+       /*
+               The infinity to use.
+               Make a mask of the sign bit of x and y (they are the same if an overflow occurred).
+               INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes INT_MIN.
+       */
+       int inf      = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
+
+       return overflow < 0 ? inf : sum;
+}
+
 /**
  * Compute the count of set bits in a 32-bit word.
  * @param x A 32-bit word.
@@ -29,9 +60,9 @@ static INLINE unsigned popcnt(unsigned x) {
 }
 
 /**
- * Compute the number of leading zeroes in a word.
+ * Compute the number of leading zeros in a word.
  * @param x The word.
- * @return The number of leading (from the most significant bit) zeroes.
+ * @return The number of leading (from the most significant bit) zeros.
  */
 static INLINE unsigned nlz(unsigned x) {
   x |= x >> 1;
@@ -43,9 +74,9 @@ static INLINE unsigned nlz(unsigned x) {
 }
 
 /**
- * Compute the number of trailing zeroes in a word.
+ * Compute the number of trailing zeros in a word.
  * @param x The word.
- * @return The number of trailing zeroes.
+ * @return The number of trailing zeros.
  */
 #define ntz(x) (HACKDEL_WORDSIZE - nlz(~(x) & ((x) - 1)))
 
@@ -74,4 +105,5 @@ static INLINE unsigned nlz(unsigned x) {
 #define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
 
 
+
 #endif