diff options
author | Max Horn | 2011-05-10 15:38:10 +0200 |
---|---|---|
committer | Max Horn | 2011-05-10 15:38:18 +0200 |
commit | 9511af6682f3a81e5956b43c1af1748c289191a8 (patch) | |
tree | bb58728bedf096c426cc550f3a0e0ade7128ae4b /common | |
parent | 5bf8a0bf846a5d3d0a02b8186de00518ca437c80 (diff) | |
download | scummvm-rg350-9511af6682f3a81e5956b43c1af1748c289191a8.tar.gz scummvm-rg350-9511af6682f3a81e5956b43c1af1748c289191a8.tar.bz2 scummvm-rg350-9511af6682f3a81e5956b43c1af1748c289191a8.zip |
COMMON: Always prefer GCC 4.x versions of READ_UINT*/WRITE_UINT*
In addition, we use them if in GCC >= 3.3 if unaligned access is
possible. The GCC variants of these macros also contain protection
against overzealous compilers' static aliasing optimizations.
Diffstat (limited to 'common')
-rw-r--r-- | common/endian.h | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/common/endian.h b/common/endian.h index afd7e2913e..c645243654 100644 --- a/common/endian.h +++ b/common/endian.h @@ -149,53 +149,57 @@ */ #define MKTAG(a0,a1,a2,a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24))) -// Functions for reading/writing native integers, -// this transparently handles the need for alignment. +// Functions for reading/writing native integers. +// They also transparently handle the need for alignment. -#if !defined(SCUMM_NEED_ALIGNMENT) +// Test for GCC >= 4.0. These implementations will automatically use +// CPU-specific instructions for unaligned data when they are available (eg. +// MIPS). See also this email thread on scummvm-devel for details: +// <http://thread.gmane.org/gmane.games.devel.scummvm/8063> +// +// Moreover, we activate this code for GCC >= 3.3 but *only* if unaligned access +// is allowed. +#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3 && !defined(SCUMM_NEED_ALIGNMENT))) FORCEINLINE uint16 READ_UINT16(const void *ptr) { - return *(const uint16 *)(ptr); + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); + return ((const Unaligned16 *)ptr)->val; } FORCEINLINE uint32 READ_UINT32(const void *ptr) { - return *(const uint32 *)(ptr); + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); + return ((const Unaligned32 *)ptr)->val; } FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { - *(uint16 *)(ptr) = value; + struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); + ((Unaligned16 *)ptr)->val = value; } FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { - *(uint32 *)(ptr) = value; + struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); + ((Unaligned32 *)ptr)->val = value; } -// Test for GCC >= 4.0. These implementations will automatically use CPU-specific -// instructions for unaligned data when they are available (eg. MIPS). -// See also this email thread on scummvm-devel for details: -// <http://thread.gmane.org/gmane.games.devel.scummvm/8063> -#elif defined(__GNUC__) && (__GNUC__ >= 4) +#elif !defined(SCUMM_NEED_ALIGNMENT) FORCEINLINE uint16 READ_UINT16(const void *ptr) { - struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); - return ((const Unaligned16 *)ptr)->val; + return *(const uint16 *)(ptr); } FORCEINLINE uint32 READ_UINT32(const void *ptr) { - struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); - return ((const Unaligned32 *)ptr)->val; + return *(const uint32 *)(ptr); } FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) { - struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__)); - ((Unaligned16 *)ptr)->val = value; + *(uint16 *)(ptr) = value; } FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) { - struct Unaligned32 { uint32 val; } __attribute__ ((__packed__, __may_alias__)); - ((Unaligned32 *)ptr)->val = value; + *(uint32 *)(ptr) = value; } + // use software fallback by loading each byte explicitely #else |