xref: /linux/include/uapi/linux/swab.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
16f52b16cSGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2607ca46eSDavid Howells #ifndef _UAPI_LINUX_SWAB_H
3607ca46eSDavid Howells #define _UAPI_LINUX_SWAB_H
4607ca46eSDavid Howells 
5607ca46eSDavid Howells #include <linux/types.h>
6*defbab27SMatt Redfearn #include <linux/stddef.h>
7d5767057SYury Norov #include <asm/bitsperlong.h>
8607ca46eSDavid Howells #include <asm/swab.h>
9607ca46eSDavid Howells 
10607ca46eSDavid Howells /*
11607ca46eSDavid Howells  * casts are necessary for constants, because we never know how for sure
12607ca46eSDavid Howells  * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
13607ca46eSDavid Howells  */
14607ca46eSDavid Howells #define ___constant_swab16(x) ((__u16)(				\
15607ca46eSDavid Howells 	(((__u16)(x) & (__u16)0x00ffU) << 8) |			\
16607ca46eSDavid Howells 	(((__u16)(x) & (__u16)0xff00U) >> 8)))
17607ca46eSDavid Howells 
18607ca46eSDavid Howells #define ___constant_swab32(x) ((__u32)(				\
19607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0x000000ffUL) << 24) |		\
20607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |		\
21607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |		\
22607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0xff000000UL) >> 24)))
23607ca46eSDavid Howells 
24607ca46eSDavid Howells #define ___constant_swab64(x) ((__u64)(				\
25607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) |	\
26607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) |	\
27607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) |	\
28607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x00000000ff000000ULL) <<  8) |	\
29607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x000000ff00000000ULL) >>  8) |	\
30607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) |	\
31607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) |	\
32607ca46eSDavid Howells 	(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
33607ca46eSDavid Howells 
34607ca46eSDavid Howells #define ___constant_swahw32(x) ((__u32)(			\
35607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0x0000ffffUL) << 16) |		\
36607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
37607ca46eSDavid Howells 
38607ca46eSDavid Howells #define ___constant_swahb32(x) ((__u32)(			\
39607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0x00ff00ffUL) << 8) |		\
40607ca46eSDavid Howells 	(((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
41607ca46eSDavid Howells 
42607ca46eSDavid Howells /*
43607ca46eSDavid Howells  * Implement the following as inlines, but define the interface using
44607ca46eSDavid Howells  * macros to allow constant folding when possible:
45607ca46eSDavid Howells  * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
46607ca46eSDavid Howells  */
47607ca46eSDavid Howells 
__fswab16(__u16 val)48607ca46eSDavid Howells static inline __attribute_const__ __u16 __fswab16(__u16 val)
49607ca46eSDavid Howells {
507322dd75SArnd Bergmann #if defined (__arch_swab16)
51607ca46eSDavid Howells 	return __arch_swab16(val);
52607ca46eSDavid Howells #else
53607ca46eSDavid Howells 	return ___constant_swab16(val);
54607ca46eSDavid Howells #endif
55607ca46eSDavid Howells }
56607ca46eSDavid Howells 
__fswab32(__u32 val)57607ca46eSDavid Howells static inline __attribute_const__ __u32 __fswab32(__u32 val)
58607ca46eSDavid Howells {
597322dd75SArnd Bergmann #if defined(__arch_swab32)
60607ca46eSDavid Howells 	return __arch_swab32(val);
61607ca46eSDavid Howells #else
62607ca46eSDavid Howells 	return ___constant_swab32(val);
63607ca46eSDavid Howells #endif
64607ca46eSDavid Howells }
65607ca46eSDavid Howells 
__fswab64(__u64 val)66607ca46eSDavid Howells static inline __attribute_const__ __u64 __fswab64(__u64 val)
67607ca46eSDavid Howells {
687322dd75SArnd Bergmann #if defined (__arch_swab64)
69607ca46eSDavid Howells 	return __arch_swab64(val);
70607ca46eSDavid Howells #elif defined(__SWAB_64_THRU_32__)
71607ca46eSDavid Howells 	__u32 h = val >> 32;
72607ca46eSDavid Howells 	__u32 l = val & ((1ULL << 32) - 1);
73607ca46eSDavid Howells 	return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
74607ca46eSDavid Howells #else
75607ca46eSDavid Howells 	return ___constant_swab64(val);
76607ca46eSDavid Howells #endif
77607ca46eSDavid Howells }
78607ca46eSDavid Howells 
__fswahw32(__u32 val)79607ca46eSDavid Howells static inline __attribute_const__ __u32 __fswahw32(__u32 val)
80607ca46eSDavid Howells {
81607ca46eSDavid Howells #ifdef __arch_swahw32
82607ca46eSDavid Howells 	return __arch_swahw32(val);
83607ca46eSDavid Howells #else
84607ca46eSDavid Howells 	return ___constant_swahw32(val);
85607ca46eSDavid Howells #endif
86607ca46eSDavid Howells }
87607ca46eSDavid Howells 
__fswahb32(__u32 val)88607ca46eSDavid Howells static inline __attribute_const__ __u32 __fswahb32(__u32 val)
89607ca46eSDavid Howells {
90607ca46eSDavid Howells #ifdef __arch_swahb32
91607ca46eSDavid Howells 	return __arch_swahb32(val);
92607ca46eSDavid Howells #else
93607ca46eSDavid Howells 	return ___constant_swahb32(val);
94607ca46eSDavid Howells #endif
95607ca46eSDavid Howells }
96607ca46eSDavid Howells 
97607ca46eSDavid Howells /**
98607ca46eSDavid Howells  * __swab16 - return a byteswapped 16-bit value
99607ca46eSDavid Howells  * @x: value to byteswap
100607ca46eSDavid Howells  */
1017322dd75SArnd Bergmann #ifdef __HAVE_BUILTIN_BSWAP16__
1027322dd75SArnd Bergmann #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
1037322dd75SArnd Bergmann #else
104607ca46eSDavid Howells #define __swab16(x)				\
105d30dfd49SJustin Stitt 	(__u16)(__builtin_constant_p(x) ?	\
106607ca46eSDavid Howells 	___constant_swab16(x) :			\
107607ca46eSDavid Howells 	__fswab16(x))
1087322dd75SArnd Bergmann #endif
109607ca46eSDavid Howells 
110607ca46eSDavid Howells /**
111607ca46eSDavid Howells  * __swab32 - return a byteswapped 32-bit value
112607ca46eSDavid Howells  * @x: value to byteswap
113607ca46eSDavid Howells  */
1147322dd75SArnd Bergmann #ifdef __HAVE_BUILTIN_BSWAP32__
1157322dd75SArnd Bergmann #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
1167322dd75SArnd Bergmann #else
117607ca46eSDavid Howells #define __swab32(x)				\
118d30dfd49SJustin Stitt 	(__u32)(__builtin_constant_p(x) ?	\
119607ca46eSDavid Howells 	___constant_swab32(x) :			\
120607ca46eSDavid Howells 	__fswab32(x))
1217322dd75SArnd Bergmann #endif
122607ca46eSDavid Howells 
123607ca46eSDavid Howells /**
124607ca46eSDavid Howells  * __swab64 - return a byteswapped 64-bit value
125607ca46eSDavid Howells  * @x: value to byteswap
126607ca46eSDavid Howells  */
1277322dd75SArnd Bergmann #ifdef __HAVE_BUILTIN_BSWAP64__
1287322dd75SArnd Bergmann #define __swab64(x) (__u64)__builtin_bswap64((__u64)(x))
1297322dd75SArnd Bergmann #else
130607ca46eSDavid Howells #define __swab64(x)				\
131d30dfd49SJustin Stitt 	(__u64)(__builtin_constant_p(x) ?	\
132607ca46eSDavid Howells 	___constant_swab64(x) :			\
133607ca46eSDavid Howells 	__fswab64(x))
1347322dd75SArnd Bergmann #endif
135607ca46eSDavid Howells 
__swab(const unsigned long y)136d5767057SYury Norov static __always_inline unsigned long __swab(const unsigned long y)
137d5767057SYury Norov {
138467d12f5SChristian Borntraeger #if __BITS_PER_LONG == 64
139d5767057SYury Norov 	return __swab64(y);
140467d12f5SChristian Borntraeger #else /* __BITS_PER_LONG == 32 */
141d5767057SYury Norov 	return __swab32(y);
142d5767057SYury Norov #endif
143d5767057SYury Norov }
144d5767057SYury Norov 
145607ca46eSDavid Howells /**
146607ca46eSDavid Howells  * __swahw32 - return a word-swapped 32-bit value
147607ca46eSDavid Howells  * @x: value to wordswap
148607ca46eSDavid Howells  *
149607ca46eSDavid Howells  * __swahw32(0x12340000) is 0x00001234
150607ca46eSDavid Howells  */
151607ca46eSDavid Howells #define __swahw32(x)				\
152607ca46eSDavid Howells 	(__builtin_constant_p((__u32)(x)) ?	\
153607ca46eSDavid Howells 	___constant_swahw32(x) :		\
154607ca46eSDavid Howells 	__fswahw32(x))
155607ca46eSDavid Howells 
156607ca46eSDavid Howells /**
157607ca46eSDavid Howells  * __swahb32 - return a high and low byte-swapped 32-bit value
158607ca46eSDavid Howells  * @x: value to byteswap
159607ca46eSDavid Howells  *
160607ca46eSDavid Howells  * __swahb32(0x12345678) is 0x34127856
161607ca46eSDavid Howells  */
162607ca46eSDavid Howells #define __swahb32(x)				\
163607ca46eSDavid Howells 	(__builtin_constant_p((__u32)(x)) ?	\
164607ca46eSDavid Howells 	___constant_swahb32(x) :		\
165607ca46eSDavid Howells 	__fswahb32(x))
166607ca46eSDavid Howells 
167607ca46eSDavid Howells /**
168607ca46eSDavid Howells  * __swab16p - return a byteswapped 16-bit value from a pointer
169607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 16-bit value
170607ca46eSDavid Howells  */
__swab16p(const __u16 * p)171bc27fb68SDenys Vlasenko static __always_inline __u16 __swab16p(const __u16 *p)
172607ca46eSDavid Howells {
173607ca46eSDavid Howells #ifdef __arch_swab16p
174607ca46eSDavid Howells 	return __arch_swab16p(p);
175607ca46eSDavid Howells #else
176607ca46eSDavid Howells 	return __swab16(*p);
177607ca46eSDavid Howells #endif
178607ca46eSDavid Howells }
179607ca46eSDavid Howells 
180607ca46eSDavid Howells /**
181607ca46eSDavid Howells  * __swab32p - return a byteswapped 32-bit value from a pointer
182607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
183607ca46eSDavid Howells  */
__swab32p(const __u32 * p)184bc27fb68SDenys Vlasenko static __always_inline __u32 __swab32p(const __u32 *p)
185607ca46eSDavid Howells {
186607ca46eSDavid Howells #ifdef __arch_swab32p
187607ca46eSDavid Howells 	return __arch_swab32p(p);
188607ca46eSDavid Howells #else
189607ca46eSDavid Howells 	return __swab32(*p);
190607ca46eSDavid Howells #endif
191607ca46eSDavid Howells }
192607ca46eSDavid Howells 
193607ca46eSDavid Howells /**
194607ca46eSDavid Howells  * __swab64p - return a byteswapped 64-bit value from a pointer
195607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 64-bit value
196607ca46eSDavid Howells  */
__swab64p(const __u64 * p)197bc27fb68SDenys Vlasenko static __always_inline __u64 __swab64p(const __u64 *p)
198607ca46eSDavid Howells {
199607ca46eSDavid Howells #ifdef __arch_swab64p
200607ca46eSDavid Howells 	return __arch_swab64p(p);
201607ca46eSDavid Howells #else
202607ca46eSDavid Howells 	return __swab64(*p);
203607ca46eSDavid Howells #endif
204607ca46eSDavid Howells }
205607ca46eSDavid Howells 
206607ca46eSDavid Howells /**
207607ca46eSDavid Howells  * __swahw32p - return a wordswapped 32-bit value from a pointer
208607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
209607ca46eSDavid Howells  *
210607ca46eSDavid Howells  * See __swahw32() for details of wordswapping.
211607ca46eSDavid Howells  */
__swahw32p(const __u32 * p)212607ca46eSDavid Howells static inline __u32 __swahw32p(const __u32 *p)
213607ca46eSDavid Howells {
214607ca46eSDavid Howells #ifdef __arch_swahw32p
215607ca46eSDavid Howells 	return __arch_swahw32p(p);
216607ca46eSDavid Howells #else
217607ca46eSDavid Howells 	return __swahw32(*p);
218607ca46eSDavid Howells #endif
219607ca46eSDavid Howells }
220607ca46eSDavid Howells 
221607ca46eSDavid Howells /**
222607ca46eSDavid Howells  * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
223607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
224607ca46eSDavid Howells  *
225607ca46eSDavid Howells  * See __swahb32() for details of high/low byteswapping.
226607ca46eSDavid Howells  */
__swahb32p(const __u32 * p)227607ca46eSDavid Howells static inline __u32 __swahb32p(const __u32 *p)
228607ca46eSDavid Howells {
229607ca46eSDavid Howells #ifdef __arch_swahb32p
230607ca46eSDavid Howells 	return __arch_swahb32p(p);
231607ca46eSDavid Howells #else
232607ca46eSDavid Howells 	return __swahb32(*p);
233607ca46eSDavid Howells #endif
234607ca46eSDavid Howells }
235607ca46eSDavid Howells 
236607ca46eSDavid Howells /**
237607ca46eSDavid Howells  * __swab16s - byteswap a 16-bit value in-place
238607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 16-bit value
239607ca46eSDavid Howells  */
__swab16s(__u16 * p)240607ca46eSDavid Howells static inline void __swab16s(__u16 *p)
241607ca46eSDavid Howells {
242607ca46eSDavid Howells #ifdef __arch_swab16s
243607ca46eSDavid Howells 	__arch_swab16s(p);
244607ca46eSDavid Howells #else
245607ca46eSDavid Howells 	*p = __swab16p(p);
246607ca46eSDavid Howells #endif
247607ca46eSDavid Howells }
248607ca46eSDavid Howells /**
249607ca46eSDavid Howells  * __swab32s - byteswap a 32-bit value in-place
250607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
251607ca46eSDavid Howells  */
__swab32s(__u32 * p)252bc27fb68SDenys Vlasenko static __always_inline void __swab32s(__u32 *p)
253607ca46eSDavid Howells {
254607ca46eSDavid Howells #ifdef __arch_swab32s
255607ca46eSDavid Howells 	__arch_swab32s(p);
256607ca46eSDavid Howells #else
257607ca46eSDavid Howells 	*p = __swab32p(p);
258607ca46eSDavid Howells #endif
259607ca46eSDavid Howells }
260607ca46eSDavid Howells 
261607ca46eSDavid Howells /**
262607ca46eSDavid Howells  * __swab64s - byteswap a 64-bit value in-place
263607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 64-bit value
264607ca46eSDavid Howells  */
__swab64s(__u64 * p)265bc27fb68SDenys Vlasenko static __always_inline void __swab64s(__u64 *p)
266607ca46eSDavid Howells {
267607ca46eSDavid Howells #ifdef __arch_swab64s
268607ca46eSDavid Howells 	__arch_swab64s(p);
269607ca46eSDavid Howells #else
270607ca46eSDavid Howells 	*p = __swab64p(p);
271607ca46eSDavid Howells #endif
272607ca46eSDavid Howells }
273607ca46eSDavid Howells 
274607ca46eSDavid Howells /**
275607ca46eSDavid Howells  * __swahw32s - wordswap a 32-bit value in-place
276607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
277607ca46eSDavid Howells  *
278607ca46eSDavid Howells  * See __swahw32() for details of wordswapping
279607ca46eSDavid Howells  */
__swahw32s(__u32 * p)280607ca46eSDavid Howells static inline void __swahw32s(__u32 *p)
281607ca46eSDavid Howells {
282607ca46eSDavid Howells #ifdef __arch_swahw32s
283607ca46eSDavid Howells 	__arch_swahw32s(p);
284607ca46eSDavid Howells #else
285607ca46eSDavid Howells 	*p = __swahw32p(p);
286607ca46eSDavid Howells #endif
287607ca46eSDavid Howells }
288607ca46eSDavid Howells 
289607ca46eSDavid Howells /**
290607ca46eSDavid Howells  * __swahb32s - high and low byteswap a 32-bit value in-place
291607ca46eSDavid Howells  * @p: pointer to a naturally-aligned 32-bit value
292607ca46eSDavid Howells  *
293607ca46eSDavid Howells  * See __swahb32() for details of high and low byte swapping
294607ca46eSDavid Howells  */
__swahb32s(__u32 * p)295607ca46eSDavid Howells static inline void __swahb32s(__u32 *p)
296607ca46eSDavid Howells {
297607ca46eSDavid Howells #ifdef __arch_swahb32s
298607ca46eSDavid Howells 	__arch_swahb32s(p);
299607ca46eSDavid Howells #else
300607ca46eSDavid Howells 	*p = __swahb32p(p);
301607ca46eSDavid Howells #endif
302607ca46eSDavid Howells }
303607ca46eSDavid Howells 
304607ca46eSDavid Howells 
305607ca46eSDavid Howells #endif /* _UAPI_LINUX_SWAB_H */
306