X-Git-Url: https://git.distorted.org.uk/~mdw/mLib/blobdiff_plain/374bb459369d47f598d1b07f6237f24abd0d52c6..a23bab96cb9eb7a869eb260336e5837e9c63d69b:/utils/bits.h diff --git a/utils/bits.h b/utils/bits.h index 3b12f96..656eee5 100644 --- a/utils/bits.h +++ b/utils/bits.h @@ -40,6 +40,10 @@ # include #endif +#ifndef MLIB_COMPILER_H +# include "compiler.h" +#endif + /*----- Decide on some types ----------------------------------------------*/ /* --- Make GNU C shut up --- */ @@ -316,6 +320,16 @@ typedef unsigned char octet, uint8; /* --- Endianness swapping --- */ +#if GCC_VERSION_P(4, 8) +# define ENDSWAP16(x) ((uint16)__builtin_bswap16(x)) +#endif +#if GCC_VERSION_P(4, 3) +# define ENDSWAP32(x) ((uint32)__builtin_bswap32(x)) +#endif +#if GCC_VERSION_P(4, 3) && defined(HAVE_UINT64) +# define ENDSWAP64(x) ((uint64)__builtin_bswap64(x)) +#endif + #ifndef ENDSWAP8 # define ENDSWAP8(x) U8(x) #endif @@ -411,8 +425,71 @@ typedef unsigned char octet, uint8; # define BTOH64_(z, x) ASSIGN64(z, x) #endif +/* --- Unaligned access (GCC-specific) --- */ + +#if GCC_VERSION_P(3, 3) && CHAR_BIT == 8 +# define MLIB_MISALIGNED __attribute__((aligned(1), may_alias)) +# if __SIZEOF_SHORT__ == 2 + typedef MLIB_MISALIGNED unsigned short misaligned_uint16; +# define RAW16(p) (*(misaligned_uint16 *)(p)) +# endif +# if __SIZEOF_INT__ == 4 + typedef MLIB_MISALIGNED unsigned int misaligned_uint32; +# define RAW32(p) (*(misaligned_uint32 *)(p)) +# elif __SIZEOF_LONG__ == 4 + typedef MLIB_MISALIGNED unsigned long misaligned_uint32; +# define RAW32(p) (*(misaligned_uint32 *)(p)) +# endif +# if __SIZEOF_LONG__ == 8 + typedef MLIB_MISALIGNED unsigned long misaligned_uint64; +# define RAW64(p) (*(misaligned_uint64 *)(p)) +# elif __SIZEOF_LONG_LONG__ == 8 + typedef MLIB_MISALIGNED unsigned long long misaligned_uint64; +# define RAW64(p) (*(misaligned_uint64 *)(p)) +# endif +#endif + /* --- Storage and retrieval --- */ +#if defined(RAW16) && defined(LTOH16) +# define LOAD16_L(p) LTOH16(RAW16(p)) +#endif +#if defined(RAW16) && defined(HTOL16) +# define STORE16_L(p, x) (RAW16(p) = HTOL16(x)) +#endif +#if defined(RAW16) && defined(BTOH16) +# define LOAD16_B(p) BTOH16(RAW16(p)) +#endif +#if defined(RAW16) && defined(HTOB16) +# define STORE16_B(p, x) (RAW16(p) = HTOB16(x)) +#endif + +#if defined(RAW32) && defined(LTOH32) +# define LOAD32_L(p) LTOH32(RAW32(p)) +#endif +#if defined(RAW32) && defined(HTOL32) +# define STORE32_L(p, x) (RAW32(p) = HTOL32(x)) +#endif +#if defined(RAW32) && defined(BTOH32) +# define LOAD32_B(p) BTOH32(RAW32(p)) +#endif +#if defined(RAW32) && defined(HTOB32) +# define STORE32_B(p, x) (RAW32(p) = HTOB32(x)) +#endif + +#if defined(RAW64) && defined(LTOH64) +# define LOAD64_L(p) LTOH64(RAW64(p)) +#endif +#if defined(RAW64) && defined(HTOL64) +# define STORE64_L(p, x) (RAW64(p) = HTOL64(x)) +#endif +#if defined(RAW64) && defined(BTOH64) +# define LOAD64_B(p) BTOH64(RAW64(p)) +#endif +#if defined(RAW64) && defined(HTOB64) +# define STORE64_B(p, x) (RAW64(p) = HTOB64(x)) +#endif + #define GETBYTE(p, o) (((octet *)(p))[o] & MASK8) #define PUTBYTE(p, o, v) (((octet *)(p))[o] = U8((v)))