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.
This commit is contained in:
Max Horn 2011-05-10 15:38:10 +02:00
parent 5bf8a0bf84
commit 9511af6682

View File

@ -149,32 +149,17 @@
*/
#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)
FORCEINLINE uint16 READ_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = 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:
// 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)
//
// 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) {
struct Unaligned16 { uint16 val; } __attribute__ ((__packed__, __may_alias__));
@ -196,6 +181,25 @@
((Unaligned32 *)ptr)->val = value;
}
#elif !defined(SCUMM_NEED_ALIGNMENT)
FORCEINLINE uint16 READ_UINT16(const void *ptr) {
return *(const uint16 *)(ptr);
}
FORCEINLINE uint32 READ_UINT32(const void *ptr) {
return *(const uint32 *)(ptr);
}
FORCEINLINE void WRITE_UINT16(void *ptr, uint16 value) {
*(uint16 *)(ptr) = value;
}
FORCEINLINE void WRITE_UINT32(void *ptr, uint32 value) {
*(uint32 *)(ptr) = value;
}
// use software fallback by loading each byte explicitely
#else