blob: 7b666eca5656ebb491d05c0b4e54c02ed21f7634 [file] [log] [blame]
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -04001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _RBENDIAN_H_
22#define _RBENDIAN_H_
23
24#include "config.h"
Michael Sevakis25f73d62014-08-26 15:53:49 -040025
William Wilgus0f5f5c32018-12-08 03:19:14 -060026#ifdef OS_USE_BYTESWAP_H
William Wilgus94506892018-12-05 21:44:09 -060027#include <byteswap.h>
28#endif
29
Michael Sevakis25f73d62014-08-26 15:53:49 -040030#ifndef __MINGW32__
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -040031#include <endian.h>
Michael Sevakis25f73d62014-08-26 15:53:49 -040032#endif
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -040033
34/* clear these out since we redefine them to be truely constant compatible */
35#undef swap16
36#undef swap32
37#undef swap64
38
39#undef letoh16
40#undef letoh32
41#undef letoh64
42#undef htole16
43#undef htole32
44#undef htole64
45#undef betoh16
46#undef betoh32
47#undef betoh64
48#undef htobe16
49#undef htobe32
50#undef htobe64
51
Michael Sevakis25f73d62014-08-26 15:53:49 -040052/* static/generic endianness conversion */
53#define SWAP16_CONST(x) \
54 ((typeof(x))( ((uint16_t)(x) >> 8) | ((uint16_t)(x) << 8) ))
55
56#define SWAP32_CONST(x) \
57 ((typeof(x))( (((uint32_t)(x) & 0xff000000) >> 24) | \
58 (((uint32_t)(x) & 0x00ff0000) >> 8) | \
59 (((uint32_t)(x) & 0x0000ff00) << 8) | \
60 (((uint32_t)(x) & 0x000000ff) << 24) ))
61
62#define SWAP64_CONST(x) \
63 ((typeof(x))( (((uint64_t)(x) & 0xff00000000000000ull) >> 56) | \
64 (((uint64_t)(x) & 0x00ff000000000000ull) >> 40) | \
65 (((uint64_t)(x) & 0x0000ff0000000000ull) >> 24) | \
66 (((uint64_t)(x) & 0x000000ff00000000ull) >> 8) | \
67 (((uint64_t)(x) & 0x00000000ff000000ull) << 8) | \
68 (((uint64_t)(x) & 0x0000000000ff0000ull) << 24) | \
69 (((uint64_t)(x) & 0x000000000000ff00ull) << 40) | \
70 (((uint64_t)(x) & 0x00000000000000ffull) << 56) ))
71
72#define SWAP_ODD_EVEN32_CONST(x) \
73 ((typeof(x))( ((uint32_t)SWAP16_CONST((uint32_t)(x) >> 16) << 16) | \
74 SWAP16_CONST((uint32_t)(x))) )
75
76#define SWAW32_CONST(x) \
77 ((typeof(x))( ((uint32_t)(x) << 16) | ((uint32_t)(x) >> 16) ))
78
79
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -040080#ifndef __ENDIAN_H_NATIVE_RB
81
82#if defined (__bswap_16)
83 #define __swap16_os(x) __bswap_16(x)
84 #define __swap32_os(x) __bswap_32(x)
85 #define __swap64_os(x) __bswap_64(x)
Franklin Weied652642017-01-07 15:29:57 -050086#elif defined (bswap_16)
87 #define __swap16_os(x) bswap_16(x)
88 #define __swap32_os(x) bswap_32(x)
89 #define __swap64_os(x) bswap_64(x)
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -040090#elif defined (__swap16)
91 #define __swap16_os(x) __swap16(x)
92 #define __swap32_os(x) __swap32(x)
93 #define __swap64_os(x) __swap64(x)
Franklin Weied652642017-01-07 15:29:57 -050094#elif defined (swap16)
95 #define __swap16_os(x) swap16(x)
96 #define __swap32_os(x) swap32(x)
97 #define __swap64_os(x) swap64(x)
Thomas Jarosch3add6c72014-12-17 23:29:44 +010098#elif defined (__MINGW32__) || (CONFIG_PLATFORM & PLATFORM_MAEMO)
Michael Sevakis25f73d62014-08-26 15:53:49 -040099 /* kinda hacky but works */
100 #define __swap16_os(x) SWAP16_CONST(x)
101 #define __swap32_os(x) SWAP32_CONST(x)
102 #define __swap64_os(x) SWAP64_CONST(x)
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -0400103#else
104 #error "Missing OS swap defines."
105#endif
106
Michael Sevakis25f73d62014-08-26 15:53:49 -0400107/* wrap these because they aren't always compatible with compound initializers */
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -0400108static FORCE_INLINE uint16_t swap16_hw(uint16_t x)
109 { return __swap16_os(x); }
110static FORCE_INLINE uint32_t swap32_hw(uint32_t x)
111 { return __swap32_os(x); }
112static FORCE_INLINE uint64_t swap64_hw(uint64_t x)
113 { return __swap64_os(x); }
114
115#endif /* __ENDIAN_H_NATIVE_RB */
116
117#if defined(NEED_GENERIC_BYTESWAPS) || !defined(__ENDIAN_H_NATIVE_RB)
118/* these are uniquely ours it seems */
119static inline uint32_t swap_odd_even32_hw(uint32_t value)
120 /*
121 * result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
122 * result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
123 */
124{
125 uint32_t t = value & 0xff00ff00;
126 return (t >> 8) | ((t ^ value) << 8);
127}
128
129static inline uint32_t swaw32_hw(uint32_t value)
130 /*
131 * result[31..16] = value[15.. 0];
132 * result[15.. 0] = value[31..16];
133 */
134{
135 return (value >> 16) | (value << 16);
136}
137#endif /* Generic */
138
Michael Sevakis6ffb8ff2014-08-24 19:46:43 -0400139/* select best method based upon whether x is a constant expression */
140#define swap16(x) \
141 ( __builtin_constant_p(x) ? SWAP16_CONST(x) : (typeof(x))swap16_hw(x) )
142
143#define swap32(x) \
144 ( __builtin_constant_p(x) ? SWAP32_CONST(x) : (typeof(x))swap32_hw(x) )
145
146#define swap64(x) \
147 ( __builtin_constant_p(x) ? SWAP64_CONST(x) : (typeof(x))swap64_hw(x) )
148
149#define swap_odd_even32(x) \
150 ( __builtin_constant_p(x) ? SWAP_ODD_EVEN32_CONST(x) : (typeof(x))swap_odd_even32_hw(x) )
151
152#define swaw32(x) \
153 ( __builtin_constant_p(x) ? SWAW32_CONST(x) : (typeof(x))swaw32_hw(x) )
154
155#if defined(ROCKBOX_LITTLE_ENDIAN)
156 #define letoh16(x) (x)
157 #define letoh32(x) (x)
158 #define letoh64(x) (x)
159 #define htole16(x) (x)
160 #define htole32(x) (x)
161 #define htole64(x) (x)
162 #define betoh16(x) swap16(x)
163 #define betoh32(x) swap32(x)
164 #define betoh64(x) swap64(x)
165 #define htobe16(x) swap16(x)
166 #define htobe32(x) swap32(x)
167 #define htobe64(x) swap64(x)
168 #define swap_odd_even_be32(x) (x)
169 #define swap_odd_even_le32(x) swap_odd_even32(x)
170#elif defined(ROCKBOX_BIG_ENDIAN)
171 #define letoh16(x) swap16(x)
172 #define letoh32(x) swap32(x)
173 #define letoh64(x) swap64(x)
174 #define htole16(x) swap16(x)
175 #define htole32(x) swap32(x)
176 #define htole64(x) swap64(x)
177 #define betoh16(x) (x)
178 #define betoh32(x) (x)
179 #define betoh64(x) (x)
180 #define htobe16(x) (x)
181 #define htobe32(x) (x)
182 #define htobe64(x) (x)
183 #define swap_odd_even_be32(x) swap_odd_even32(x)
184 #define swap_odd_even_le32(x) (x)
185#else
186 #error "Unknown endianness!"
187#endif
188
189#endif /* _RBENDIAN_H_ */