summaryrefslogtreecommitdiffstats
path: root/lz4.c
diff options
context:
space:
mode:
authoryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>2012-02-20 20:53:49 (GMT)
committeryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>2012-02-20 20:53:49 (GMT)
commitecbce64ac93a81784c23c0cb8fe9ae8ede0866f9 (patch)
tree495f2885ee99740f09eb17c6d2adb077a10a8f04 /lz4.c
parent4045a42bb14007bd982e256c2ac97cc8695de9cd (diff)
downloadlz4-ecbce64ac93a81784c23c0cb8fe9ae8ede0866f9.zip
lz4-ecbce64ac93a81784c23c0cb8fe9ae8ede0866f9.tar.gz
lz4-ecbce64ac93a81784c23c0cb8fe9ae8ede0866f9.tar.bz2
Corrected : default to Software Bit Count for GCC earlier than 3.4. Thanks to Gray.
Corrected : ARM compilation under Visual Studio : now generates cautious code, like GCC, to ensure compatibility with strict-align CPUs. Thanks to Joe WoodBury. Minor : bench.c : Hash verification changed to MurmurHash3A Minor : bench.c : selectable block size git-svn-id: https://lz4.googlecode.com/svn/trunk@56 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
Diffstat (limited to 'lz4.c')
-rw-r--r--lz4.c78
1 files changed, 35 insertions, 43 deletions
diff --git a/lz4.c b/lz4.c
index 2c3f1c4..a131a81 100644
--- a/lz4.c
+++ b/lz4.c
@@ -70,15 +70,15 @@
// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
#endif
-// Unaligned memory access ?
-// This feature is automatically enabled for "common" CPU, such as x86.
-// For others CPU, you may want to force this option manually to improve performance if your target CPU supports unaligned memory access
+// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
+// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
+// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance
#if defined(__ARM_FEATURE_UNALIGNED)
#define LZ4_FORCE_UNALIGNED_ACCESS 1
#endif
-// Uncomment this parameter if your target system does not support hardware bit count
-//#define _FORCE_SW_BITCOUNT
+// Uncomment this parameter if your target system or compiler does not support hardware bit count
+//#define LZ4_FORCE_SW_BITCOUNT
@@ -95,12 +95,6 @@
#define inline __forceinline // Visual is not C99, but supports inline
#endif
-#if (defined(__GNUC__) && (!defined(LZ4_FORCE_UNALIGNED_ACCESS)))
-#define _PACKED __attribute__ ((packed))
-#else
-#define _PACKED
-#endif
-
#ifdef _MSC_VER // Visual Studio
#define bswap16(i) _byteswap_ushort(i)
#else
@@ -134,11 +128,32 @@
#define U64 uint64_t
#endif
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(push, 1)
+#endif
+
+typedef struct _U16_S { U16 v; } U16_S;
+typedef struct _U32_S { U32 v; } U32_S;
+typedef struct _U64_S { U64 v; } U64_S;
+
+#ifndef LZ4_FORCE_UNALIGNED_ACCESS
+#pragma pack(pop)
+#endif
+
+#define A64(x) (((U64_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A16(x) (((U16_S *)(x))->v)
+
//**************************************
// Constants
//**************************************
#define MINMATCH 4
+
+#define HASH_LOG COMPRESSIONLEVEL
+#define HASHTABLESIZE (1 << HASH_LOG)
+#define HASH_MASK (HASHTABLESIZE - 1)
+
#define SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION>2?NOTCOMPRESSIBLE_CONFIRMATION:2)
#define STACKLIMIT 13
#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
@@ -150,10 +165,6 @@
#define MAXD_LOG 16
#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
-#define HASH_LOG COMPRESSIONLEVEL
-#define HASHTABLESIZE (1 << HASH_LOG)
-#define HASH_MASK (HASHTABLESIZE - 1)
-
#define ML_BITS 4
#define ML_MASK ((1U<<ML_BITS)-1)
#define RUN_BITS (8-ML_BITS)
@@ -200,25 +211,6 @@ struct refTables
HTYPE hashTable[HASHTABLESIZE];
};
-typedef struct _U64_S
-{
- U64 v;
-} _PACKED U64_S;
-
-typedef struct _U32_S
-{
- U32 v;
-} _PACKED U32_S;
-
-typedef struct _U16_S
-{
- U16 v;
-} _PACKED U16_S;
-
-#define A64(x) (((U64_S *)(x))->v)
-#define A32(x) (((U32_S *)(x))->v)
-#define A16(x) (((U16_S *)(x))->v)
-
//**************************************
// Macros
@@ -237,11 +229,11 @@ typedef struct _U16_S
inline static int LZ4_NbCommonBytes (register U64 val)
{
#if defined(LZ4_BIG_ENDIAN)
- #if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
+ #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanReverse64( &r, val );
return (int)(r>>3);
- #elif defined(__GNUC__) && !defined(_FORCE_SW_BITCOUNT)
+ #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clzll(val) >> 3);
#else
int r;
@@ -251,11 +243,11 @@ inline static int LZ4_NbCommonBytes (register U64 val)
return r;
#endif
#else
- #if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
+ #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanForward64( &r, val );
return (int)(r>>3);
- #elif defined(__GNUC__) && !defined(_FORCE_SW_BITCOUNT)
+ #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctzll(val) >> 3);
#else
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
@@ -269,11 +261,11 @@ inline static int LZ4_NbCommonBytes (register U64 val)
inline static int LZ4_NbCommonBytes (register U32 val)
{
#if defined(LZ4_BIG_ENDIAN)
- #if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
+ #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanReverse( &r, val );
return (int)(r>>3);
- #elif defined(__GNUC__) && !defined(_FORCE_SW_BITCOUNT)
+ #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_clz(val) >> 3);
#else
int r;
@@ -282,15 +274,15 @@ inline static int LZ4_NbCommonBytes (register U32 val)
return r;
#endif
#else
- #if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
+ #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
unsigned long r = 0;
_BitScanForward( &r, val );
return (int)(r>>3);
- #elif defined(__GNUC__) && !defined(_FORCE_SW_BITCOUNT)
+ #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
return (__builtin_ctz(val) >> 3);
#else
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
- return DeBruijnBytePos[((U32)((val & -val) * 0x077CB531U)) >> 27];
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
#endif
#endif
}