diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2009-06-27 21:05:14 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2009-06-27 21:05:14 +0000 |
commit | 4e5f07abc5cdc1f076eb8713c75823fd2097d911 (patch) | |
tree | 1e640322b516eeab31c58aad886edd3932814efe /lib/util | |
parent | 3ecf4ceb636585673b6eec27c1e56f85dc6d2dfe (diff) | |
download | netpbm-mirror-4e5f07abc5cdc1f076eb8713c75823fd2097d911.tar.gz netpbm-mirror-4e5f07abc5cdc1f076eb8713c75823fd2097d911.tar.xz netpbm-mirror-4e5f07abc5cdc1f076eb8713c75823fd2097d911.zip |
Release 10.47.00: rebase to trunk
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@944 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/util')
-rw-r--r-- | lib/util/intcode.h | 203 | ||||
-rw-r--r-- | lib/util/nstring.h | 12 | ||||
-rw-r--r-- | lib/util/wordaccess.h | 30 | ||||
-rw-r--r-- | lib/util/wordaccess_64_le.h | 48 | ||||
-rw-r--r-- | lib/util/wordaccess_gcc3_be.h | 17 | ||||
-rw-r--r-- | lib/util/wordaccess_gcc3_le.h | 56 | ||||
-rw-r--r-- | lib/util/wordaccess_generic.h | 74 |
7 files changed, 217 insertions, 223 deletions
diff --git a/lib/util/intcode.h b/lib/util/intcode.h index 0ee70932..dd42f669 100644 --- a/lib/util/intcode.h +++ b/lib/util/intcode.h @@ -1,10 +1,78 @@ #ifndef INTCODE_H_INCLUDED #define INTCODE_H_INCLUDED -#include "pm_config.h" /* For uint32_t, BYTE_ORDER */ +#include "pm_config.h" /* For uint32_t, BYTE_ORDER, HAVE_INT64 */ static unsigned int const pm_byteOrder = BYTE_ORDER; +typedef struct { +/*---------------------------------------------------------------------------- + This is a big-endian representation of a 16 bit integer. I.e. + bytes[0] is the most significant 8 bits; bytes[1] is the least + significant 8 bits of the number in pure binary. + + On a big-endian machines, this is bit for bit identical to uint16_t. + On a little-endian machine, it isn't. + + This is an important data type because decent file formats use + big-endian -- they don't care if some CPU happens to use some other + code for its own work. +-----------------------------------------------------------------------------*/ + unsigned char bytes[2]; +} bigend16; + + +static __inline__ uint16_t +pm_uintFromBigend16(bigend16 const arg) { + + uint16_t retval; + + switch (pm_byteOrder) { + case BIG_ENDIAN: { + union { + bigend16 bigend; + uint16_t native; + } converter; + converter.bigend = arg; + retval = converter.native; + } break; + + default: { + retval = + (arg.bytes[0] << 8) | + (arg.bytes[1] << 0); + } + } + return retval; +} + + + +static __inline__ bigend16 +pm_bigendFromUint16(uint16_t const arg) { + + bigend16 retval; + + switch (pm_byteOrder) { + case BIG_ENDIAN: { + union { + bigend16 bigend; + uint16_t native; + } converter; + converter.native = arg; + retval = converter.bigend; + } break; + + default: { + uint16_t shift; + shift = arg; + retval.bytes[1] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[0] = shift; /* Takes lower 8 bits */ + } + } + return retval; +} typedef struct { /*---------------------------------------------------------------------------- @@ -34,19 +102,30 @@ pm_uintFromBigend32(bigend32 const arg) { bigend32 bigend; uint32_t native; } converter; - converter.bigend = arg; - retval = converter.native; - }; break; + } break; + +#if HAVE_GCC_BSWAP case LITTLE_ENDIAN: { + /* Use GCC built-in */ + union { + bigend32 bigend; + uint32_t native; + } converter; + converter.bigend = arg; + retval = __builtin_bswap32(converter.native); + } break; +#endif + + default: retval = (arg.bytes[0] << 24) | (arg.bytes[1] << 16) | (arg.bytes[2] << 8) | (arg.bytes[3] << 0); - } break; } + return retval; } @@ -63,12 +142,23 @@ pm_bigendFromUint32(uint32_t const arg) { bigend32 bigend; uint32_t native; } converter; - converter.native = arg; - retval = converter.bigend; } break; + +#if HAVE_GCC_BSWAP case LITTLE_ENDIAN: { + /* Use GCC built-in */ + union { + bigend32 bigend; + uint32_t native; + } converter; + converter.native = __builtin_bswap32(arg); + retval = converter.bigend; + } break; +#endif + + default: { uint32_t shift; shift = arg; retval.bytes[3] = shift; /* Takes lower 8 bits */ @@ -78,80 +168,127 @@ pm_bigendFromUint32(uint32_t const arg) { retval.bytes[1] = shift; /* Takes lower 8 bits */ shift >>= 8; retval.bytes[0] = shift; /* Takes lower 8 bits */ - } break; + } } return retval; } + +#if HAVE_INT64 + typedef struct { /*---------------------------------------------------------------------------- - This is a big-endian representation of a 16 bit integer. I.e. - bytes[0] is the most significant 8 bits; bytes[1] is the least + This is a big-endian representation of a 64 bit integer. I.e. + bytes[0] is the most significant 8 bits; bytes[7] is the least significant 8 bits of the number in pure binary. - On a big-endian machines, this is bit for bit identical to uint16_t. + On a big-endian machines, this is bit for bit identical to uint64_t. On a little-endian machine, it isn't. This is an important data type because decent file formats use big-endian -- they don't care if some CPU happens to use some other code for its own work. + + uint64_t is supported only when available. -----------------------------------------------------------------------------*/ - unsigned char bytes[2]; -} bigend16; + unsigned char bytes[8]; +} bigend64; -static __inline__ uint16_t -pm_uintFromBigend16(bigend16 const arg) { +static __inline__ uint64_t +pm_uintFromBigend64(bigend64 const arg) { - uint16_t retval; + uint64_t retval; switch (pm_byteOrder) { case BIG_ENDIAN: { union { - bigend16 bigend; - uint16_t native; + bigend64 bigend; + uint64_t native; } converter; - converter.bigend = arg; - retval = converter.native; - }; break; + } break; + +#if HAVE_GCC_BSWAP case LITTLE_ENDIAN: { - retval = - (arg.bytes[0] << 8) | - (arg.bytes[1] << 0); + /* Use GCC built-in */ + union { + bigend64 bigend; + uint64_t native; + } converter; + converter.bigend = arg; + retval = __builtin_bswap64(converter.native); } break; +#endif + default: + retval = + ((uint64_t)arg.bytes[0] << 56) | ((uint64_t)arg.bytes[1] << 48) | + ((uint64_t)arg.bytes[2] << 40) | ((uint64_t)arg.bytes[3] << 32) | + ((uint64_t)arg.bytes[4] << 24) | ((uint64_t)arg.bytes[5] << 16) | + ((uint64_t)arg.bytes[6] << 8) | ((uint64_t)arg.bytes[7] << 0); } return retval; } -static __inline__ bigend16 -pm_bigendFromUint16(uint16_t const arg) { +static __inline__ bigend64 +pm_bigendFromUint64(uint64_t const arg) { - bigend16 retval; + bigend64 retval; switch (pm_byteOrder) { case BIG_ENDIAN: { union { - bigend16 bigend; - uint16_t native; + bigend64 bigend; + uint64_t native; } converter; - converter.native = arg; - retval = converter.bigend; } break; + +#if HAVE_GCC_BSWAP case LITTLE_ENDIAN: { - uint16_t shift; + + /* Use GCC built-in */ + union { + bigend64 bigend; + uint64_t native; + } converter; + converter.native = __builtin_bswap64(arg); + retval = converter.bigend; + } break; +#endif + + default: { + uint64_t shift; shift = arg; + retval.bytes[7] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[6] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[5] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[4] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[3] = shift; /* Takes lower 8 bits */ + shift >>= 8; + retval.bytes[2] = shift; /* Takes lower 8 bits */ + shift >>= 8; retval.bytes[1] = shift; /* Takes lower 8 bits */ shift >>= 8; retval.bytes[0] = shift; /* Takes lower 8 bits */ - } break; + } } return retval; } +#endif /* HAVE_INT64 */ + #endif + + + + + diff --git a/lib/util/nstring.h b/lib/util/nstring.h index 1e5ca4c3..53f1e4c0 100644 --- a/lib/util/nstring.h +++ b/lib/util/nstring.h @@ -28,8 +28,16 @@ extern "C" { (strncpy(A+strlen(A), B, sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0') #define STRSEQ(A, B) \ (strneq((A), (B), sizeof(A))) -#define MEMSZERO(A) \ - bzero((A), sizeof(A)) + +#define MEMEQ(a,b,c) (memcmp(a, b, c) == 0) + +#define MEMSEQ(a,b) (memeq(a, b, sizeof(*(a))) == 0) + +#define MEMSSET(a,b) (memset(a, b, sizeof(*(a)))) + +#define MEMSCPY(a,b) (memcpy(a, b, sizeof(*(a)))) + +#define MEMSZERO(a) (MEMSSET(a, 0)) static __inline__ int diff --git a/lib/util/wordaccess.h b/lib/util/wordaccess.h index 08034361..2eaa2b24 100644 --- a/lib/util/wordaccess.h +++ b/lib/util/wordaccess.h @@ -36,31 +36,39 @@ work with that. We also assume that a char is 8 bits. + + HAVE_GCC_BITCOUNT and HAVE_GCC_BSWAP are set in pm_config.h + + BITS_PER_LONG is the number of bits in long int. */ #include "pm_config.h" -#if (!defined(WORDACCESS_GENERIC) \ - && defined(__GNUC__) && defined(__GLIBC__) \ - && (__GNUC__ * 100 + __GNUC_MINOR__ >= 304) ) - - #if BYTE_ORDER==BIG_ENDIAN /* defined by GCC */ +#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 defined(__ia64__) || defined(__amd64__) || defined(__x86_64__) - /* all these macros are defined by GCC */ - + #elif (BITS_PER_LONG == 64) + /* AMD Athlon 64, Intel x86_64, Intel Itanium, etc. */ #include "wordaccess_64_le.h" - #else + #elif (BITS_PER_LONG == 32) + /* Intel x86_32 (80386, 80486, Pentium), etc. */ + #include "wordaccess_generic.h" - #include "wordaccess_gcc3_le.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 #else - + /* Non GCC, GCC prior to v.3.4 or WORDACCESS_GENERIC defined */ #include "wordaccess_generic.h" #endif diff --git a/lib/util/wordaccess_64_le.h b/lib/util/wordaccess_64_le.h index ad316df2..4d148ad2 100644 --- a/lib/util/wordaccess_64_le.h +++ b/lib/util/wordaccess_64_le.h @@ -2,28 +2,21 @@ This file is the part of wordaccess.h for use under these conditions: - * GCC (>=3.4), GLIBC - * 64 bit Little-Endian machines (IA64, X86-64, AMD64) -=============================================================================*/ - -/* - 64 bit hton and ntoh do not exist. Here we use bswap_64. - - While bswap_64 works on 64 bit data, __builtin_clzl works on "long" which - may or may not be 64 bits. Code provided to find the right data type and - file off any extra when necessary. -*/ - -#include <byteswap.h> /* See note above on bswap_64 */ - -#include "pm.h" + * GCC (>=3.4) (__builtin_clz appears in GCC 3.4) + * Little-Endian machines (IA64, X86-64, AMD64) + * 64 bit long +=============================================================================*/ + +#include "intcode.h" + typedef uint64_t wordint; typedef unsigned char wordintBytes[sizeof(wordint)]; + static __inline__ wordint -bytesToWordint(wordintBytes bytes) { - return ((wordint) bswap_64(*(wordint *)bytes)); +bytesToWordint(wordintBytes const bytes) { + return (wordint) pm_uintFromBigend64(*(bigend64*)bytes); } @@ -31,24 +24,5 @@ bytesToWordint(wordintBytes bytes) { static __inline__ void wordintToBytes(wordintBytes * const bytesP, wordint const wordInt) { - *(wordint *)bytesP = bswap_64(wordInt); -} - - - -static __inline__ unsigned int -wordintClz(wordint const x){ - - unsigned int s; - - if (x == 0) - return sizeof(wordint) * 8; - - /* Find the data type closest to 64 bits, and file off any extra. */ - else if ((s=sizeof(long int)) >= 8) - return (__builtin_clzl((long int)x << (s - 8) * 8)); - else if ((s=sizeof(long long int)) >= 8) - return (__builtin_clzll((long long int)x << (s - 8) * 8)); - else - pm_error("Long long int is less than 64 bits on this machine"); + *(bigend64*)bytesP = pm_bigendFromUint64(wordInt); } diff --git a/lib/util/wordaccess_gcc3_be.h b/lib/util/wordaccess_gcc3_be.h index 6f5d86fc..5aa63521 100644 --- a/lib/util/wordaccess_gcc3_be.h +++ b/lib/util/wordaccess_gcc3_be.h @@ -4,16 +4,6 @@ * GCC (>=3.4), GLIBC * Big-Endian machines - - __builtin_clz is available on GCC 3.4 and above - - Note that the clz scheme does not work and requires adjustment - if long type does not make use of all bits for data storage. - - This is unlikely. According to GNU MP (http://www.swox.com/gmp/), - in rare cases such as Cray, there are smaller data types that take up - the same space as long, but leave the higher bits silent. Currently, - there are no known such cases for data type long. *===========================================================================*/ typedef unsigned long int wordint; @@ -31,10 +21,3 @@ wordintToBytes(wordintBytes * const bytesP, wordint const wordInt) { *(wordint *)bytesP = wordInt; } - - - -static __inline__ unsigned int -wordintClz(wordint const x) { - return (x==0 ? sizeof(wordint)*8 : __builtin_clzl(x)); -} diff --git a/lib/util/wordaccess_gcc3_le.h b/lib/util/wordaccess_gcc3_le.h deleted file mode 100644 index 798566af..00000000 --- a/lib/util/wordaccess_gcc3_le.h +++ /dev/null @@ -1,56 +0,0 @@ -/*============================================================================= - - This file is the part of wordaccess.h for use under these - conditions: - - * GCC (>=3.4), GLIBC - * 32 bit Little-Endian machines (intel MPUs 80386, Pentium, etc.) - * Other non-Big-Endian machines (very rare) - -=============================================================================*/ - -typedef uint32_t wordint; -typedef unsigned char wordintBytes[sizeof(wordint)]; - -#include <sys/types.h> -#include <netinet/in.h> - -#include "pm.h" - -/* - Here we use the more widely used functions htonl and ntohl instead of - bswap_32. This makes possible the handling of weird byte ordering - (neither Big-Endian nor Little-Endian) schemes, if any. -*/ - -static __inline__ wordint -bytesToWordint(wordintBytes const bytes) { - return (wordint) ntohl(*(wordint *)bytes); -} - - - -static __inline__ void -wordintToBytes(wordintBytes * const bytesP, - wordint const wordInt) { - - *(wordint *)bytesP = htonl(wordInt); -} - - - -static __inline__ unsigned int -wordintClz(wordint const x) { - - /* Find the data type closest to 32 bits, and file off any extra. */ - - if (x == 0) - return sizeof(wordint) * 8; - else if (sizeof(int) >= 4) - return __builtin_clz((int)x << (sizeof(int) - 4) * 8); - else if (sizeof(long int) >= 4) - return __builtin_clzl((long int)x << (sizeof(long int) - 4) * 8); - else - pm_error("Long int is less than 32 bits on this machine"); -} - diff --git a/lib/util/wordaccess_generic.h b/lib/util/wordaccess_generic.h index 7f27ef74..94cc8124 100644 --- a/lib/util/wordaccess_generic.h +++ b/lib/util/wordaccess_generic.h @@ -5,85 +5,25 @@ * Compilers other than GCC * GCC before version 3.4 - * c libraries other than Glibc * Specified by the user with WORDACCESS_GENERIC =============================================================================*/ +#include "intcode.h" + typedef uint32_t wordint; typedef unsigned char wordintBytes[sizeof(wordint)]; + static __inline__ wordint -bytesToWordint(wordintBytes const bytes) { - wordint retval; - unsigned int i; +bytesToWordint(wordintBytes const bytes) { - /* Note that 'bytes' is a pointer, due to C array degeneration. - That means sizeof(bytes) isn't what you think it is. - */ - - for (i = 1, retval = bytes[0]; i < sizeof(wordint); ++i) { - retval = (retval << 8) + bytes[i]; - } - return retval; + return (wordint) pm_uintFromBigend32( * (bigend32*) bytes); } - static __inline__ void wordintToBytes(wordintBytes * const bytesP, - wordint const wordInt) { - - wordint buffer; - int i; - - for (i = sizeof(*bytesP)-1, buffer = wordInt; i >= 0; --i) { - (*bytesP)[i] = buffer & 0xFF; - buffer >>= 8; - } -} - -static unsigned char const clz8[256]= { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - - -static __inline__ unsigned int -clz16(wordint const x) { - if (x >> 8 != 0) - return clz8[x >> 8]; - else - return clz8[x] + 8; -} - - - -static __inline__ unsigned int -clz32(wordint const x) { - if (x >> 16 != 0) - return clz16(x >> 16); - else - return clz16(x) +16; -} - - + wordint const wordInt) { -static __inline__ unsigned int -wordintClz(wordint const x) { - return clz32(x); + * (bigend32*) bytesP = pm_bigendFromUint32((uint32_t)wordInt); } |