mirror of
				https://github.com/facebook/zstd.git
				synced 2025-10-31 16:47:48 +02:00 
			
		
		
		
	Merge branch 'dev' into http-to-https
This commit is contained in:
		| @@ -190,25 +190,6 @@ typedef   signed long long  S64; | ||||
| /**************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* FSE_FORCE_MEMORY_ACCESS | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets generating assembly depending on alignment. | ||||
|  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef FSE_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define FSE_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static unsigned FSE_32bits(void) | ||||
| { | ||||
| @@ -221,24 +202,6 @@ static unsigned FSE_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| static U16 FSE_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| static U32 FSE_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| static U64 FSE_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| #elif defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign; | ||||
|  | ||||
| static U16 FSE_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| static U32 FSE_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| static U64 FSE_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| static U16 FSE_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -254,8 +217,6 @@ static U64 FSE_read64(const void* memPtr) | ||||
|     U64 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| } | ||||
|  | ||||
| #endif /* FSE_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
| static U16 FSE_readLE16(const void* memPtr) | ||||
| { | ||||
|     if (FSE_isLittleEndian()) | ||||
|   | ||||
| @@ -115,24 +115,6 @@ extern "C" { | ||||
| /**************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets generating assembly depending on alignment. | ||||
|  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } | ||||
| @@ -143,33 +125,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -190,9 +145,6 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
|  | ||||
| MEM_STATIC U16 MEM_readLE16(const void* memPtr) | ||||
| { | ||||
|     if (MEM_isLittleEndian()) | ||||
|   | ||||
| @@ -116,24 +116,6 @@ extern "C" { | ||||
| /**************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets generating assembly depending on alignment. | ||||
|  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } | ||||
| @@ -144,33 +126,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -191,10 +146,6 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
|  | ||||
| MEM_STATIC U16 MEM_readLE16(const void* memPtr) | ||||
| { | ||||
|     if (MEM_isLittleEndian()) | ||||
|   | ||||
| @@ -87,24 +87,6 @@ extern "C" { | ||||
| /**************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets generating assembly depending on alignment. | ||||
|  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } | ||||
| @@ -115,33 +97,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -162,9 +117,6 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
|  | ||||
| MEM_STATIC U16 MEM_readLE16(const void* memPtr) | ||||
| { | ||||
|     if (MEM_isLittleEndian()) | ||||
|   | ||||
| @@ -106,24 +106,6 @@ extern "C" { | ||||
| /*-************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS : | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets depending on alignment. | ||||
|  *            In some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } | ||||
| @@ -134,37 +116,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard, by lying on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
| MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } | ||||
| MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
| MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } | ||||
| MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -195,9 +146,6 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
|  | ||||
| MEM_STATIC U16 MEM_readLE16(const void* memPtr) | ||||
| { | ||||
|     if (MEM_isLittleEndian()) | ||||
|   | ||||
| @@ -108,24 +108,6 @@ extern "C" { | ||||
| /*-************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS : | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets depending on alignment. | ||||
|  *            In some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } | ||||
| @@ -136,33 +118,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard, by lying on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -183,9 +138,6 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
| MEM_STATIC U32 MEM_swap32(U32 in) | ||||
| { | ||||
| #if defined(_MSC_VER)     /* Visual Studio */ | ||||
| @@ -4035,7 +3987,8 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd, | ||||
|                     size_t const toLoad = hSize - zbd->lhSize;   /* if hSize!=0, hSize > zbd->lhSize */ | ||||
|                     if (ZSTDv06_isError(hSize)) return hSize; | ||||
|                     if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */ | ||||
|                         memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip); | ||||
|                         if (ip != NULL) | ||||
|                             memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip); | ||||
|                         zbd->lhSize += iend-ip; | ||||
|                         *dstCapacityPtr = 0; | ||||
|                         return (hSize - zbd->lhSize) + ZSTDv06_blockHeaderSize;   /* remaining header bytes + next block header */ | ||||
|   | ||||
| @@ -268,24 +268,6 @@ extern "C" { | ||||
| /*-************************************************************** | ||||
| *  Memory I/O | ||||
| *****************************************************************/ | ||||
| /* MEM_FORCE_MEMORY_ACCESS : | ||||
|  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. | ||||
|  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. | ||||
|  * The below switch allow to select different access method for improved performance. | ||||
|  * Method 0 (default) : use `memcpy()`. Safe and portable. | ||||
|  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). | ||||
|  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. | ||||
|  * Method 2 : direct access. This method is portable but violate C standard. | ||||
|  *            It can generate buggy code on targets depending on alignment. | ||||
|  *            In some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) | ||||
|  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. | ||||
|  * Prefer these methods in priority order (0 > 1 > 2) | ||||
|  */ | ||||
| #ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */ | ||||
| #  if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) | ||||
| #    define MEM_FORCE_MEMORY_ACCESS 1 | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } | ||||
| MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } | ||||
| @@ -296,33 +278,6 @@ MEM_STATIC unsigned MEM_isLittleEndian(void) | ||||
|     return one.c[0]; | ||||
| } | ||||
|  | ||||
| #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) | ||||
|  | ||||
| /* violates C standard, by lying on structure alignment. | ||||
| Only use if no other choice to achieve best performance on target platform */ | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } | ||||
| MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } | ||||
| MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } | ||||
|  | ||||
| #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) | ||||
|  | ||||
| /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ | ||||
| /* currently only defined for gcc and icc */ | ||||
| typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign; | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } | ||||
| MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } | ||||
| MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } | ||||
|  | ||||
| MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } | ||||
|  | ||||
| #else | ||||
|  | ||||
| /* default method, safe and standard. | ||||
|    can sometimes prove slower */ | ||||
|  | ||||
| MEM_STATIC U16 MEM_read16(const void* memPtr) | ||||
| { | ||||
|     U16 val; memcpy(&val, memPtr, sizeof(val)); return val; | ||||
| @@ -343,8 +298,6 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value) | ||||
|     memcpy(memPtr, &value, sizeof(value)); | ||||
| } | ||||
|  | ||||
| #endif /* MEM_FORCE_MEMORY_ACCESS */ | ||||
|  | ||||
| MEM_STATIC U32 MEM_swap32(U32 in) | ||||
| { | ||||
| #if defined(_MSC_VER)     /* Visual Studio */ | ||||
| @@ -4417,7 +4370,8 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd, | ||||
|                 if (hSize != 0) { | ||||
|                     size_t const toLoad = hSize - zbd->lhSize;   /* if hSize!=0, hSize > zbd->lhSize */ | ||||
|                     if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */ | ||||
|                         memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip); | ||||
|                         if (ip != NULL) | ||||
|                             memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip); | ||||
|                         zbd->lhSize += iend-ip; | ||||
|                         *dstCapacityPtr = 0; | ||||
|                         return (hSize - zbd->lhSize) + ZSTDv07_blockHeaderSize;   /* remaining header bytes + next block header */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user