4 * Open Hack'Ware BIOS: provides all common endianness conversions functions
6 * Copyright (c) 2004-2005 Jocelyn Mayer
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
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__
43 typedef enum endian_t endian_t;
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__) || defined (_ARCH_PPC)
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);
118 #error "unsupported CPU architecture"
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);
130 #if !defined (__HAVE_CPU_SWAP32P__)
131 static inline void cpu_swap32p (uint32_t *outp, uint32_t in)
133 generic_cpu_swap32p(outp, in);
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);
145 #error "Don't know how to make 64 bits swapping on this arch"
150 static inline void cpu_nswap16p (uint16_t *outp, uint16_t in)
155 static inline void cpu_nswap32p (uint32_t *outp, uint32_t in)
160 static inline void cpu_nswap64p (uint64_t *outp, uint64_t in)
165 static inline void _endian_be16_p (uint16_t *outp, uint16_t in,
171 cpu_swap16p(outp, in);
175 cpu_nswap16p(outp, in);
180 static inline void _endian_be32_p (uint32_t *outp, uint32_t in,
185 cpu_swap32p(outp, in);
188 cpu_nswap32p(outp, in);
199 static inline void _endian_be64_p (uint64_t *outp, uint64_t in,
204 cpu_swap64p(outp, in);
207 cpu_nswap64p(outp, in);
218 static inline void _endian_le16_p (uint16_t *outp, uint16_t in,
224 cpu_nswap16p(outp, in);
228 cpu_swap16p(outp, in);
233 static inline void _endian_le32_p (uint32_t *outp, uint32_t in,
238 cpu_nswap32p(outp, in);
241 cpu_swap32p(outp, in);
252 static inline void _endian_le64_p (uint64_t *outp, uint64_t in,
257 cpu_nswap64p(outp, in);
260 cpu_swap64p(outp, in);
271 static inline void endian_to_be16p (uint16_t *outp, uint16_t in,
274 _endian_be16_p(outp, in, endian);
277 static inline void endian_to_be32p (uint32_t *outp, uint32_t in,
280 _endian_be32_p(outp, in, endian);
283 static inline void endian_to_be64p (uint64_t *outp, uint64_t in,
286 _endian_be64_p(outp, in, endian);
289 static inline void endian_to_le16p (uint16_t *outp, uint16_t in,
292 _endian_le16_p(outp, in, endian);
295 static inline void endian_to_le32p (uint32_t *outp, uint32_t in,
298 _endian_le32_p(outp, in, endian);
301 static inline void endian_to_le64p (uint64_t *outp, uint64_t in,
304 _endian_le64_p(outp, in, endian);
307 static inline void be16_to_endianp (uint16_t *outp, uint16_t in,
310 _endian_be16_p(outp, in, endian);
313 static inline void be32_to_endianp (uint32_t *outp, uint32_t in,
316 _endian_be32_p(outp, in, endian);
319 static inline void be64_to_endianp (uint64_t *outp, uint64_t in,
322 _endian_be64_p(outp, in, endian);
325 static inline void le16_to_endianp (uint16_t *outp, uint16_t in,
328 _endian_le16_p(outp, in, endian);
331 static inline void le32_to_endianp (uint32_t *outp, uint32_t in,
334 _endian_le32_p(outp, in, endian);
337 static inline void le64_to_endianp (uint64_t *outp, uint64_t in,
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,
408 endian_to_le16p(outp, in, endian);
411 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
414 endian_to_le32p(outp, in, endian);
417 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
420 endian_to_le64p(outp, in, endian);
423 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
426 le16_to_endianp(outp, in, endian);
429 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
432 le32_to_endianp(outp, in, endian);
435 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
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,
476 endian_to_be16p(outp, in, endian);
479 static inline void endian_to_cpu32p (uint32_t *outp, uint32_t in,
482 endian_to_be32p(outp, in, endian);
485 static inline void endian_to_cpu64p (uint64_t *outp, uint64_t in,
488 endian_to_be64p(outp, in, endian);
491 static inline void cpu16_to_endianp (uint16_t *outp, uint16_t in,
494 be16_to_endianp(outp, in, endian);
497 static inline void cpu32_to_endianp (uint32_t *outp, uint32_t in,
500 be32_to_endianp(outp, in, endian);
503 static inline void cpu64_to_endianp (uint64_t *outp, uint64_t in,
506 be64_to_endianp(outp, in, endian);
509 #else /* 2143 / 3412 */
514 #endif /* !defined (__OHW_ENDIAN_H__) */