aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt18
-rw-r--r--src/core/defs.h63
2 files changed, 81 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1dca028c..f859a7d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -207,6 +207,24 @@ if (NOT WIN32 AND NOT CYGWIN)
endif ()
endif ()
+# Detect endianness -- this only handles little and big endian.
+# PDP users, sorry, but you're out of luck.'
+if (DEFINED CMAKE_LANG_C_BYTE_ORDER)
+ if (CMAKE_LANG_BYTE_ORDER EQUAL BIG_ENDIAN)
+ add_definitions(-DNNG_BIG_ENDIAN=1)
+ else()
+ add_definitions(-DNNG_LITTLE_ENDIAN=1)
+ endif()
+else()
+ include(TestBigEndian)
+ test_big_endian(NNG_BIG_ENDIAN)
+ if (NNG_BIG_ENDIAN)
+ add_definitions(-DNNG_BIG_EDNDIAN=1)
+ else()
+ add_definitions(-DNNG_LITTLE_ENDIAN=1)
+ endif()
+endif()
+
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
add_definitions(-DNNG_PLATFORM_POSIX)
add_definitions(-DNNG_PLATFORM_LINUX)
diff --git a/src/core/defs.h b/src/core/defs.h
index f1947fe9..6050782b 100644
--- a/src/core/defs.h
+++ b/src/core/defs.h
@@ -121,6 +121,54 @@ typedef void (*nni_cb)(void *);
(((uint64_t) ((uint8_t) (ptr)[6])) << 8u) + \
(((uint64_t) (uint8_t) (ptr)[7]))
+// Modern CPUs are all little endian. Let's stop paying the endian tax.
+
+#define NNI_PUT16LE(ptr, u) \
+ do { \
+ (ptr)[1] = (uint8_t) (((uint16_t) (u)) >> 8u); \
+ (ptr)[0] = (uint8_t) ((uint16_t) (u)); \
+ } while (0)
+
+#define NNI_PUT32LE(ptr, u) \
+ do { \
+ (ptr)[3] = (uint8_t) (((uint32_t) (u)) >> 24u); \
+ (ptr)[2] = (uint8_t) (((uint32_t) (u)) >> 16u); \
+ (ptr)[1] = (uint8_t) (((uint32_t) (u)) >> 8u); \
+ (ptr)[0] = (uint8_t) ((uint32_t) (u)); \
+ } while (0)
+
+#define NNI_PUT64LE(ptr, u) \
+ do { \
+ (ptr)[7] = (uint8_t) (((uint64_t) (u)) >> 56u); \
+ (ptr)[6] = (uint8_t) (((uint64_t) (u)) >> 48u); \
+ (ptr)[5] = (uint8_t) (((uint64_t) (u)) >> 40u); \
+ (ptr)[4] = (uint8_t) (((uint64_t) (u)) >> 32u); \
+ (ptr)[3] = (uint8_t) (((uint64_t) (u)) >> 24u); \
+ (ptr)[2] = (uint8_t) (((uint64_t) (u)) >> 16u); \
+ (ptr)[1] = (uint8_t) (((uint64_t) (u)) >> 8u); \
+ (ptr)[0] = (uint8_t) ((uint64_t) (u)); \
+ } while (0)
+
+#define NNI_GET16LE(ptr, v) \
+ v = (((uint16_t) ((uint8_t) (ptr)[1])) << 8u) + \
+ (((uint16_t) (uint8_t) (ptr)[0]))
+
+#define NNI_GET32LE(ptr, v) \
+ v = (((uint32_t) ((uint8_t) (ptr)[3])) << 24u) + \
+ (((uint32_t) ((uint8_t) (ptr)[2])) << 16u) + \
+ (((uint32_t) ((uint8_t) (ptr)[1])) << 8u) + \
+ (((uint32_t) (uint8_t) (ptr)[0]))
+
+#define NNI_GET64LE(ptr, v) \
+ v = (((uint64_t) ((uint8_t) (ptr)[7])) << 56u) + \
+ (((uint64_t) ((uint8_t) (ptr)[6])) << 48u) + \
+ (((uint64_t) ((uint8_t) (ptr)[5])) << 40u) + \
+ (((uint64_t) ((uint8_t) (ptr)[4])) << 32u) + \
+ (((uint64_t) ((uint8_t) (ptr)[3])) << 24u) + \
+ (((uint64_t) ((uint8_t) (ptr)[2])) << 16u) + \
+ (((uint64_t) ((uint8_t) (ptr)[1])) << 8u) + \
+ (((uint64_t) (uint8_t) (ptr)[0]))
+
// This increments a pointer a fixed number of byte cells.
#define NNI_INCPTR(ptr, n) ((ptr) = (void *) ((char *) (ptr) + (n)))
@@ -178,4 +226,19 @@ typedef nni_type nni_opt_type;
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
+#if !defined(NNG_BIG_ENDIAN) && !defined(NNG_LITTLE_ENDIAN)
+#if defined(__BYTE_ORDER__)
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define NNG_BIG_ENDIAN 1
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define NNG_LITTLE_ENDIAN 1
+#else // middle-endian? (aka PDP-11)
+#error "Unsupported or unknown endian"
+#endif // __BYTE_ORDER__
+#else // defined(__BYTE_ORDER__)
+#define NNG_LITTLE_ENDIAN 1
+#error "Unknown endian: specify -DNNG_BIG_ENDIAN=1 or -DNNG_LITTLE_ENDIAN=1"
+#endif // defined(__BYTE_ORDER)
+#endif // defined() endianness
+
#endif // CORE_DEFS_H