X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fbyteorder.h;h=ff1237adf3a52e8a6a9c8714f41ba23cdf341d21;hb=02da7e0db83863a2efe15b490c7713ffe0526aeb;hp=f2d402df20682db906f587786231288015753f36;hpb=747b943bfd16b0d5eb20bc31c125ab12bafe65de;p=bertos.git diff --git a/bertos/cpu/byteorder.h b/bertos/cpu/byteorder.h index f2d402df..ff1237ad 100644 --- a/bertos/cpu/byteorder.h +++ b/bertos/cpu/byteorder.h @@ -40,25 +40,36 @@ #include #include +#include +#include /** * Swap upper and lower bytes in a 16-bit value. */ -#define swab16(x) ((uint16_t)(ROTR(x, 8))) +#define SWAB16(x) ((uint16_t)(ROTR((x), 8) + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t)))) -#if GNUC_PREREQ(4, 3) -#define SWAB32(x) __builtin_bswap32(x) -#define SWAB64(x) __builtin_bswap64(x) +/* + * On Cortex-M3, GCC 4.4 builtin implementation is slower than our own + * rot-based implementation. + */ +#if GNUC_PREREQ(4, 3) && !CPU_CM3 +#define SWAB32(x) ((uint32_t)(__builtin_bswap32((x) + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))))) #else /** * Reverse bytes in a 32-bit value (e.g.: 0x12345678 -> 0x78563412). */ -#define SWAB32(x) ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24))) +#define SWAB32(x) ((uint32_t)(( \ + (ROTR(x, 8) & 0xFF00FF00) | \ + (ROTL(x, 8) & 0x00FF00FF))) + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))) +#endif +#if GNUC_PREREQ(4, 3) +#define SWAB64(x) ((uint64_t)(__builtin_bswap64((x) + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t))))) +#else /** * Reverse bytes in a 64-bit value. */ @@ -70,35 +81,30 @@ (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56))) + (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t)))) #endif #if CPU_BYTE_ORDER == CPU_LITTLE_ENDIAN -#define cpu_to_le16(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t))) -#define cpu_to_le32(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))) -#define cpu_to_le64(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t))) -#define cpu_to_be16(x) \ - SWAB16(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t))) -#define cpu_to_be32(x) \ - SWAB32(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))) -#define cpu_to_be64(x) \ - SWAB64(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t))) +#define cpu_to_le16(x) ((uint16_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t)))) +#define cpu_to_le32(x) ((uint32_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t)))) +#define cpu_to_le64(x) ((uint64_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t)))) +#define cpu_to_be16(x) SWAB16(x) +#define cpu_to_be32(x) SWAB32(x) +#define cpu_to_be64(x) SWAB64(x) #elif CPU_BYTE_ORDER == CPU_BIG_ENDIAN -#define cpu_to_le16(x) \ - SWAB16(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t))) -#define cpu_to_le32(x) \ - SWAB32(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))) -#define cpu_to_le64(x) \ - SWAB64(x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t))) -#define cpu_to_be16(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t))) -#define cpu_to_be32(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t))) -#define cpu_to_be64(x) \ - (x + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t))) +#define cpu_to_le16(x) SWAB16(x) +#define cpu_to_le32(x) SWAB32(x) +#define cpu_to_le64(x) SWAB64(x) +#define cpu_to_be16(x) ((uint16_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint16_t)))) +#define cpu_to_be32(x) ((uint32_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint32_t)))) +#define cpu_to_be64(x) ((uint64_t)(x + \ + STATIC_ASSERT_EXPR(sizeof(x) == sizeof(uint64_t)))) #else #error "unrecognized CPU endianness" #endif @@ -168,12 +174,12 @@ INLINE float net_to_host_float(float x) template INLINE T swab(T x); -template<> INLINE uint16_t swab(uint16_t x) { return swab16(x); } -template<> INLINE uint32_t swab(uint32_t x) { return swab32(x); } -template<> INLINE uint64_t swab(uint64_t x) { return swab64(x); } -template<> INLINE int16_t swab(int16_t x) { return static_cast(swab16(static_cast(x))); } -template<> INLINE int32_t swab(int32_t x) { return static_cast(swab32(static_cast(x))); } -template<> INLINE int64_t swab(int64_t x) { return static_cast(swab64(static_cast(x))); } +template<> INLINE uint16_t swab(uint16_t x) { return SWAB16(x); } +template<> INLINE uint32_t swab(uint32_t x) { return SWAB32(x); } +template<> INLINE uint64_t swab(uint64_t x) { return SWAB64(x); } +template<> INLINE int16_t swab(int16_t x) { return static_cast(SWAB16(static_cast(x))); } +template<> INLINE int32_t swab(int32_t x) { return static_cast(SWAB32(static_cast(x))); } +template<> INLINE int64_t swab(int64_t x) { return static_cast(SWAB64(static_cast(x))); } template<> INLINE float swab(float x) { return swab_float(x); } /// Type generic conversion from CPU byte order to big-endian byte order.