1/*
2 * endians.h - Definitions related to handling of byte ordering.
3 *             Originated from the Linux-NTFS project.
4 *
5 * Copyright (c) 2000-2005 Anton Altaparmakov
6 *
7 * This program/include file is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program/include file is distributed in the hope that it will be
13 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program (in the main directory of the NTFS-3G
19 * distribution in the file COPYING); if not, write to the Free Software
20 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22
23#ifndef _NTFS_ENDIANS_H
24#define _NTFS_ENDIANS_H
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30/*
31 * Notes:
32 *	We define the conversion functions including typecasts since the
33 * defaults don't necessarily perform appropriate typecasts.
34 *	Also, using our own functions means that we can change them if it
35 * turns out that we do need to use the unaligned access macros on
36 * architectures requiring aligned memory accesses...
37 */
38
39#ifdef HAVE_ENDIAN_H
40#include <endian.h>
41#endif
42#ifdef HAVE_SYS_ENDIAN_H
43#include <sys/endian.h>
44#endif
45#ifdef HAVE_MACHINE_ENDIAN_H
46#include <machine/endian.h>
47#endif
48#ifdef HAVE_SYS_BYTEORDER_H
49#include <sys/byteorder.h>
50#endif
51#ifdef HAVE_SYS_PARAM_H
52#include <sys/param.h>
53#endif
54
55#ifndef __BYTE_ORDER
56#	if defined(_BYTE_ORDER)
57#		define __BYTE_ORDER _BYTE_ORDER
58#		define __LITTLE_ENDIAN _LITTLE_ENDIAN
59#		define __BIG_ENDIAN _BIG_ENDIAN
60#	elif defined(BYTE_ORDER)
61#		define __BYTE_ORDER BYTE_ORDER
62#		define __LITTLE_ENDIAN LITTLE_ENDIAN
63#		define __BIG_ENDIAN BIG_ENDIAN
64#	elif defined(__BYTE_ORDER__) && defined(__LITTLE_ENDIAN__) && \
65			defined(__BIG_ENDIAN__)
66#		define __BYTE_ORDER __BYTE_ORDER__
67#		define __LITTLE_ENDIAN __LITTLE_ENDIAN__
68#		define __BIG_ENDIAN __BIG_ENDIAN__
69#	elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
70			defined(__ORDER_BIG_ENDIAN__)
71#		define __BYTE_ORDER __BYTE_ORDER__
72#		define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
73#		define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
74#	elif (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
75			defined(WORDS_LITTLEENDIAN)
76#		define __BYTE_ORDER 1
77#		define __LITTLE_ENDIAN 1
78#		define __BIG_ENDIAN 0
79#	elif (!defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)) || \
80			defined(WORDS_BIGENDIAN)
81#		define __BYTE_ORDER 0
82#		define __LITTLE_ENDIAN 1
83#		define __BIG_ENDIAN 0
84#	else
85#		error "__BYTE_ORDER is not defined."
86#	endif
87#endif
88
89#define __ntfs_bswap_constant_16(x)		\
90	  (u16)((((u16)(x) & 0xff00) >> 8) |	\
91		(((u16)(x) & 0x00ff) << 8))
92
93#define __ntfs_bswap_constant_32(x)			\
94	  (u32)((((u32)(x) & 0xff000000u) >> 24) |	\
95		(((u32)(x) & 0x00ff0000u) >>  8) |	\
96		(((u32)(x) & 0x0000ff00u) <<  8) |	\
97		(((u32)(x) & 0x000000ffu) << 24))
98
99#define __ntfs_bswap_constant_64(x)				\
100	  (u64)((((u64)(x) & 0xff00000000000000ull) >> 56) |	\
101		(((u64)(x) & 0x00ff000000000000ull) >> 40) |	\
102		(((u64)(x) & 0x0000ff0000000000ull) >> 24) |	\
103		(((u64)(x) & 0x000000ff00000000ull) >>  8) |	\
104		(((u64)(x) & 0x00000000ff000000ull) <<  8) |	\
105		(((u64)(x) & 0x0000000000ff0000ull) << 24) |	\
106		(((u64)(x) & 0x000000000000ff00ull) << 40) |	\
107		(((u64)(x) & 0x00000000000000ffull) << 56))
108
109#ifdef HAVE_BYTESWAP_H
110#	include <byteswap.h>
111#else
112#	define bswap_16(x) __ntfs_bswap_constant_16(x)
113#	define bswap_32(x) __ntfs_bswap_constant_32(x)
114#	define bswap_64(x) __ntfs_bswap_constant_64(x)
115#endif
116
117#if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
118
119#define __le16_to_cpu(x) (x)
120#define __le32_to_cpu(x) (x)
121#define __le64_to_cpu(x) (x)
122
123#define __cpu_to_le16(x) (x)
124#define __cpu_to_le32(x) (x)
125#define __cpu_to_le64(x) (x)
126
127#define __constant_le16_to_cpu(x) (x)
128#define __constant_le32_to_cpu(x) (x)
129#define __constant_le64_to_cpu(x) (x)
130
131#define __constant_cpu_to_le16(x) (x)
132#define __constant_cpu_to_le32(x) (x)
133#define __constant_cpu_to_le64(x) (x)
134
135#define __be16_to_cpu(x) bswap_16(x)
136#define __be32_to_cpu(x) bswap_32(x)
137#define __be64_to_cpu(x) bswap_64(x)
138
139#define __cpu_to_be16(x) bswap_16(x)
140#define __cpu_to_be32(x) bswap_32(x)
141#define __cpu_to_be64(x) bswap_64(x)
142
143#define __constant_be16_to_cpu(x) __ntfs_bswap_constant_16((u16)(x))
144#define __constant_be32_to_cpu(x) __ntfs_bswap_constant_32((u32)(x))
145#define __constant_be64_to_cpu(x) __ntfs_bswap_constant_64((u64)(x))
146
147#define __constant_cpu_to_be16(x) __ntfs_bswap_constant_16((u16)(x))
148#define __constant_cpu_to_be32(x) __ntfs_bswap_constant_32((u32)(x))
149#define __constant_cpu_to_be64(x) __ntfs_bswap_constant_64((u64)(x))
150
151#elif defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
152
153#define __le16_to_cpu(x) bswap_16(x)
154#define __le32_to_cpu(x) bswap_32(x)
155#define __le64_to_cpu(x) bswap_64(x)
156
157#define __cpu_to_le16(x) bswap_16(x)
158#define __cpu_to_le32(x) bswap_32(x)
159#define __cpu_to_le64(x) bswap_64(x)
160
161#define __constant_le16_to_cpu(x) __ntfs_bswap_constant_16((u16)(x))
162#define __constant_le32_to_cpu(x) __ntfs_bswap_constant_32((u32)(x))
163#define __constant_le64_to_cpu(x) __ntfs_bswap_constant_64((u64)(x))
164
165#define __constant_cpu_to_le16(x) __ntfs_bswap_constant_16((u16)(x))
166#define __constant_cpu_to_le32(x) __ntfs_bswap_constant_32((u32)(x))
167#define __constant_cpu_to_le64(x) __ntfs_bswap_constant_64((u64)(x))
168
169#define __be16_to_cpu(x) (x)
170#define __be32_to_cpu(x) (x)
171#define __be64_to_cpu(x) (x)
172
173#define __cpu_to_be16(x) (x)
174#define __cpu_to_be32(x) (x)
175#define __cpu_to_be64(x) (x)
176
177#define __constant_be16_to_cpu(x) (x)
178#define __constant_be32_to_cpu(x) (x)
179#define __constant_be64_to_cpu(x) (x)
180
181#define __constant_cpu_to_be16(x) (x)
182#define __constant_cpu_to_be32(x) (x)
183#define __constant_cpu_to_be64(x) (x)
184
185#else
186
187#error "You must define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN."
188
189#endif
190
191/* Unsigned from LE to CPU conversion. */
192
193#define le16_to_cpu(x)		(u16)__le16_to_cpu((u16)(x))
194#define le32_to_cpu(x)		(u32)__le32_to_cpu((u32)(x))
195#define le64_to_cpu(x)		(u64)__le64_to_cpu((u64)(x))
196
197#define le16_to_cpup(x)		(u16)__le16_to_cpu(*(const u16*)(x))
198#define le32_to_cpup(x)		(u32)__le32_to_cpu(*(const u32*)(x))
199#define le64_to_cpup(x)		(u64)__le64_to_cpu(*(const u64*)(x))
200
201/* Signed from LE to CPU conversion. */
202
203#define sle16_to_cpu(x)		(s16)__le16_to_cpu((s16)(x))
204#define sle32_to_cpu(x)		(s32)__le32_to_cpu((s32)(x))
205#define sle64_to_cpu(x)		(s64)__le64_to_cpu((s64)(x))
206
207#define sle16_to_cpup(x)	(s16)__le16_to_cpu(*(s16*)(x))
208#define sle32_to_cpup(x)	(s32)__le32_to_cpu(*(s32*)(x))
209#define sle64_to_cpup(x)	(s64)__le64_to_cpu(*(s64*)(x))
210
211/* Unsigned from CPU to LE conversion. */
212
213#define cpu_to_le16(x)		(u16)__cpu_to_le16((u16)(x))
214#define cpu_to_le32(x)		(u32)__cpu_to_le32((u32)(x))
215#define cpu_to_le64(x)		(u64)__cpu_to_le64((u64)(x))
216
217#define cpu_to_le16p(x)		(u16)__cpu_to_le16(*(u16*)(x))
218#define cpu_to_le32p(x)		(u32)__cpu_to_le32(*(u32*)(x))
219#define cpu_to_le64p(x)		(u64)__cpu_to_le64(*(u64*)(x))
220
221/* Signed from CPU to LE conversion. */
222
223#define cpu_to_sle16(x)		(s16)__cpu_to_le16((s16)(x))
224#define cpu_to_sle32(x)		(s32)__cpu_to_le32((s32)(x))
225#define cpu_to_sle64(x)		(s64)__cpu_to_le64((s64)(x))
226
227#define cpu_to_sle16p(x)	(s16)__cpu_to_le16(*(s16*)(x))
228#define cpu_to_sle32p(x)	(s32)__cpu_to_le32(*(s32*)(x))
229#define cpu_to_sle64p(x)	(s64)__cpu_to_le64(*(s64*)(x))
230
231/* Unsigned from BE to CPU conversion. */
232
233#define be16_to_cpu(x)		(u16)__be16_to_cpu((u16)(x))
234#define be32_to_cpu(x)		(u32)__be32_to_cpu((u32)(x))
235#define be64_to_cpu(x)		(u64)__be64_to_cpu((u64)(x))
236
237#define be16_to_cpup(x)		(u16)__be16_to_cpu(*(const u16*)(x))
238#define be32_to_cpup(x)		(u32)__be32_to_cpu(*(const u32*)(x))
239#define be64_to_cpup(x)		(u64)__be64_to_cpu(*(const u64*)(x))
240
241/* Signed from BE to CPU conversion. */
242
243#define sbe16_to_cpu(x)		(s16)__be16_to_cpu((s16)(x))
244#define sbe32_to_cpu(x)		(s32)__be32_to_cpu((s32)(x))
245#define sbe64_to_cpu(x)		(s64)__be64_to_cpu((s64)(x))
246
247#define sbe16_to_cpup(x)	(s16)__be16_to_cpu(*(s16*)(x))
248#define sbe32_to_cpup(x)	(s32)__be32_to_cpu(*(s32*)(x))
249#define sbe64_to_cpup(x)	(s64)__be64_to_cpu(*(s64*)(x))
250
251/* Unsigned from CPU to BE conversion. */
252
253#define cpu_to_be16(x)		(u16)__cpu_to_be16((u16)(x))
254#define cpu_to_be32(x)		(u32)__cpu_to_be32((u32)(x))
255#define cpu_to_be64(x)		(u64)__cpu_to_be64((u64)(x))
256
257#define cpu_to_be16p(x)		(u16)__cpu_to_be16(*(u16*)(x))
258#define cpu_to_be32p(x)		(u32)__cpu_to_be32(*(u32*)(x))
259#define cpu_to_be64p(x)		(u64)__cpu_to_be64(*(u64*)(x))
260
261/* Signed from CPU to BE conversion. */
262
263#define cpu_to_sbe16(x)		(s16)__cpu_to_be16((s16)(x))
264#define cpu_to_sbe32(x)		(s32)__cpu_to_be32((s32)(x))
265#define cpu_to_sbe64(x)		(s64)__cpu_to_be64((s64)(x))
266
267#define cpu_to_sbe16p(x)	(s16)__cpu_to_be16(*(s16*)(x))
268#define cpu_to_sbe32p(x)	(s32)__cpu_to_be32(*(s32*)(x))
269#define cpu_to_sbe64p(x)	(s64)__cpu_to_be64(*(s64*)(x))
270
271/* Constant endianness conversion defines. */
272
273#define const_le16_to_cpu(x)	((u16) __constant_le16_to_cpu(x))
274#define const_le32_to_cpu(x)	((u32) __constant_le32_to_cpu(x))
275#define const_le64_to_cpu(x)	((u64) __constant_le64_to_cpu(x))
276
277#define const_cpu_to_le16(x)	((le16) __constant_cpu_to_le16(x))
278#define const_cpu_to_le32(x)	((le32) __constant_cpu_to_le32(x))
279#define const_cpu_to_le64(x)	((le64) __constant_cpu_to_le64(x))
280
281#define const_sle16_to_cpu(x)	((s16) __constant_le16_to_cpu((le16) x))
282#define const_sle32_to_cpu(x)	((s32) __constant_le32_to_cpu((le32) x))
283#define const_sle64_to_cpu(x)	((s64) __constant_le64_to_cpu((le64) x))
284
285#define const_cpu_to_sle16(x)	((sle16) __constant_cpu_to_le16((u16) x))
286#define const_cpu_to_sle32(x)	((sle32) __constant_cpu_to_le32((u32) x))
287#define const_cpu_to_sle64(x)	((sle64) __constant_cpu_to_le64((u64) x))
288
289#define const_be16_to_cpu(x)	((u16) __constant_be16_to_cpu(x)))
290#define const_be32_to_cpu(x)	((u32) __constant_be32_to_cpu(x)))
291#define const_be64_to_cpu(x)	((u64) __constant_be64_to_cpu(x)))
292
293#define const_cpu_to_be16(x)	((be16) __constant_cpu_to_be16(x))
294#define const_cpu_to_be32(x)	((be32) __constant_cpu_to_be32(x))
295#define const_cpu_to_be64(x)	((be64) __constant_cpu_to_be64(x))
296
297#define const_sbe16_to_cpu(x)	((s16) __constant_be16_to_cpu((be16) x))
298#define const_sbe32_to_cpu(x)	((s32) __constant_be32_to_cpu((be32) x))
299#define const_sbe64_to_cpu(x)	((s64) __constant_be64_to_cpu((be64) x))
300
301#define const_cpu_to_sbe16(x)	((sbe16) __constant_cpu_to_be16((u16) x))
302#define const_cpu_to_sbe32(x)	((sbe32) __constant_cpu_to_be32((u32) x))
303#define const_cpu_to_sbe64(x)	((sbe64) __constant_cpu_to_be64((u64) x))
304
305#endif /* defined _NTFS_ENDIANS_H */
306