Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / system / Wanderer / portable-include / aros / macros.h
blob3395ce3250190f26a1991f69670340c679cb30f6
1 #ifndef AROS_MACROS_H
2 #define AROS_MACROS_H
4 /*
5 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
6 $Id$
8 Desc: Miscellanous macros
9 Lang: english
12 #ifndef AROS_SYSTEM_H
13 # include <aros/system.h>
14 #endif
17 /* Reverse the bits in a byte */
18 #define AROS_SWAP_BITS_BYTE_GENERIC(_b) \
19 ({ \
20 UBYTE __aros_swap_tmp = _b, \
21 b = __aros_swap_tmp; \
23 b = ((b >> 1) & 0x55) | ((b << 1) & 0xaa); \
24 b = ((b >> 2) & 0x33) | ((b << 2) & 0xcc); \
25 ((b >> 4) & 0x0f) | ((b << 4) & 0xf0); \
28 /* Reverse the bits in a word */
29 #define AROS_SWAP_BITS_WORD_GENERIC(_w) \
30 ({ \
31 UWORD __aros_swap_tmp = _w, \
32 w = __aros_swap_tmp; \
34 w = ((w >> 1) & 0x5555) | ((w << 1) & 0xaaaa); \
35 w = ((w >> 2) & 0x3333) | ((w << 2) & 0xcccc); \
36 w = ((w >> 4) & 0x0f0f) | ((w << 4) & 0xf0f0); \
37 ((w >> 8) & 0x00ff) | ((w << 8) & 0xff00); \
40 /* Reverse the bits in a long */
41 #define AROS_SWAP_BITS_LONG_GENERIC(_l) \
42 ({ \
43 ULONG __aros_swap_tmp = _l, l = __aros_swap_tmp; \
45 l = ((l >> 1) & 0x55555555UL) | ((l << 1) & 0xaaaaaaaaUL); \
46 l = ((l >> 2) & 0x33333333UL) | ((l << 2) & 0xccccccccUL); \
47 l = ((l >> 4) & 0x0f0f0f0fUL) | ((l << 4) & 0xf0f0f0f0UL); \
48 l = ((l >> 8) & 0x00ff00ffUL) | ((l << 8) & 0xff00ff00UL); \
49 ((l >> 16) & 0x0000ffffUL) | ((l << 16) & 0xffff0000UL); \
52 /* Reverse the bits in a quad */
53 #define AROS_SWAP_BITS_QUAD_GENERIC(_q) \
54 ({ \
55 UQUAD __aros_swap_tmp = _q, q = __aros_swap_tmp; \
57 q = ((q >> 1) & 0x5555555555555555ULL) | ((q << 1) & 0xaaaaaaaaaaaaaaaaULL); \
58 q = ((q >> 2) & 0x3333333333333333ULL) | ((q << 2) & 0xccccccccccccccccULL); \
59 q = ((q >> 4) & 0x0f0f0f0f0f0f0f0fULL) | ((q << 4) & 0xf0f0f0f0f0f0f0f0ULL); \
60 q = ((q >> 8) & 0x00ff00ff00ff00ffULL) | ((q << 8) & 0xff00ff00ff00ff00ULL); \
61 q = ((q >> 16) & 0x0000ffff0000ffffULL) | ((q << 16) & 0xffff0000ffff0000ULL); \
62 ((q >> 32) & 0x00000000ffffffffULL) | ((q << 32) & 0xffffffff00000000ULL); \
65 /* Reverse the bytes in a word */
66 #define AROS_SWAP_BYTES_WORD_GENERIC(_w) \
67 ({ \
68 const UWORD __aros_swap_tmp = _w, \
69 w = __aros_swap_tmp; \
71 (UWORD)(((w >> 8) & 0x00FF) | ((w << 8) & 0xFF00)); \
74 /* Reverse the bytes in a long */
75 #define AROS_SWAP_BYTES_LONG_GENERIC(_l) \
76 ({ \
77 const ULONG __aros_swap_tmp = _l, \
78 l = __aros_swap_tmp; \
80 ((ULONG)AROS_SWAP_BYTES_WORD(l & 0xFFFF) << 16) | \
81 (AROS_SWAP_BYTES_WORD((l >> 16) & 0xFFFF)); \
84 /* Reverse the bytes in a quad */
85 #define AROS_SWAP_BYTES_QUAD_GENERIC(_q) \
86 ({ \
87 const UQUAD __aros_swap_tmp = _q, \
88 q = __aros_swap_tmp; \
90 ((UQUAD)AROS_SWAP_BYTES_LONG(q & 0xFFFFFFFFULL) << 32) | \
91 (AROS_SWAP_BYTES_LONG(q >> 32) & 0xFFFFFFFFULL); \
94 /* Reverse the words in a long */
95 #define AROS_SWAP_WORDS_LONG_GENERIC(_l) \
96 ({ \
97 const ULONG __aros_swap_tmp = _l, l = __aros_swap_tmp; \
99 (ULONG)(((l >> 16) & 0x0000FFFFUL) | ((l << 16) & 0xFFFF0000UL)); \
102 /* Reverse the words in a quad */
103 #define AROS_SWAP_WORDS_QUAD_GENERIC(_q) \
104 ({ \
105 const UQUAD __aros_swap_tmp = _q, q = __aros_swap_tmp; \
107 ((UQUAD)AROS_SWAP_WORDS_LONG(q & 0xFFFFFFFFULL) << 32) | \
108 (AROS_SWAP_WORDS_LONG(q >> 32) & 0xFFFFFFFFULL); \
111 /* Reverse the longs in a quad */
112 #define AROS_SWAP_LONGS_QUAD_GENERIC(_q) \
113 ({ \
114 const UQUAD __aros_swap_tmp = _q, q = __aros_swap_tmp; \
116 (UQUAD)(((q >> 32) & 0xFFFFFFFFULL) | ((q << 32) & 0xFFFFFFFF00000000ULL)); \
119 /* Use the CPU-specific definitions of the above macros, if they exist, but reuse
120 the generic macros in case the given value is a compile-time constant, because
121 the compiler will optimize things out for us. */
122 #if !defined(AROS_SWAP_BITS_BYTE_CPU)
123 # define AROS_SWAP_BITS_BYTE(b) AROS_SWAP_BITS_BYTE_GENERIC(b)
124 #elif defined(__GNUC__)
125 # define AROS_SWAP_BITS_BYTE(b) \
127 __builtin_constant_p(b) \
128 ? AROS_SWAP_BITS_BYTE_GENERIC(b) \
129 : AROS_SWAP_BITS_BYTE_CPU(b) \
131 #else
132 # define AROS_SWAP_BITS_BYTE(b) AROS_SWAP_BITS_BYTE_CPU(b)
133 #endif
135 #if !defined(AROS_SWAP_BITS_WORD_CPU)
136 # define AROS_SWAP_BITS_WORD(w) AROS_SWAP_BITS_WORD_GENERIC(w)
137 #elif defined(__GNUC__)
138 # define AROS_SWAP_BITS_WORD(w) \
140 __builtin_constant_p(w) \
141 ? AROS_SWAP_BITS_WORD_GENERIC(w) \
142 : AROS_SWAP_BITS_WORD_CPU(w) \
144 #else
145 # define AROS_SWAP_BITS_WORD(w) AROS_SWAP_BITS_WORD_CPU(w)
146 #endif
148 #if !defined(AROS_SWAP_BITS_LONG_CPU)
149 # define AROS_SWAP_BITS_LONG(l) AROS_SWAP_BITS_LONG_GENERIC(l)
150 #elif defined(__GNUC__)
151 # define AROS_SWAP_BITS_LONG(l) \
153 __builtin_constant_p(l) \
154 ? AROS_SWAP_BITS_LONG_GENERIC(l) \
155 : AROS_SWAP_BITS_LONG_CPU(l) \
157 #else
158 # define AROS_SWAP_BITS_LONG(l) AROS_SWAP_BITS_LONG_CPU(l)
159 #endif
161 #if !defined(AROS_SWAP_BITS_QUAD_CPU)
162 # define AROS_SWAP_BITS_QUAD(q) AROS_SWAP_BITS_QUAD_GENERIC(q)
163 #elif defined(__GNUC__)
164 # define AROS_SWAP_BITS_QUAD(q) \
166 __builtin_constant_p(q) \
167 ? AROS_SWAP_BITS_QUAD_GENERIC(q) \
168 : AROS_SWAP_BITS_QUAD_CPU(q) \
170 #else
171 # define AROS_SWAP_BITS_QUAD(q) AROS_SWAP_BITS_QUAD_CPU(q)
172 #endif
174 /* Just for consistency... */
175 #define AROS_SWAP_BYTES_BYTE(b) ((UBYTE)b)
176 #define AROS_SWAP_WORDS_WORD(w) ((ULONG)l)
177 #define AROS_SWAP_LONGS_LONG(l) ((UWORD)l)
178 #define AROS_SWAP_QUADS_QUAD(q) ((UQUAD)q)
180 #if !defined(AROS_SWAP_BYTES_WORD_CPU)
181 # define AROS_SWAP_BYTES_WORD(w) AROS_SWAP_BYTES_WORD_GENERIC(w)
182 #elif defined(__GNUC__)
183 # define AROS_SWAP_BYTES_WORD(w) \
185 __builtin_constant_p(w) \
186 ? AROS_SWAP_BYTES_WORD_GENERIC(w) \
187 : AROS_SWAP_BYTES_WORD_CPU(w) \
189 #else
190 # define AROS_SWAP_BYTES_WORD(w) AROS_SWAP_BYTES_WORD_CPU(w)
191 #endif
193 #if !defined(AROS_SWAP_BYTES_LONG_CPU)
194 # define AROS_SWAP_BYTES_LONG(l) AROS_SWAP_BYTES_LONG_GENERIC(l)
195 #elif defined(__GNUC__)
196 # define AROS_SWAP_BYTES_LONG(l) \
198 __builtin_constant_p(l) \
199 ? AROS_SWAP_BYTES_LONG_GENERIC(l) \
200 : AROS_SWAP_BYTES_LONG_CPU(l) \
202 #else
203 # define AROS_SWAP_BYTES_LONG(l) AROS_SWAP_BYTES_LONG_CPU(l)
204 #endif
206 #if !defined(AROS_SWAP_BYTES_QUAD_CPU)
207 # define AROS_SWAP_BYTES_QUAD(q) AROS_SWAP_BYTES_QUAD_GENERIC(q)
208 #elif defined(__GNUC__)
209 # define AROS_SWAP_BYTES_QUAD(q) \
211 __builtin_constant_p(q) \
212 ? AROS_SWAP_BYTES_QUAD_GENERIC(q) \
213 : AROS_SWAP_BYTES_QUAD_CPU(q) \
215 #else
216 # define AROS_SWAP_BYTES_QUAD(q) AROS_SWAP_BYTES_QUAD_CPU(q)
217 #endif
219 #if !defined(AROS_SWAP_WORDS_LONG_CPU)
220 # define AROS_SWAP_WORDS_LONG(l) AROS_SWAP_WORDS_LONG_GENERIC(l)
221 #elif defined(__GNUC__)
222 # define AROS_SWAP_WORDS_LONG(l) \
224 __builtin_constant_p(l) \
225 ? AROS_SWAP_WORDS_LONG_GENERIC(l) \
226 : AROS_SWAP_WORDS_LONG_CPU(l) \
228 #else
229 # define AROS_SWAP_WORDS_LONG(l) AROS_SWAP_WORDS_LONG_CPU(l)
230 #endif
232 #if !defined(AROS_SWAP_WORDS_QUAD_CPU)
233 # define AROS_SWAP_WORDS_QUAD(q) AROS_SWAP_WORDS_QUAD_GENERIC(q)
234 #elif defined(__GNUC__)
235 # define AROS_SWAP_WORDS_QUAD(q) \
237 __builtin_constant_p(q) \
238 ? AROS_SWAP_WORDS_QUAD_GENERIC(q) \
239 : AROS_SWAP_WORDS_QUAD_CPU(q) \
241 #else
242 # define AROS_SWAP_WORDS_QUAD(l) AROS_SWAP_WORDS_QUAD_CPU(l)
243 #endif
245 #if !defined(AROS_SWAP_LONGS_QUAD_CPU)
246 # define AROS_SWAP_LONGS_QUAD(q) AROS_SWAP_LONGS_QUAD_GENERIC(q)
247 #elif defined(__GNUC__)
248 # define AROS_SWAP_LONGS_QUAD(q) \
250 __builtin_constant_p(q) \
251 ? AROS_SWAP_LONGS_QUAD_GENERIC(q) \
252 : AROS_SWAP_LONGS_QUAD_CPU(q) \
254 #else
255 # define AROS_SWAP_LONGS_QUAD(q) AROS_SWAP_LONGS_QUAD_CPU(q)
256 #endif
258 #if AROS_BIG_ENDIAN
259 # define AROS_BE(type)
260 # define AROS_LE(type) AROS_SWAP_BYTES_ ## type
261 #else
262 # define AROS_BE(type) AROS_SWAP_BYTES_ ## type
263 # define AROS_LE(type)
264 #endif
266 /* Convert a word, long or quad to big endian and vice versa on the current hardware */
267 #define AROS_WORD2BE(w) AROS_BE(WORD)(w)
268 #define AROS_LONG2BE(l) AROS_BE(LONG)(l)
269 #define AROS_QUAD2BE(q) AROS_BE(QUAD)(q)
270 #define AROS_BE2WORD(w) AROS_BE(WORD)(w)
271 #define AROS_BE2LONG(l) AROS_BE(LONG)(l)
272 #define AROS_BE2QUAD(q) AROS_BE(QUAD)(q)
274 /* Convert a word, long or quad to little endian and vice versa on the current hardware */
275 #define AROS_WORD2LE(w) AROS_LE(WORD)(w)
276 #define AROS_LONG2LE(l) AROS_LE(LONG)(l)
277 #define AROS_QUAD2LE(q) AROS_LE(QUAD)(q)
278 #define AROS_LE2WORD(w) AROS_LE(WORD)(w)
279 #define AROS_LE2LONG(l) AROS_LE(LONG)(l)
280 #define AROS_LE2QUAD(q) AROS_LE(QUAD)(q)
282 /* Return the least set bit, ie. 0xFF00 will return 0x0100 */
283 #ifndef AROS_LEAST_BIT
284 # define AROS_LEAST_BIT(l) ((l) & -(l))
285 #endif
287 /* Check if an int is a power of two */
288 #ifndef AROS_IS_POWER_OF_2
289 # define AROS_IS_POWER_OF_2(l) (((l) & -(l)) == (l))
290 #endif
292 /* Round down <x> to a multiple of <r>. <r> must be a power of two */
293 #ifndef AROS_ROUNDDOWN2
294 # define AROS_ROUNDDOWN2(x,r) ((x) & ~((r) - 1))
295 #endif
297 /* Round up <x> to a multiple of <r>. <r> must be a power of two */
298 #ifndef AROS_ROUNDUP2
299 # define AROS_ROUNDUP2(x,r) (((x) + ((r) - 1)) & ~((r) - 1))
300 #endif
302 /* Return the number of the least set bit, ie. 0xFF00 will return 8 */
303 #ifndef AROS_LEAST_BIT_POS
304 # define AROS_LEAST_BIT_POS(l) \
305 (((l) & 0x0000FFFFUL) ? \
306 ((l) & 0x000000FFUL) ? \
307 ((l) & 0x0000000FUL) ? \
308 ((l) & 0x03UL) ? \
309 ((l) & 0x01UL) ? 0 : 1 \
310 : ((l) & 0x04UL) ? 2 : 3 \
311 : ((l) & 0x30UL) ? \
312 ((l) & 0x10UL) ? 4 : 5 \
313 : ((l) & 0x40UL) ? 6 : 7 \
314 : ((l) & 0x00000F00UL) ? \
315 ((l) & 0x0300UL) ? \
316 ((l) & 0x0100UL) ? 8 : 9 \
317 : ((l) & 0x0400UL) ? 10 : 11 \
318 : ((l) & 0x3000UL) ? \
319 ((l) & 0x1000UL) ? 12 : 13 \
320 : ((l) & 0x4000UL) ? 14 : 15 \
321 : ((l) & 0x00FF0000UL) ? \
322 ((l) & 0x000F0000UL) ? \
323 ((l) & 0x030000UL) ? \
324 ((l) & 0x010000UL) ? 16 : 17 \
325 : ((l) & 0x040000UL) ? 18 : 19 \
326 : ((l) & 0x300000UL) ? \
327 ((l) & 0x100000UL) ? 20 : 21 \
328 : ((l) & 0x400000UL) ? 22 : 23 \
329 : ((l) & 0x0F00000000UL) ? \
330 ((l) & 0x03000000UL) ? \
331 ((l) & 0x01000000UL) ? 24 : 25 \
332 : ((l) & 0x04000000UL) ? 26 : 27 \
333 : ((l) & 0x30000000UL) ? \
334 ((l) & 0x10000000UL) ? 28 : 29 \
335 : ((l) & 0x40000000UL) ? 30 : (l) ? 31 : -1)
336 #endif /* AROS_LEAST_BIT_POS */
338 /* Swap two integer variables */
339 #ifndef AROS_SWAP
340 # define AROS_SWAP(x,y) (x) ^= (y) ^= (x) ^= (y)
341 #endif
343 /* Build an 'ID' as used by iffparse.library and some other libraries as well. */
344 #define AROS_MAKE_ID(a,b,c,d) (((ULONG) (a)<<24) | ((ULONG) (b)<<16) | \
345 ((ULONG) (c)<<8) | ((ULONG) (d)))
347 #endif /* AROS_MACROS_H */