1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_SWAB_H
3 #define _LINUX_SWAB_H
4
5 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
6 #ifndef _UAPI_LINUX_SWAB_H
7 #define _UAPI_LINUX_SWAB_H
8
9 #include "../types.h"
10 #include "stddef.h"
11 #include "bitsperlong.h"
12 // #include <asm/swab.h>
13
14 /*
15 * casts are necessary for constants, because we never know how for sure
16 * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
17 */
18 #define ___constant_swab16(x) ((__u16)( \
19 (((__u16)(x) & (__u16)0x00ffU) << 8) | \
20 (((__u16)(x) & (__u16)0xff00U) >> 8)))
21
22 #define ___constant_swab32(x) ((__u32)( \
23 (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
24 (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
25 (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
26 (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
27
28 #define ___constant_swab64(x) ((__u64)( \
29 (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
30 (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
31 (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
32 (((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
33 (((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
34 (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
35 (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
36 (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
37
38 #define ___constant_swahw32(x) ((__u32)( \
39 (((__u32)(x) & (__u32)0x0000ffffUL) << 16) | \
40 (((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
41
42 #define ___constant_swahb32(x) ((__u32)( \
43 (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) | \
44 (((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
45
46 /*
47 * Implement the following as inlines, but define the interface using
48 * macros to allow constant folding when possible:
49 * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
50 */
51
__fswab16(__u16 val)52 static inline __attribute_const__ __u16 __fswab16(__u16 val)
53 {
54 #if defined (__arch_swab16)
55 return __arch_swab16(val);
56 #else
57 return ___constant_swab16(val);
58 #endif
59 }
60
__fswab32(__u32 val)61 static inline __attribute_const__ __u32 __fswab32(__u32 val)
62 {
63 #if defined(__arch_swab32)
64 return __arch_swab32(val);
65 #else
66 return ___constant_swab32(val);
67 #endif
68 }
69
__fswab64(__u64 val)70 static inline __attribute_const__ __u64 __fswab64(__u64 val)
71 {
72 #if defined (__arch_swab64)
73 return __arch_swab64(val);
74 #elif defined(__SWAB_64_THRU_32__)
75 __u32 h = val >> 32;
76 __u32 l = val & ((1ULL << 32) - 1);
77 return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
78 #else
79 return ___constant_swab64(val);
80 #endif
81 }
82
__fswahw32(__u32 val)83 static inline __attribute_const__ __u32 __fswahw32(__u32 val)
84 {
85 #ifdef __arch_swahw32
86 return __arch_swahw32(val);
87 #else
88 return ___constant_swahw32(val);
89 #endif
90 }
91
__fswahb32(__u32 val)92 static inline __attribute_const__ __u32 __fswahb32(__u32 val)
93 {
94 #ifdef __arch_swahb32
95 return __arch_swahb32(val);
96 #else
97 return ___constant_swahb32(val);
98 #endif
99 }
100
101 /**
102 * __swab16 - return a byteswapped 16-bit value
103 * @x: value to byteswap
104 */
105 #ifdef __HAVE_BUILTIN_BSWAP16__
106 #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
107 #else
108 #define __swab16(x) \
109 (__u16)(__builtin_constant_p(x) ? \
110 ___constant_swab16(x) : \
111 __fswab16(x))
112 #endif
113
114 /**
115 * __swab32 - return a byteswapped 32-bit value
116 * @x: value to byteswap
117 */
118 #ifdef __HAVE_BUILTIN_BSWAP32__
119 #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
120 #else
121 #define __swab32(x) \
122 (__u32)(__builtin_constant_p(x) ? \
123 ___constant_swab32(x) : \
124 __fswab32(x))
125 #endif
126
127 /**
128 * __swab64 - return a byteswapped 64-bit value
129 * @x: value to byteswap
130 */
131 #ifdef __HAVE_BUILTIN_BSWAP64__
132 #define __swab64(x) (__u64)__builtin_bswap64((__u64)(x))
133 #else
134 #define __swab64(x) \
135 (__u64)(__builtin_constant_p(x) ? \
136 ___constant_swab64(x) : \
137 __fswab64(x))
138 #endif
139
__swab(const unsigned long y)140 static __always_inline unsigned long __swab(const unsigned long y)
141 {
142 #if __BITS_PER_LONG == 64
143 return __swab64(y);
144 #else /* __BITS_PER_LONG == 32 */
145 return __swab32(y);
146 #endif
147 }
148
149 /**
150 * __swahw32 - return a word-swapped 32-bit value
151 * @x: value to wordswap
152 *
153 * __swahw32(0x12340000) is 0x00001234
154 */
155 #define __swahw32(x) \
156 (__builtin_constant_p((__u32)(x)) ? \
157 ___constant_swahw32(x) : \
158 __fswahw32(x))
159
160 /**
161 * __swahb32 - return a high and low byte-swapped 32-bit value
162 * @x: value to byteswap
163 *
164 * __swahb32(0x12345678) is 0x34127856
165 */
166 #define __swahb32(x) \
167 (__builtin_constant_p((__u32)(x)) ? \
168 ___constant_swahb32(x) : \
169 __fswahb32(x))
170
171 /**
172 * __swab16p - return a byteswapped 16-bit value from a pointer
173 * @p: pointer to a naturally-aligned 16-bit value
174 */
__swab16p(const __u16 * p)175 static __always_inline __u16 __swab16p(const __u16 *p)
176 {
177 #ifdef __arch_swab16p
178 return __arch_swab16p(p);
179 #else
180 return __swab16(*p);
181 #endif
182 }
183
184 /**
185 * __swab32p - return a byteswapped 32-bit value from a pointer
186 * @p: pointer to a naturally-aligned 32-bit value
187 */
__swab32p(const __u32 * p)188 static __always_inline __u32 __swab32p(const __u32 *p)
189 {
190 #ifdef __arch_swab32p
191 return __arch_swab32p(p);
192 #else
193 return __swab32(*p);
194 #endif
195 }
196
197 /**
198 * __swab64p - return a byteswapped 64-bit value from a pointer
199 * @p: pointer to a naturally-aligned 64-bit value
200 */
__swab64p(const __u64 * p)201 static __always_inline __u64 __swab64p(const __u64 *p)
202 {
203 #ifdef __arch_swab64p
204 return __arch_swab64p(p);
205 #else
206 return __swab64(*p);
207 #endif
208 }
209
210 /**
211 * __swahw32p - return a wordswapped 32-bit value from a pointer
212 * @p: pointer to a naturally-aligned 32-bit value
213 *
214 * See __swahw32() for details of wordswapping.
215 */
__swahw32p(const __u32 * p)216 static inline __u32 __swahw32p(const __u32 *p)
217 {
218 #ifdef __arch_swahw32p
219 return __arch_swahw32p(p);
220 #else
221 return __swahw32(*p);
222 #endif
223 }
224
225 /**
226 * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
227 * @p: pointer to a naturally-aligned 32-bit value
228 *
229 * See __swahb32() for details of high/low byteswapping.
230 */
__swahb32p(const __u32 * p)231 static inline __u32 __swahb32p(const __u32 *p)
232 {
233 #ifdef __arch_swahb32p
234 return __arch_swahb32p(p);
235 #else
236 return __swahb32(*p);
237 #endif
238 }
239
240 /**
241 * __swab16s - byteswap a 16-bit value in-place
242 * @p: pointer to a naturally-aligned 16-bit value
243 */
__swab16s(__u16 * p)244 static inline void __swab16s(__u16 *p)
245 {
246 #ifdef __arch_swab16s
247 __arch_swab16s(p);
248 #else
249 *p = __swab16p(p);
250 #endif
251 }
252 /**
253 * __swab32s - byteswap a 32-bit value in-place
254 * @p: pointer to a naturally-aligned 32-bit value
255 */
__swab32s(__u32 * p)256 static __always_inline void __swab32s(__u32 *p)
257 {
258 #ifdef __arch_swab32s
259 __arch_swab32s(p);
260 #else
261 *p = __swab32p(p);
262 #endif
263 }
264
265 /**
266 * __swab64s - byteswap a 64-bit value in-place
267 * @p: pointer to a naturally-aligned 64-bit value
268 */
__swab64s(__u64 * p)269 static __always_inline void __swab64s(__u64 *p)
270 {
271 #ifdef __arch_swab64s
272 __arch_swab64s(p);
273 #else
274 *p = __swab64p(p);
275 #endif
276 }
277
278 /**
279 * __swahw32s - wordswap a 32-bit value in-place
280 * @p: pointer to a naturally-aligned 32-bit value
281 *
282 * See __swahw32() for details of wordswapping
283 */
__swahw32s(__u32 * p)284 static inline void __swahw32s(__u32 *p)
285 {
286 #ifdef __arch_swahw32s
287 __arch_swahw32s(p);
288 #else
289 *p = __swahw32p(p);
290 #endif
291 }
292
293 /**
294 * __swahb32s - high and low byteswap a 32-bit value in-place
295 * @p: pointer to a naturally-aligned 32-bit value
296 *
297 * See __swahb32() for details of high and low byte swapping
298 */
__swahb32s(__u32 * p)299 static inline void __swahb32s(__u32 *p)
300 {
301 #ifdef __arch_swahb32s
302 __arch_swahb32s(p);
303 #else
304 *p = __swahb32p(p);
305 #endif
306 }
307
308
309 #endif /* _UAPI_LINUX_SWAB_H */
310
311
312 # define swab16 __swab16
313 # define swab32 __swab32
314 # define swab64 __swab64
315 # define swab __swab
316 # define swahw32 __swahw32
317 # define swahb32 __swahb32
318 # define swab16p __swab16p
319 # define swab32p __swab32p
320 # define swab64p __swab64p
321 # define swahw32p __swahw32p
322 # define swahb32p __swahb32p
323 # define swab16s __swab16s
324 # define swab32s __swab32s
325 # define swab64s __swab64s
326 # define swahw32s __swahw32s
327 # define swahb32s __swahb32s
328
swab16_array(u16 * buf,unsigned int words)329 static inline void swab16_array(u16 *buf, unsigned int words)
330 {
331 while (words--) {
332 swab16s(buf);
333 buf++;
334 }
335 }
336
swab32_array(u32 * buf,unsigned int words)337 static inline void swab32_array(u32 *buf, unsigned int words)
338 {
339 while (words--) {
340 swab32s(buf);
341 buf++;
342 }
343 }
344
swab64_array(u64 * buf,unsigned int words)345 static inline void swab64_array(u64 *buf, unsigned int words)
346 {
347 while (words--) {
348 swab64s(buf);
349 buf++;
350 }
351 }
352
353 #endif /* _LINUX_SWAB_H */
354