Whitespace fixes.
[cparser] / adt / bitfiddle.h
1 /*
2  * This file is part of cparser.
3  * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18  * 02111-1307, USA.
19  */
20
21 /**
22  * @file
23  * @date    28.9.2004
24  * @brief   Functions from hackers delight.
25  * @author  Sebastian Hack, Matthias Braun
26  * @version $Id$
27  */
28 #ifndef _FIRM_BITFIDDLE_H_
29 #define _FIRM_BITFIDDLE_H_
30
31 #include <limits.h>
32 #include "util.h"
33
34 /* some functions here assume ints are 32 bit wide */
35 #define HACKDEL_WORDSIZE 32
36 COMPILETIME_ASSERT(sizeof(unsigned) == 4, unsignedsize)
37 COMPILETIME_ASSERT(UINT_MAX == 4294967295U, uintmax)
38
39 /**
40  * Add saturated.
41  * @param x Summand 1.
42  * @param y Summand 2.
43  * @return x + y or INT_MAX/INT_MIN if an overflow occurred and x,y was positive/negative.
44  *
45  * @note See hacker's delight, page 27.
46  */
47 static inline __attribute__((const))
48 int add_saturated(int x, int y)
49 {
50         int sum      = x + y;
51         /*
52                 An overflow occurs, if the sign of the both summands is equal
53                 and the one of the sum is different from the summand's one.
54                 The sign bit is 1, if an overflow occurred, 0 otherwise.
55                 int overflow = ~(x ^ y) & (sum ^ x);
56         */
57         int overflow = (x ^ sum) & (y ^ sum);
58
59         /*
60                 The infinity to use.
61                 Make a mask of the sign bit of x and y (they are the same if an
62                 overflow occurred).
63                 INT_MIN == ~INT_MAX, so if the sign was negative, INT_MAX becomes
64                 INT_MIN.
65         */
66         int inf = (x >> (sizeof(x) * 8 - 1)) ^ INT_MAX;
67
68         return overflow < 0 ? inf : sum;
69 }
70
71 /**
72  * Compute the count of set bits in a 32-bit word.
73  * @param x A 32-bit word.
74  * @return The number of bits set in x.
75  */
76 static inline __attribute__((const))
77 unsigned popcnt(unsigned x) {
78         x -= ((x >> 1) & 0x55555555);
79         x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
80         x = (x + (x >> 4)) & 0x0f0f0f0f;
81         x += x >> 8;
82         x += x >> 16;
83         return x & 0x3f;
84 }
85
86 /**
87  * Compute the number of leading zeros in a word.
88  * @param x The word.
89  * @return The number of leading (from the most significant bit) zeros.
90  */
91 static inline __attribute__((const))
92 unsigned nlz(unsigned x) {
93 #ifdef USE_X86_ASSEMBLY
94         unsigned res;
95         if(x == 0)
96                 return 32;
97
98         __asm__("bsrl %1,%0"
99                         : "=r" (res)
100                         : "r" (x));
101         return 31 - res;
102 #else
103         x |= x >> 1;
104         x |= x >> 2;
105         x |= x >> 4;
106         x |= x >> 8;
107         x |= x >> 16;
108         return popcnt(~x);
109 #endif
110 }
111
112 /**
113  * Compute the number of trailing zeros in a word.
114  * @param x The word.
115  * @return The number of trailing zeros.
116  */
117 static inline __attribute__((const))
118 unsigned ntz(unsigned x) {
119 #ifdef USE_X86_ASSEMBLY
120         unsigned res;
121         if(x == 0)
122                 return 32;
123
124         __asm__("bsfl %1,%0"
125                         : "=r" (res)
126                         : "r" (x));
127         return  res;
128 #else
129         return HACKDEL_WORDSIZE - nlz(~x & (x - 1));
130 #endif
131 }
132
133 /**
134  * Compute the greatest power of 2 smaller or equal to a value.
135  * This is also known as the binary logarithm.
136  * @param x The value.
137  * @return The power of two.
138  */
139 #define log2_floor(x) (HACKDEL_WORDSIZE - 1 - nlz(x))
140
141 /**
142  * Compute the smallest power of 2 greater or equal to a value.
143  * This is also known as the binary logarithm.
144  * @param x The value.
145  * @return The power of two.
146  */
147 #define log2_ceil(x) (HACKDEL_WORDSIZE - nlz((x) - 1))
148
149 /**
150  * Round up to the next multiple of a power of two.
151  * @param x A value.
152  * @param pot A power of two.
153  * @return x rounded up to the next multiple of pot.
154  */
155 #define round_up2(x,pot) (((x) + ((pot) - 1)) & (~((pot) - 1)))
156
157 /**
158  * Returns the biggest power of 2 that is equal or smaller than @p x
159  * (see hackers delight power-of-2 boundaries, page 48)
160  */
161 static inline __attribute__((const))
162 unsigned floor_po2(unsigned x)
163 {
164 #ifdef USE_X86_ASSEMBLY // in this case nlz is fast
165         if(x == 0)
166                 return 0;
167         // note that x != 0 here, so nlz(x) < 32!
168         return 0x80000000U >> nlz(x);
169 #else
170         x |= x >> 1;
171         x |= x >> 2;
172         x |= x >> 4;
173         x |= x >> 8;
174         x |= x >> 16;
175         return x - (x >> 1);
176 #endif
177 }
178
179 /**
180  * Returns the smallest power of 2 that is equal or greater than x
181  * @remark x has to be <= 0x8000000 of course
182  * @note see hackers delight power-of-2 boundaries, page 48
183  */
184 static inline __attribute__((const))
185 unsigned ceil_po2(unsigned x)
186 {
187         if(x == 0)
188                 return 0;
189         assert(x < (1U << 31));
190
191 #ifdef USE_X86_ASSEMBLY // in this case nlz is fast
192         // note that x != 0 here!
193         return 0x80000000U >> (nlz(x-1) - 1);
194 #else
195         x = x - 1;
196         x |= x >> 1;
197         x |= x >> 2;
198         x |= x >> 4;
199         x |= x >> 8;
200         x |= x >> 16;
201         return x + 1;
202 #endif
203 }
204
205 /**
206  * Tests whether @p x is a power of 2
207  */
208 static inline __attribute__((const))
209 int is_po2(unsigned x)
210 {
211         return (x & (x-1)) == 0;
212 }
213
214 #endif