Import of openhackware-0.4.1
[openhackware.git] / src / libc / include / endian.h
blob87fc546073378d5231efa115b2470dfd98eb08fd
1 /*
2 * <endian.h>
4 * Open Hack'Ware BIOS: provides all common endianness conversions functions
5 *
6 * Copyright (c) 2004-2005 Jocelyn Mayer
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License V2
10 * as published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * This file provides:
23 * void cpu_to_be16p (uint16_t *outp, uint16_t in);
24 * void cpu_to_be32p (uint32_t *outp, uint32_t in);
25 * void cpu_to_be64p (uint64_t *outp, uint64_t in);
26 * void cpu_to_le16p (uint16_t *outp, uint16_t in);
27 * void cpu_to_le32p (uint32_t *outp, uint32_t in);
28 * void cpu_to_le64p (uint64_t *outp, uint64_t in);
29 * void endian_to_cpu16p (uint16_t *outp, uint16_t in, endian_t endian);
30 * void endian_to_cpu32p (uint32_t *outp, uint32_t in, endian_t endian);
31 * void endian_to_cpu64p (uint64_t *outp, uint64_t in, endian_t endian);
32 * void cpu16_to_endianp (uint16_t *outp, uint16_t in, endian_t endian);
33 * void cpu32_to_endianp (uint32_t *outp, uint32_t in, endian_t endian);
34 * void cpu64_to_endianp (uint64_t *outp, uint64_t in, endian_t endian);
38 #if !defined (__OHW_ENDIAN_H__)
39 #define __OHW_ENDIAN_H__
41 #include <stdint.h>
43 typedef enum endian_t endian_t;
44 enum endian_t {
45 ENDIAN_1234 = 0,
46 ENDIAN_4321,
47 ENDIAN_3412,
48 ENDIAN_2143,
51 /* Generic endian conversion functions */
52 static inline void generic_cpu_swap16p (uint16_t *outp, uint16_t in)
54 *outp = ((in & 0xFF00) >> 8) | ((in & 0x00FF) << 8);
57 static inline void generic_cpu_swap32p (uint32_t *outp, uint32_t in)
59 *outp = ((in & 0xFF000000) >> 24) | ((in & 0x00FF0000) >> 8) |
60 ((in & 0x0000FF00) << 8) | ((in & 0x000000FF) << 24);
63 static inline void generic_cpu_swap64p (uint64_t *outp, uint64_t in)
65 *outp = ((in & 0xFF00000000000000ULL) >> 56) |
66 ((in & 0x00FF000000000000ULL) >> 40) |
67 ((in & 0x0000FF0000000000ULL) >> 24) |
68 ((in & 0x000000FF00000000ULL) >> 8) |
69 ((in & 0x00000000FF000000ULL) << 8) |
70 ((in & 0x0000000000FF0000ULL) << 24) |
71 ((in & 0x000000000000FF00ULL) << 40) |
72 ((in & 0x00000000000000FFULL) << 56);
75 static inline void generic_cpu_swap64p_32 (uint64_t *outp, uint64_t in)
77 uint32_t *_outp = (uint32_t *)outp;
79 generic_cpu_swap32p(_outp, in);
80 generic_cpu_swap32p(_outp + 1, in >> 32);
83 #if defined (__i386__)
85 #define __CPU_ENDIAN_4321__
86 #define __CPU_LENGTH_32__
88 #elif defined (__x86_64__)
90 #define __CPU_ENDIAN_4321__
91 #define __CPU_LENGTH_64__
93 #elif defined (__powerpc__)
95 #define __CPU_ENDIAN_1234__
96 #define __CPU_LENGTH_32__
98 #define __HAVE_CPU_SWAP16P__
99 static inline void cpu_swap16p (uint16_t *outp, uint16_t in)
101 __asm__ __volatile__ ("sthbrx %4, 0(%3)");
104 #define __HAVE_CPU_SWAP32P__
105 static inline void cpu_swap32p (uint32_t *outp, uint32_t in)
107 __asm__ __volatile__ ("stwbrx %4, 0(%3)");
110 #define __HAVE_CPU_SWAP64P__
111 static inline void cpu_swap64p (uint64_t *outp, uint64_t in)
113 return generic_cpu_swap64p_32(outp, in);
116 #else
118 #error "unsupported CPU architecture"
120 #endif
122 /* Use generic swap function if no cpu specific were provided */
123 #if !defined (__HAVE_CPU_SWAP16P__)
124 static inline void cpu_swap16p (uint16_t *outp, uint16_t in)
126 generic_cpu_swap16p(outp, in);
128 #endif
130 #if !defined (__HAVE_CPU_SWAP32P__)
131 static inline void cpu_swap32p (uint32_t *outp, uint32_t in)
133 generic_cpu_swap32p(outp, in);
135 #endif
137 #if !defined (__HAVE_CPU_SWAP64P__)
138 static inline void cpu_swap64p (uint64_t *outp, uint64_t in)
140 #if defined (__CPU_LENGTH_64__)
141 generic_cpu_swap64p(outp, in);
142 #elif defined (__CPU_LENGTH_32__)
143 generic_cpu_swap64p_32(outp, in);
144 #else
145 #error "Don't know how to make 64 bits swapping on this arch"
146 #endif
148 #endif
150 static inline void cpu_nswap16p (uint16_t *outp, uint16_t in)
152 *outp = in;
155 static inline void cpu_nswap32p (uint32_t *outp, uint32_t in)
157 *outp = in;
160 static inline void cpu_nswap64p (uint64_t *outp, uint64_t in)
162 *outp = in;
165 static inline void _endian_be16_p (uint16_t *outp, uint16_t in,
166 endian_t endian)
168 switch (endian) {
169 case ENDIAN_4321:
170 case ENDIAN_2143:
171 cpu_swap16p(outp, in);
172 break;
173 case ENDIAN_1234:
174 case ENDIAN_3412:
175 cpu_nswap16p(outp, in);
176 break;
180 static inline void _endian_be32_p (uint32_t *outp, uint32_t in,
181 endian_t endian)
183 switch (endian) {
184 case ENDIAN_4321:
185 cpu_swap32p(outp, in);
186 break;
187 case ENDIAN_1234:
188 cpu_nswap32p(outp, in);
189 break;
190 case ENDIAN_2143:
191 /* TODO */
192 break;
193 case ENDIAN_3412:
194 /* TODO */
195 break;
199 static inline void _endian_be64_p (uint64_t *outp, uint64_t in,
200 endian_t endian)
202 switch (endian) {
203 case ENDIAN_4321:
204 cpu_swap64p(outp, in);
205 break;
206 case ENDIAN_1234:
207 cpu_nswap64p(outp, in);
208 break;
209 case ENDIAN_2143:
210 /* TODO */
211 break;
212 case ENDIAN_3412:
213 /* TODO */
214 break;
218 static inline void _endian_le16_p (uint16_t *outp, uint16_t in,
219 endian_t endian)
221 switch (endian) {
222 case ENDIAN_4321:
223 case ENDIAN_2143:
224 cpu_nswap16p(outp, in);
225 break;
226 case ENDIAN_1234:
227 case ENDIAN_3412:
228 cpu_swap16p(outp, in);
229 break;
233 static inline void _endian_le32_p (uint32_t *outp, uint32_t in,
234 endian_t endian)
236 switch (endian) {
237 case ENDIAN_4321:
238 cpu_nswap32p(outp, in);
239 break;
240 case ENDIAN_1234:
241 cpu_swap32p(outp, in);
242 break;
243 case ENDIAN_2143:
244 /* TODO */
245 break;
246 case ENDIAN_3412:
247 /* TODO */
248 break;
252 static inline void _endian_le64_p (uint64_t *outp, uint64_t in,
253 endian_t endian)
255 switch (endian) {
256 case ENDIAN_4321:
257 cpu_nswap64p(outp, in);
258 break;
259 case ENDIAN_1234:
260 cpu_swap64p(outp, in);
261 break;
262 case ENDIAN_2143:
263 /* TODO */
264 break;
265 case ENDIAN_3412:
266 /* TODO */
267 break;
271 static inline void endian_to_be16p (uint16_t *outp, uint16_t in,
272 endian_t endian)
274 _endian_be16_p(outp, in, endian);
277 static inline void endian_to_be32p (uint32_t *outp, uint32_t in,
278 endian_t endian)
280 _endian_be32_p(outp, in, endian);
283 static inline void endian_to_be64p (uint64_t *outp, uint64_t in,
284 endian_t endian)
286 _endian_be64_p(outp, in, endian);
289 static inline void endian_to_le16p (uint16_t *outp, uint16_t in,
290 endian_t endian)
292 _endian_le16_p(outp, in, endian);
295 static inline void endian_to_le32p (uint32_t *outp, uint32_t in,
296 endian_t endian)
298 _endian_le32_p(outp, in, endian);
301 static inline void endian_to_le64p (uint64_t *outp, uint64_t in,
302 endian_t endian)
304 _endian_le64_p(outp, in, endian);
307 static inline void be16_to_endianp (uint16_t *outp, uint16_t in,
308 endian_t endian)
310 _endian_be16_p(outp, in, endian);
313 static inline void be32_to_endianp (uint32_t *outp, uint32_t in,
314 endian_t endian)
316 _endian_be32_p(outp, in, endian);
319 static inline void be64_to_endianp (uint64_t *outp, uint64_t in,
320 endian_t endian)
322 _endian_be64_p(outp, in, endian);
325 static inline void le16_to_endianp (uint16_t *outp, uint16_t in,
326 endian_t endian)
328 _endian_le16_p(outp, in, endian);
331 static inline void le32_to_endianp (uint32_t *outp, uint32_t in,
332 endian_t endian)
334 _endian_le32_p(outp, in, endian);
337 static inline void le64_to_endianp (uint64_t *outp, uint64_t in,
338 endian_t endian)
340 _endian_le64_p(outp, in, endian);
343 #if defined (__CPU_ENDIAN_4321__)
345 static inline void cpu_to_be16p (uint16_t *outp, uint16_t in)
347 cpu_swap16p(outp, in);
350 static inline void cpu_to_be32p (uint32_t *outp, uint32_t in)
352 cpu_swap32p(outp, in);
355 static inline void cpu_to_be64p (uint64_t *outp, uint64_t in)
357 cpu_swap64p(outp, in);
360 static inline void cpu_to_le16p (uint16_t *outp, uint16_t in)
362 cpu_nswap16p(outp, in);
365 static inline void cpu_to_le32p (uint32_t *outp, uint32_t in)
367 cpu_nswap32p(outp, in);
370 static inline void cpu_to_le64p (uint64_t *outp, uint64_t in)
372 cpu_nswap64p(outp, in);
375 static inline void be16_to_cpup (uint16_t *outp, uint16_t in)
377 cpu_swap16p(outp, in);
380 static inline void be32_to_cpup (uint32_t *outp, uint32_t in)
382 cpu_swap32p(outp, in);
385 static inline void be64_to_cpup (uint64_t *outp, uint64_t in)
387 cpu_swap64p(outp, in);
390 static inline void le16_to_cpup (uint16_t *outp, uint16_t in)
392 cpu_nswap16p(outp, in);
395 static inline void le32_to_cpup (uint32_t *outp, uint32_t in)
397 cpu_nswap32p(outp, in);
400 static inline void le64_to_cpup (uint64_t *outp, uint64_t in)
402 cpu_nswap64p(outp, in);
405 static inline void endian_to_cpu16p (uint16_t *outp, uint16_t in,
406 endian_t endian)
408 endian_to_le16p(outp, in, endian);
411 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
412 endian_t endian)
414 endian_to_le32p(outp, in, endian);
417 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
418 endian_t endian)
420 endian_to_le64p(outp, in, endian);
423 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
424 endian_t endian)
426 le16_to_endianp(outp, in, endian);
429 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
430 endian_t endian)
432 le32_to_endianp(outp, in, endian);
435 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
436 endian_t endian)
438 le64_to_endianp(outp, in, endian);
441 #elif defined (__CPU_ENDIAN_1234__)
443 static inline void cpu_to_be16p (uint16_t *outp, uint16_t in)
445 cpu_nswap16p(outp, in);
448 static inline void cpu_to_be32p (uint32_t *outp, uint32_t in)
450 cpu_nswap32p(outp, in);
453 static inline void cpu_to_be64p (uint64_t *outp, uint64_t in)
455 cpu_nswap64p(outp, in);
458 static inline void cpu_to_le16p (uint16_t *outp, uint16_t in)
460 cpu_swap16p(outp, in);
463 static inline void cpu_to_le32p (uint32_t *outp, uint32_t in)
465 cpu_swap32p(outp, in);
468 static inline void cpu_to_le64p (uint64_t *outp, uint64_t in)
470 cpu_swap64p(outp, in);
473 static inline void endian_to_cpu16p (uint16_t *outp, uint16_t in,
474 endian_t endian)
476 endian_to_be16p(outp, in, endian);
479 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
480 endian_t endian)
482 endian_to_be32p(outp, in, endian);
485 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
486 endian_t endian)
488 endian_to_be64p(outp, in, endian);
491 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
492 endian_t endian)
494 be16_to_endianp(outp, in, endian);
497 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
498 endian_t endian)
500 be32_to_endianp(outp, in, endian);
503 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
504 endian_t endian)
506 be64_to_endianp(outp, in, endian);
509 #else /* 2143 / 3412 */
510 /* TODO */
511 #error "TODO"
512 #endif
514 #endif /* !defined (__OHW_ENDIAN_H__) */