diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-05-02 16:24:22 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-05-02 16:24:22 +0000 |
commit | 67b7c93971748e23254c2768545c15631fc111b9 (patch) | |
tree | c27a89b14a09d01bead559753ae2fad04296e032 /lib/util | |
parent | 62f18c5e354db1cd2584a6267ddbd9ac8bff80e4 (diff) | |
download | netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.tar.gz netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.tar.xz netpbm-mirror-67b7c93971748e23254c2768545c15631fc111b9.zip |
Fix unaligned memory access on Sparc
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1892 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/util')
-rw-r--r-- | lib/util/wordaccess.h | 51 | ||||
-rw-r--r-- | lib/util/wordaccess_be_aligned.h | 35 | ||||
-rw-r--r-- | lib/util/wordaccess_be_unaligned.h (renamed from lib/util/wordaccess_gcc3_be.h) | 7 | ||||
-rw-r--r-- | lib/util/wordaccess_generic.h | 6 |
4 files changed, 65 insertions, 34 deletions
diff --git a/lib/util/wordaccess.h b/lib/util/wordaccess.h index 2eaa2b24..09a896c4 100644 --- a/lib/util/wordaccess.h +++ b/lib/util/wordaccess.h @@ -44,33 +44,32 @@ #include "pm_config.h" -#if (!defined(WORDACCESS_GENERIC) && HAVE_GCC_BITCOUNT ) - - #if BYTE_ORDER == BIG_ENDIAN /* See pm_config.h */ - /* Sun Sparc 64, etc */ - #include "wordaccess_gcc3_be.h" - - #elif (BITS_PER_LONG == 64) - /* AMD Athlon 64, Intel x86_64, Intel Itanium, etc. */ - #include "wordaccess_64_le.h" - - #elif (BITS_PER_LONG == 32) - /* Intel x86_32 (80386, 80486, Pentium), etc. */ - #include "wordaccess_generic.h" - - #else - /* Extremely rare case. - If long is neither 32 nor 64 bits, (say, 128) it comes here. - */ - #define WORDACCESS_GENERIC - #include "wordaccess_generic.h" - - #endif - +#if defined(WORDACCESS_GENERIC) + /* User wants this, regardless of whether machine can do better */ + #include "wordaccess_generic.h" +#elif BYTE_ORDER == BIG_ENDIAN + #if UNALIGNED_OK + #include wordaccess_be_unaligned.h + #else + /* Sparc */ + #include wordaccess_be_aligned.h + #endif +#elif HAVE_GCC_BITCOUNT + #if (BITS_PER_LONG == 64) + /* AMD Athlon 64, Intel x86_64, Intel Itanium, etc. */ + #include "wordaccess_64_le.h" + #elif (BITS_PER_LONG == 32) + /* Intel x86_32 (80386, 80486, Pentium), etc. */ + #include "wordaccess_generic.h" + #else + /* Extremely rare case. + If long is neither 32 nor 64 bits, (say, 128) it comes here. + */ + #include "wordaccess_generic.h" + #endif #else - /* Non GCC, GCC prior to v.3.4 or WORDACCESS_GENERIC defined */ - #include "wordaccess_generic.h" - + /* Non GCC or GCC prior to v.3.4; little-endian */ + #include "wordaccess_generic.h" #endif #endif diff --git a/lib/util/wordaccess_be_aligned.h b/lib/util/wordaccess_be_aligned.h new file mode 100644 index 00000000..0d5809e6 --- /dev/null +++ b/lib/util/wordaccess_be_aligned.h @@ -0,0 +1,35 @@ +/*============================================================================= + This file is the part of wordaccess.h for use under with big-endian + machines that require word accesses to be word-aligned. +*===========================================================================*/ + +typedef unsigned long int wordint; +typedef unsigned char wordintBytes[sizeof(wordint)]; + +static __inline__ wordint +bytesToWordint(wordintBytes bytes) { + uint16_t const hi = *((uint16_t *) (bytes + 0)); + uint16_t const mh = *((uint16_t *) (bytes + 2)); + uint16_t const ml = *((uint16_t *) (bytes + 4)); + uint16_t const lo = *((uint16_t *) (bytes + 6)); + return + (((wordint) hi) << 48) | + (((wordint) mh) << 32) | + (((wordint) ml) << 24) | + (((wordint) lo) << 0); +} + + + +static __inline__ void +wordintToBytes(wordintBytes * const bytesP, + wordint const wordInt) { + uint16_t const hi = ((wordInt >> 48) & 0xFF) + uint16_t const mh = ((wordInt >> 32) & 0xFF); + uint16_t const ml = ((wordInt >> 24) & 0xFF); + uint16_t const lo = ((wordInt >> 0) & 0xFF); + *(uint16_t *)(bytesP + 0) = hi; + *(uint16_t *)(bytesP + 2) = mh; + *(uint16_t *)(bytesP + 4) = ml; + *(uint16_t *)(bytesP + 6) = lo; +} diff --git a/lib/util/wordaccess_gcc3_be.h b/lib/util/wordaccess_be_unaligned.h index 5aa63521..95b68ac7 100644 --- a/lib/util/wordaccess_gcc3_be.h +++ b/lib/util/wordaccess_be_unaligned.h @@ -1,9 +1,6 @@ /*============================================================================= - This file is the part of wordaccess.h for use under these - conditions: - - * GCC (>=3.4), GLIBC - * Big-Endian machines + This file is the part of wordaccess.h for use on a big-endian machine + that does not require word accesses to be word-aligned. *===========================================================================*/ typedef unsigned long int wordint; diff --git a/lib/util/wordaccess_generic.h b/lib/util/wordaccess_generic.h index 94cc8124..6e0a20ef 100644 --- a/lib/util/wordaccess_generic.h +++ b/lib/util/wordaccess_generic.h @@ -1,11 +1,11 @@ /*============================================================================= - This file is the part of wordaccess.h for use under these + This file is the part of wordaccess.h for use under any of these conditions: - * Compilers other than GCC + * Compiler other than GCC * GCC before version 3.4 - * Specified by the user with WORDACCESS_GENERIC + * Requested by the user with WORDACCESS_GENERIC =============================================================================*/ #include "intcode.h" |