aboutsummaryrefslogtreecommitdiff
path: root/common/endian.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/endian.h')
-rw-r--r--common/endian.h45
1 files changed, 24 insertions, 21 deletions
diff --git a/common/endian.h b/common/endian.h
index e6c39d3a4c..9cb703858a 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * $URL$
- * $Id$
- *
*/
#ifndef COMMON_ENDIAN_H
@@ -149,51 +146,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)
-#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