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