Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / diskimage / include / endian.h
blob9846926620fef5ded6b995e7da158f1d3c6e0ba8
1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
2 **
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
5 ** are met:
6 **
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
9 **
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
27 #ifndef ENDIAN_H
28 #define ENDIAN_H
30 #include <stdint.h>
32 #ifndef WORDS_BIGENDIAN
33 #ifdef __AROS__
34 #include_next <endian.h>
35 #if _BYTE_ORDER == _BIG_ENDIAN
36 #define WORDS_BIGENDIAN 1
37 #elif _BYTE_ORDER == _LITTLE_ENDIAN
38 #define WORDS_BIGENDIAN 0
39 #else
40 #error "Unsupported endian format."
41 #endif
42 #else
43 #define WORDS_BIGENDIAN 1
44 #endif
45 #endif
47 #define swap16(x) ((((uint16_t)(x) & 0x00ff)<<8)| \
48 (((uint16_t)(x) & 0xff00)>>8))
49 #define swap32(x) ((((uint32_t)(x) & 0x000000ff)<<24)| \
50 (((uint32_t)(x) & 0x0000ff00)<<8)| \
51 (((uint32_t)(x) & 0x00ff0000)>>8)| \
52 (((uint32_t)(x) & 0xff000000)>>24))
53 #define swap64(x) ((uint64_t)swap32((uint64_t)(x) >> 32)|((uint64_t)swap32(x) << 32))
54 #define rswap16(p) swap16(*(uint16_t *)(p))
55 #define rswap32(p) swap32(*(uint32_t *)(p))
56 #define rswap64(p) swap64(*(uint64_t *)(p))
57 #define wswap16(p,x) (*(uint16_t *)(p) = swap16(x))
58 #define wswap32(p,x) (*(uint32_t *)(p) = swap32(x))
59 #define wswap64(p,x) (*(uint64_t *)(p) = swap64(x))
61 #if WORDS_BIGENDIAN
62 #define h2be16(x) (x)
63 #define h2be32(x) (x)
64 #define h2be64(x) (x)
65 #define h2le16(x) swap16(x)
66 #define h2le32(x) swap32(x)
67 #define h2le64(x) swap64(x)
68 #define rbe16(p) (*(uint16_t *)(p))
69 #define rbe32(p) (*(uint32_t *)(p))
70 #define rbe64(p) (*(uint64_t *)(p))
71 #define rle16(p) rswap16(p)
72 #define rle32(p) rswap32(p)
73 #define rle64(p) rswap64(p)
74 #define wbe16(p,x) (*(uint16_t *)(p) = (x))
75 #define wbe32(p,x) (*(uint32_t *)(p) = (x))
76 #define wbe64(p,x) (*(uint64_t *)(p) = (x))
77 #define wle16(p,x) wswap16(p,x)
78 #define wle32(p,x) wswap32(p,x)
79 #define wle64(p,x) wswap64(p,x)
80 #else
81 #define h2le16(x) (x)
82 #define h2le32(x) (x)
83 #define h2le64(x) (x)
84 #define h2be16(x) swap16(x)
85 #define h2be32(x) swap32(x)
86 #define h2be64(x) swap64(x)
87 #define rle16(p) (*(uint16_t *)(p))
88 #define rle32(p) (*(uint32_t *)(p))
89 #define rle64(p) (*(uint64_t *)(p))
90 #define rbe16(p) rswap16(p)
91 #define rbe32(p) rswap32(p)
92 #define rbe64(p) rswap64(p)
93 #define wle16(p,x) (*(uint16_t *)(p) = (x))
94 #define wle32(p,x) (*(uint32_t *)(p) = (x))
95 #define wle64(p,x) (*(uint64_t *)(p) = (x))
96 #define wbe16(p,x) wswap16(p,x)
97 #define wbe32(p,x) wswap32(p,x)
98 #define wbe64(p,x) wswap64(p,x)
99 #endif
101 #if defined(__VBCC__) && defined(__PPC__)
103 #undef swap16
104 #undef swap32
105 #undef swap64
107 uint16_t swap16(__reg("r4") uint16_t) =
108 "\trlwinm\t3,4,8,16,24\n"
109 "\trlwimi\t3,4,24,24,31";
111 uint32_t swap32(__reg("r4") uint32_t) =
112 "\trlwinm\t3,4,24,0,31\n"
113 "\trlwimi\t3,4,8,8,15\n"
114 "\trlwimi\t3,4,8,24,31";
116 uint64_t swap64(__reg("r5/r6") uint64_t) =
117 "\trlwinm\t4,5,24,0,31\n"
118 "\trlwinm\t3,6,24,0,31\n"
119 "\trlwimi\t4,5,8,8,15\n"
120 "\trlwimi\t3,6,8,8,15\n"
121 "\trlwimi\t4,5,8,24,31\n"
122 "\trlwimi\t3,6,8,24,31";
124 #undef rswap16
125 #undef rswap32
126 #undef rswap64
128 uint16_t rswap16(__reg("r3") void *) =
129 "\tlhbrx\t3,0,3";
131 uint32_t rswap32(__reg("r3") void *) =
132 "\tlwbrx\t3,0,3";
134 uint64_t rswap64(__reg("r3") void *) =
135 "\taddi\t5,3,4\n" // r5 = r3 + 4
136 "\tlwbrx\t4,0,3\n"
137 "\tlwbrx\t3,0,5";
139 #undef wswap16
140 #undef wswap32
141 #undef wswap64
143 void wswap16(__reg("r3") void *, __reg("r4") uint16_t) =
144 "\tsthbrx\t4,0,3";
146 void wswap32(__reg("r3") void *, __reg("r4") uint32_t) =
147 "\tstwbrx\t4,0,3";
149 void wswap64(__reg("r3") void *, __reg("r5/r6") uint64_t) =
150 "\taddi\t4,3,4\n" // r4 = r3 + 4
151 "\tstwbrx\t6,0,3\n"
152 "\tstwbrx\t5,0,4";
154 #endif /* defined(__VBCC__) && defined(__PPC__) */
156 #if defined(__GNUC__) && defined(__PPC__)
158 #undef swap16
159 #undef swap32
160 #undef swap64
162 static inline uint32_t swap16(uint16_t x) {
163 uint32_t res;
164 asm("rlwinm %0,%1,8,16,23\n"
165 "\trlwimi %0,%1,24,24,31"
166 : "=&r" (res)
167 : "r" (x));
168 return res;
171 static inline uint32_t swap32(uint32_t x) {
172 uint32_t res;
173 asm("rlwinm %0,%1,24,0,31\n"
174 "\trlwimi %0,%1,8,8,15\n"
175 "\trlwimi %0,%1,8,24,31"
176 : "=&r" (res)
177 : "r" (x));
178 return res;
181 static inline uint64_t swap64(uint64_t x) {
182 uint64_t res;
183 asm("rlwinm %L0,%H1,24,0,31\n"
184 "\trlwinm %H0,%L1,24,0,31\n"
185 "\trlwimi %L0,%H1,8,8,15\n"
186 "\trlwimi %H0,%L1,8,8,15\n"
187 "\trlwimi %L0,%H1,8,24,31\n"
188 "\trlwimi %H0,%L1,8,24,31"
189 : "=&r" (res)
190 : "r" (x));
191 return res;
194 #undef rswap16
195 #undef rswap32
196 #undef rswap64
198 static inline uint32_t rswap16(const void *p) {
199 uint32_t res;
200 const uint16_t *p0 = p;
201 asm("lhbrx %0,%y1"
202 : "=r" (res)
203 : "Z" (*p0));
204 return res;
207 static inline uint32_t rswap32(const void *p) {
208 uint32_t res;
209 const uint32_t *p0 = p;
210 asm("lwbrx %0,%y1"
211 : "=r" (res)
212 : "Z" (*p0));
213 return res;
216 static inline uint64_t rswap64(const void *p) {
217 uint64_t res;
218 const uint32_t *p0 = p;
219 const uint32_t *p1 = p0+1;
220 asm("lwbrx %L0,%y1\n"
221 "\tlwbrx %H0,%y2"
222 : "=&r" (res)
223 : "Z" (*p0), "Z" (*p1));
224 return res;
227 #undef wswap16
228 #undef wswap32
229 #undef wswap64
231 static inline void wswap16(void *p, uint16_t x) {
232 uint16_t *p0 = p;
233 asm("sthbrx %1,%y0"
235 : "Z" (*p0), "r" (x));
238 static inline void wswap32(void *p, uint32_t x) {
239 uint32_t *p0 = p;
240 asm("stwbrx %1,%y0"
242 : "Z" (*p0), "r" (x));
245 static inline void wswap64(void *p, uint64_t x) {
246 uint32_t *p0 = p;
247 uint32_t *p1 = p0+1;
248 asm("stwbrx %L2,%y0\n"
249 "\tstwbrx %H2,%y1"
251 : "Z" (*p0), "Z" (*p1), "r" (x));
253 #endif /* defined(__GNUC__) && defined(__PPC__) */
255 #if defined(__GNUC__) && (defined(__i386__) || defined(__i486__))
257 #ifndef USE_BSWAP
258 #define USE_BSWAP 1
259 #endif
261 #undef swap16
262 #undef swap32
264 static inline uint16_t swap16(uint16_t x) {
265 uint16_t res;
266 asm("rorw $8,%w0"
267 : "=r" (res)
268 : "0" (x)
269 : "cc");
270 return res;
273 static inline uint32_t swap32(uint32_t x) {
274 uint32_t res;
275 #if USE_BSWAP
276 asm("bswap %0"
277 : "=r" (res)
278 : "0" (x));
279 #else
280 asm("rorw $8,%w0\n"
281 "\trorl $16,%0\n"
282 "\trorw $8,%w0"
283 : "=r" (res)
284 : "0" (x)
285 : "cc");
286 #endif
287 return res;
290 #endif
292 #if defined(__VBCC__) && defined(__M68K__)
294 #undef swap16
295 #undef swap32
296 #undef swap64
298 static inline uint16_t swap16(__reg("d0") uint16_t) =
299 "\trol.w\t#8,d0";
301 static inline uint32_t swap32(__reg("d0") uint32_t) =
302 "\trol.w\t#8,d0\n"
303 "\tswap\td0\n"
304 "\trol.w\t#8,d0";
306 static inline uint64_t swap64(__reg("d0/d1") uint64_t) =
307 "\trol.w\t#8,d0\n"
308 "\trol.w\t#8,d1\n"
309 "\tswap\td0\n"
310 "\tswap\td1\n"
311 "\trol.w\t#8,d0\n"
312 "\trol.w\t#8,d1\n"
313 "\teor.l\td0,d1\n"
314 "\teor.l\td1,d0\n"
315 "\teor.l\td0,d1";
317 #undef rswap64
319 static inline uint64_t rswap64(__reg("a0") void *) =
320 "\tmove.l\t4(a0),d0\n"
321 "\tmove.l\t(a0),d1\n"
322 "\trol.w\t#8,d0\n"
323 "\trol.w\t#8,d1\n"
324 "\tswap\td0\n"
325 "\tswap\td1\n"
326 "\trol.w\t#8,d0\n"
327 "\trol.w\t#8,d1";
329 #undef wswap64
331 static inline uint64_t wswap64(__reg("a0") void *, __reg("d0/d1") uint64_t) =
332 "\trol.w\t#8,d0\n"
333 "\trol.w\t#8,d1\n"
334 "\tswap\td0\n"
335 "\tswap\td1\n"
336 "\trol.w\t#8,d0\n"
337 "\trol.w\t#8,d1\n"
338 "\tmove.l\td0,4(a0)\n"
339 "\tmove.l\td1,(a0)";
341 #endif /* defined(__VBCC__) && defined(__M68K__) */
343 #endif /* ENDIAN_H */