diff options
author | Ivo van Doorn <IvDoorn@gmail.com> | 2008-06-03 16:45:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-14 12:17:54 -0400 |
commit | 9dad92b9ba49eaab72513d821ae43298bcf93b90 (patch) | |
tree | d2addafa1534616865c563cb0f71207a8a7cde33 /drivers/net/wireless | |
parent | 030352a9c7715780b2c01033ae9afe56249bb7cc (diff) |
rt2x00: Calculate register offset during compile time
By using __ffs() the register offsets were always calculated
at run-time which all FIELD32/FIELD16 definitions were builtin
constants. This means we can heavily optimize the register handling
by allowing GCC to do all the work during compilation.
Add some compile_ffs() macros to perform the calculation at
compile time. After this each rt2x00 module size is reduced
by ~2500 bytes. And the stack size of several functions is reduced
as well which further limits the number of rt2x00 results in
'make checkstack'.
v2: Merge GertJan's bugfix of patch [1/11] directly into this patch
instead of providing it as seperate patch.
v3: Add extra parentheses when bitshifting __x
Signed-off-by: Gertjan van Wingerde <gwingerde@kpnplanet.nl>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00reg.h | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 3f255df58b78..b0d27edcc330 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -130,40 +130,71 @@ struct rt2x00_field32 { | |||
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Power of two check, this will check | 132 | * Power of two check, this will check |
133 | * if the mask that has been given contains | 133 | * if the mask that has been given contains and contiguous set of bits. |
134 | * and contiguous set of bits. | 134 | * Note that we cannot use the is_power_of_2() function since this |
135 | * check must be done at compile-time. | ||
135 | */ | 136 | */ |
136 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) | 137 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) |
137 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) | 138 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) |
138 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) | 139 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) |
139 | 140 | ||
141 | /* | ||
142 | * Macro's to find first set bit in a variable. | ||
143 | * These macro's behaves the same as the __ffs() function with | ||
144 | * the most important difference that this is done during | ||
145 | * compile-time rather then run-time. | ||
146 | */ | ||
147 | #define compile_ffs2(__x) \ | ||
148 | ( ((__x) & 0x1) ? 0 : 1 ) | ||
149 | |||
150 | #define compile_ffs4(__x) \ | ||
151 | ( ((__x) & 0x3) ? \ | ||
152 | compile_ffs2(__x) : (compile_ffs2((__x) >> 2) + 2) ) | ||
153 | |||
154 | #define compile_ffs8(__x) \ | ||
155 | ( ((__x) & 0xf) ? \ | ||
156 | compile_ffs4(__x) : (compile_ffs4((__x) >> 4) + 4) ) | ||
157 | |||
158 | #define compile_ffs16(__x) \ | ||
159 | ( ((__x) & 0xff) ? \ | ||
160 | compile_ffs8(__x) : (compile_ffs8((__x) >> 8) + 8) ) | ||
161 | |||
162 | #define compile_ffs32(__x) \ | ||
163 | ( ((__x) & 0xffff) ? \ | ||
164 | compile_ffs16(__x) : (compile_ffs16((__x) >> 16) + 16) ) | ||
165 | |||
166 | /* | ||
167 | * This macro will check the requirements for the FIELD{8,16,32} macros | ||
168 | * The mask should be a constant non-zero contiguous set of bits which | ||
169 | * does not exceed the given typelimit. | ||
170 | */ | ||
171 | #define FIELD_CHECK(__mask, __type) \ | ||
172 | BUILD_BUG_ON(!__builtin_constant_p(__mask) || \ | ||
173 | !(__mask) || \ | ||
174 | !is_valid_mask(__mask) || \ | ||
175 | (__mask) != (__type)(__mask)) \ | ||
176 | |||
140 | #define FIELD8(__mask) \ | 177 | #define FIELD8(__mask) \ |
141 | ({ \ | 178 | ({ \ |
142 | BUILD_BUG_ON(!(__mask) || \ | 179 | FIELD_CHECK(__mask, u8); \ |
143 | !is_valid_mask(__mask) || \ | ||
144 | (__mask) != (u8)(__mask)); \ | ||
145 | (struct rt2x00_field8) { \ | 180 | (struct rt2x00_field8) { \ |
146 | __ffs(__mask), (__mask) \ | 181 | compile_ffs8(__mask), (__mask) \ |
147 | }; \ | 182 | }; \ |
148 | }) | 183 | }) |
149 | 184 | ||
150 | #define FIELD16(__mask) \ | 185 | #define FIELD16(__mask) \ |
151 | ({ \ | 186 | ({ \ |
152 | BUILD_BUG_ON(!(__mask) || \ | 187 | FIELD_CHECK(__mask, u16); \ |
153 | !is_valid_mask(__mask) || \ | ||
154 | (__mask) != (u16)(__mask));\ | ||
155 | (struct rt2x00_field16) { \ | 188 | (struct rt2x00_field16) { \ |
156 | __ffs(__mask), (__mask) \ | 189 | compile_ffs16(__mask), (__mask) \ |
157 | }; \ | 190 | }; \ |
158 | }) | 191 | }) |
159 | 192 | ||
160 | #define FIELD32(__mask) \ | 193 | #define FIELD32(__mask) \ |
161 | ({ \ | 194 | ({ \ |
162 | BUILD_BUG_ON(!(__mask) || \ | 195 | FIELD_CHECK(__mask, u32); \ |
163 | !is_valid_mask(__mask) || \ | ||
164 | (__mask) != (u32)(__mask));\ | ||
165 | (struct rt2x00_field32) { \ | 196 | (struct rt2x00_field32) { \ |
166 | __ffs(__mask), (__mask) \ | 197 | compile_ffs32(__mask), (__mask) \ |
167 | }; \ | 198 | }; \ |
168 | }) | 199 | }) |
169 | 200 | ||