|
10 | 10 | * separated swab functions from cpu_to_XX, |
11 | 11 | * to clean up support for bizarre-endian architectures. |
12 | 12 | * |
| 13 | + * Trent Piepho <xyzzy@speakeasy.org> 2007114 |
| 14 | + * make constant-folding work, provide C versions that |
| 15 | + * gcc can optimize better, explain different versions |
| 16 | + * |
13 | 17 | * See asm-i386/byteorder.h and suches for examples of how to provide |
14 | 18 | * architecture-dependent optimized versions |
15 | 19 | * |
16 | 20 | */ |
17 | 21 |
|
18 | 22 | #include <linux/compiler.h> |
19 | 23 |
|
| 24 | +/* Functions/macros defined, there are a lot: |
| 25 | + * |
| 26 | + * ___swabXX |
| 27 | + * Generic C versions of the swab functions. |
| 28 | + * |
| 29 | + * ___constant_swabXX |
| 30 | + * C versions that gcc can fold into a compile-time constant when |
| 31 | + * the argument is a compile-time constant. |
| 32 | + * |
| 33 | + * __arch__swabXX[sp]? |
| 34 | + * Architecture optimized versions of all the swab functions |
| 35 | + * (including the s and p versions). These can be defined in |
| 36 | + * asm-arch/byteorder.h. Any which are not, are defined here. |
| 37 | + * __arch__swabXXs() is defined in terms of __arch__swabXXp(), which |
| 38 | + * is defined in terms of __arch__swabXX(), which is in turn defined |
| 39 | + * in terms of ___swabXX(x). |
| 40 | + * These must be macros. They may be unsafe for arguments with |
| 41 | + * side-effects. |
| 42 | + * |
| 43 | + * __fswabXX |
| 44 | + * Inline function versions of the __arch__ macros. These _are_ safe |
| 45 | + * if the arguments have side-effects. Note there are no s and p |
| 46 | + * versions of these. |
| 47 | + * |
| 48 | + * __swabXX[sb] |
| 49 | + * There are the ones you should actually use. The __swabXX versions |
| 50 | + * will be a constant given a constant argument and use the arch |
| 51 | + * specific code (if any) for non-constant arguments. The s and p |
| 52 | + * versions always use the arch specific code (constant folding |
| 53 | + * doesn't apply). They are safe to use with arguments with |
| 54 | + * side-effects. |
| 55 | + * |
| 56 | + * swabXX[sb] |
| 57 | + * Nicknames for __swabXX[sb] to use in the kernel. |
| 58 | + */ |
| 59 | + |
20 | 60 | /* casts are necessary for constants, because we never know how for sure |
21 | 61 | * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. |
22 | 62 | */ |
23 | | -#define ___swab16(x) \ |
24 | | -({ \ |
25 | | - __u16 __x = (x); \ |
26 | | - ((__u16)( \ |
27 | | - (((__u16)(__x) & (__u16)0x00ffU) << 8) | \ |
28 | | - (((__u16)(__x) & (__u16)0xff00U) >> 8) )); \ |
29 | | -}) |
30 | 63 |
|
31 | | -#define ___swab32(x) \ |
32 | | -({ \ |
33 | | - __u32 __x = (x); \ |
34 | | - ((__u32)( \ |
35 | | - (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \ |
36 | | - (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \ |
37 | | - (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \ |
38 | | - (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \ |
39 | | -}) |
40 | | - |
41 | | -#define ___swab64(x) \ |
42 | | -({ \ |
43 | | - __u64 __x = (x); \ |
44 | | - ((__u64)( \ |
45 | | - (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ |
46 | | - (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ |
47 | | - (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ |
48 | | - (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ |
49 | | - (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ |
50 | | - (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ |
51 | | - (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ |
52 | | - (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ |
53 | | -}) |
| 64 | +static __inline__ __attribute_const__ __u16 ___swab16(__u16 x) |
| 65 | +{ |
| 66 | + return x<<8 | x>>8; |
| 67 | +} |
| 68 | +static __inline__ __attribute_const__ __u32 ___swab32(__u32 x) |
| 69 | +{ |
| 70 | + return x<<24 | x>>24 | |
| 71 | + (x & (__u32)0x0000ff00UL)<<8 | |
| 72 | + (x & (__u32)0x00ff0000UL)>>8; |
| 73 | +} |
| 74 | +static __inline__ __attribute_const__ __u64 ___swab64(__u64 x) |
| 75 | +{ |
| 76 | + return x<<56 | x>>56 | |
| 77 | + (x & (__u64)0x000000000000ff00ULL)<<40 | |
| 78 | + (x & (__u64)0x0000000000ff0000ULL)<<24 | |
| 79 | + (x & (__u64)0x00000000ff000000ULL)<< 8 | |
| 80 | + (x & (__u64)0x000000ff00000000ULL)>> 8 | |
| 81 | + (x & (__u64)0x0000ff0000000000ULL)>>24 | |
| 82 | + (x & (__u64)0x00ff000000000000ULL)>>40; |
| 83 | +} |
54 | 84 |
|
55 | 85 | #define ___constant_swab16(x) \ |
56 | 86 | ((__u16)( \ |
|
77 | 107 | * provide defaults when no architecture-specific optimization is detected |
78 | 108 | */ |
79 | 109 | #ifndef __arch__swab16 |
80 | | -# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); }) |
| 110 | +# define __arch__swab16(x) ___swab16(x) |
81 | 111 | #endif |
82 | 112 | #ifndef __arch__swab32 |
83 | | -# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); }) |
| 113 | +# define __arch__swab32(x) ___swab32(x) |
84 | 114 | #endif |
85 | 115 | #ifndef __arch__swab64 |
86 | | -# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); }) |
| 116 | +# define __arch__swab64(x) ___swab64(x) |
87 | 117 | #endif |
88 | 118 |
|
89 | 119 | #ifndef __arch__swab16p |
|
97 | 127 | #endif |
98 | 128 |
|
99 | 129 | #ifndef __arch__swab16s |
100 | | -# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0) |
| 130 | +# define __arch__swab16s(x) ((void)(*(x) = __arch__swab16p(x))) |
101 | 131 | #endif |
102 | 132 | #ifndef __arch__swab32s |
103 | | -# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0) |
| 133 | +# define __arch__swab32s(x) ((void)(*(x) = __arch__swab32p(x))) |
104 | 134 | #endif |
105 | 135 | #ifndef __arch__swab64s |
106 | | -# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0) |
| 136 | +# define __arch__swab64s(x) ((void)(*(x) = __arch__swab64p(x))) |
107 | 137 | #endif |
108 | 138 |
|
109 | 139 |
|
|
113 | 143 | #if defined(__GNUC__) && defined(__OPTIMIZE__) |
114 | 144 | # define __swab16(x) \ |
115 | 145 | (__builtin_constant_p((__u16)(x)) ? \ |
116 | | - ___swab16((x)) : \ |
| 146 | + ___constant_swab16((x)) : \ |
117 | 147 | __fswab16((x))) |
118 | 148 | # define __swab32(x) \ |
119 | 149 | (__builtin_constant_p((__u32)(x)) ? \ |
120 | | - ___swab32((x)) : \ |
| 150 | + ___constant_swab32((x)) : \ |
121 | 151 | __fswab32((x))) |
122 | 152 | # define __swab64(x) \ |
123 | 153 | (__builtin_constant_p((__u64)(x)) ? \ |
124 | | - ___swab64((x)) : \ |
| 154 | + ___constant_swab64((x)) : \ |
125 | 155 | __fswab64((x))) |
126 | 156 | #else |
127 | 157 | # define __swab16(x) __fswab16(x) |
|
0 commit comments