aboutsummaryrefslogtreecommitdiffhomepage
path: root/endian.h
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-18 22:26:53 +0200
committerlemon <lsof@mailbox.org>2023-06-18 22:26:53 +0200
commit4f979636327bb1acb371d3094554da6cc4672973 (patch)
treef1bdf1546eb83991339c1c8eeaf77cbbeb16ff21 /endian.h
parentb246b0f1f617d34560402c734630369145c2dee1 (diff)
add endian.h for endian dependent stuff
Diffstat (limited to 'endian.h')
-rw-r--r--endian.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/endian.h b/endian.h
new file mode 100644
index 0000000..8448c79
--- /dev/null
+++ b/endian.h
@@ -0,0 +1,133 @@
+#ifndef ENDIAN_H_
+#define ENDIAN_H_
+
+#include "common.h"
+
+/*** Macros and functions for endian specific memory access ***/
+
+/** byte-swapping functions **/
+
+#if HAS_BUILTIN(bswap16)
+#define bswap16 __builtin_bswap16
+#else
+static inline ushort
+bswap16(ushort x) {
+ return x >> 8 | x << 8;
+}
+#endif
+
+#if HAS_BUILTIN(bswap32)
+#define bswap32 __builtin_bswap32
+#else
+static inline uint
+bswap32(uint x) {
+ return x >> 24 & 0x000000FF | x >> 8 & 0x0000FF00
+ | x << 8 & 0x00FF0000 | x << 24 & 0xFF000000;
+}
+#endif
+
+#if HAS_BUILTIN(bswap64)
+#define bswap64 __builtin_bswap64
+#else
+static inline uvlong
+bswap64(uvlong x) {
+ return (uvlong) bswap32(x) << 32 | bswap32(x >> 32);
+}
+#endif
+
+#if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+ defined __hppa__ || defined __m68k__ || defined mc68000 || defined _M_M68K || \
+ (defined __MIPS__ && defined __MIPSEB__) || \
+ defined __ppc__ || defined __POWERPC__ || defined __powerpc__ || defined __PPC__ || \
+ defined __sparc__
+#define HOST_BIG_ENDIAN
+#define hostntarg_sameendian() (targ_bigendian)
+#else
+#define HOST_LIL_ENDIAN
+#define hostntarg_sameendian() (!targ_bigendian)
+#endif
+
+/** little-endian memory writes **/
+
+static inline void
+wr16le(uchar *p, ushort x)
+{
+#ifndef HOST_LIL_ENDIAN
+ x = bswap16(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr32le(uchar *p, uint x)
+{
+#ifndef HOST_LIL_ENDIAN
+ x = bswap32(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr64le(uchar *p, uvlong x)
+{
+#ifndef HOST_LIL_ENDIAN
+ x = bswap64(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+/** big-endian memory writes **/
+
+static inline void
+wr16be(uchar *p, ushort x)
+{
+#ifndef HOST_BIG_ENDIAN
+ x = bswap16(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr32be(uchar *p, uint x)
+{
+#ifndef HOST_BIG_ENDIAN
+ x = bswap32(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr64be(uchar *p, uvlong x)
+{
+#ifndef HOST_BIG_ENDIAN
+ x = bswap64(x);
+#endif
+ memcpy(p, &x, sizeof x);
+}
+
+/** target-endian memory writes **/
+
+static inline void
+wr16targ(uchar *p, ushort x)
+{
+ if (!hostntarg_sameendian()) x = bswap16(x);
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr32targ(uchar *p, uint x)
+{
+ if (!hostntarg_sameendian()) x = bswap32(x);
+ memcpy(p, &x, sizeof x);
+}
+
+static inline void
+wr64targ(uchar *p, uvlong x)
+{
+ if (!hostntarg_sameendian()) x = bswap64(x);
+ memcpy(p, &x, sizeof x);
+}
+
+#endif /* ENDIAN_H_ */
+
+/* vim:set ts=3 sw=3 expandtab: */