summaryrefslogtreecommitdiff
path: root/firmware/libc
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2014-08-24 19:46:43 -0400
committerMichael Sevakis <jethead71@rockbox.org>2014-08-25 12:16:56 -0400
commit6ffb8ffeeed9aca75c278906785a957d72b3ef57 (patch)
treeabeeb7df67dfaba1d5bfef6d6a29507b16192455 /firmware/libc
parentd3cf366868500403bbe072bddf44eaf8c7f749d4 (diff)
Do a better endian.h setup that isn't as fragile
We redefine the top-level macros to our own in order to maintain compatibility with compound initializers by wrapping the mid or low level definitions from the OS header. This allows, hopefully optimized, macros from the host OS's headers to be used when building any hosted target obviating the need for NEED_GENERIC_BYTESWAPS unless the target simply doesn't define its own optimized versions (MIPS!). Throw in some 64-bit swaps for completeness' sake; they generate no code if not yet used anyway. Change-Id: I21b384b55fea46833d01ea3cad1ad8952ea01a11
Diffstat (limited to 'firmware/libc')
-rw-r--r--firmware/libc/include/endian.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/firmware/libc/include/endian.h b/firmware/libc/include/endian.h
new file mode 100644
index 0000000000..de1c508da7
--- /dev/null
+++ b/firmware/libc/include/endian.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Alan Korr
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_
+
+#ifndef _RBENDIAN_H_
+/* this only defines what may be substituted in the native endian.h */
+#error "Include rbendian.h instead."
+#endif
+
+#define __ENDIAN_H_NATIVE_RB
+
+#ifdef NEED_GENERIC_BYTESWAPS
+static inline uint16_t swap16_hw(uint16_t value)
+ /*
+ * result[15..8] = value[ 7..0];
+ * result[ 7..0] = value[15..8];
+ */
+{
+ return (value >> 8) | (value << 8);
+}
+
+static inline uint32_t swap32_hw(uint32_t value)
+ /*
+ * result[31..24] = value[ 7.. 0];
+ * result[23..16] = value[15.. 8];
+ * result[15.. 8] = value[23..16];
+ * result[ 7.. 0] = value[31..24];
+ */
+{
+ uint32_t hi = swap16_hw(value >> 16);
+ uint32_t lo = swap16_hw(value & 0xffff);
+ return (lo << 16) | hi;
+}
+#endif /* NEED_GENERIC_BYTESWAPS */
+
+static FORCE_INLINE uint64_t swap64_hw(uint64_t x)
+ { return swap32_hw((uint32_t)(x >> 32)) |
+ ((uint64_t)swap32_hw((uint32_t)x) << 32); }
+
+#endif /* _ENDIAN_H_ */