xref: /DragonStub/inc/dragonstub/linux/swab.h (revision f412fd2a1a248b546b7085648dece8d908077fab)
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