X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fadt%2Fbitfiddle.h;h=e01eea3ac3fe8b404f0ebdd87c3933b0e48197b8;hb=83909ad3889884e223dcab09fddc3c77410ac15c;hp=d51b40552800b6851a712bba833690503a0b33dc;hpb=ed68ef335c85f51d542de75a52111527269860ea;p=libfirm diff --git a/ir/adt/bitfiddle.h b/ir/adt/bitfiddle.h index d51b40552..e01eea3ac 100644 --- a/ir/adt/bitfiddle.h +++ b/ir/adt/bitfiddle.h @@ -10,10 +10,41 @@ #ifndef __FIRM_HACKDEL_H #define __FIRM_HACKDEL_H +#include + #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