+#include <cfg/compiler.h>
+#include <cpu/attr.h>
+
+/**
+ * Swap upper and lower bytes in a 16-bit value.
+ */
+INLINE uint16_t swab16(uint16_t x)
+{
+ return ((x & (uint16_t)0x00FFU) << 8)
+ | ((x & (uint16_t)0xFF00U) >> 8);
+}
+
+/**
+ * Reverse bytes in a 32-bit value (e.g.: 0x12345678 -> 0x78563412).
+ */
+INLINE uint32_t swab32(uint32_t x)
+{
+ return ((x & (uint32_t)0x000000FFUL) << 24)
+ | ((x & (uint32_t)0x0000FF00UL) << 8)
+ | ((x & (uint32_t)0x00FF0000UL) >> 8)
+ | ((x & (uint32_t)0xFF000000UL) >> 24);
+}
+
+/**
+ * Reverse bytes in a 64-bit value.
+ */
+INLINE uint64_t swab64(uint64_t x)
+{
+ return (uint64_t)swab32(x >> 32)
+ | ((uint64_t)swab32(x & 0xFFFFFFFFUL) << 32);
+}
+
+/**
+ * Reverse bytes in a float value.
+ */
+INLINE float swab_float(float x)
+{
+ /* Avoid breaking strict aliasing rules. */
+ char *cx = (char *)(&x);
+ STATIC_ASSERT(sizeof(float) == 4);
+ #define BYTEORDER_SWAP(a, b) ((a) ^= (b) ^= (a) ^= (b))
+ BYTEORDER_SWAP(cx[0], cx[3]);
+ BYTEORDER_SWAP(cx[1], cx[2]);
+ #undef BYTEORDER_SWAP
+ return x;
+}
+
+INLINE uint16_t cpu_to_be16(uint16_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab16(x) : x;
+}
+
+INLINE uint16_t cpu_to_le16(uint16_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab16(x) : x;
+}
+
+INLINE uint32_t cpu_to_be32(uint32_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab32(x) : x;
+}
+
+INLINE uint32_t cpu_to_le32(uint32_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab32(x) : x;
+}
+
+INLINE uint64_t cpu_to_be64(uint64_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab64(x) : x;
+}
+
+INLINE uint64_t cpu_to_le64(uint64_t x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab64(x) : x;
+}
+
+INLINE float cpu_to_be_float(float x)
+{
+ return (CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN) ? swab_float(x) : x;
+}
+
+INLINE float cpu_to_le_float(float x)
+{
+ return (CPU_BYTE_ORDER == CPU_BIG_ENDIAN) ? swab_float(x) : x;
+}
+
+INLINE uint16_t be16_to_cpu(uint16_t x)
+{
+ return cpu_to_be16(x);
+}