Skip to content

Commit

Permalink
[asm] Share portability macros and restrict ASM further
Browse files Browse the repository at this point in the history
Move portability macros to `lib/common/portability_macros.h`. This file
only contains platform/feature detection (e.g. 0/1 macros). This file is
shared between C and ASM code, so it cannot include any C code.

Rename `HUF_` ASM macros to be `ZSTD_` prefixed, and move to the new
header.

Restrict `ZSTD_ASM_SUPPORTED` to `__GNUC__`, because we need the GAS
assembler.

Finally, only include the ASM code if we are actually going to use it.
This disables it on all Windows platforms, which should resolve the
problem brought up in Issue #2789.
  • Loading branch information
terrelln committed Dec 1, 2021
1 parent e34e58b commit 9b9936b
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 96 deletions.
60 changes: 2 additions & 58 deletions lib/common/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#ifndef ZSTD_COMPILER_H
#define ZSTD_COMPILER_H

#include "portability_macros.h"

/*-*******************************************************
* Compiler specifics
*********************************************************/
Expand Down Expand Up @@ -92,9 +94,6 @@


/* target attribute */
#ifndef __has_attribute
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if defined(__GNUC__) || defined(__ICCARM__)
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
#else
Expand All @@ -107,22 +106,6 @@
*/
#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")


/* Enable runtime BMI2 dispatch based on the CPU.
* Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
*/
#ifndef DYNAMIC_BMI2
#if ((defined(__clang__) && __has_attribute(__target__)) \
|| (defined(__GNUC__) \
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
&& (defined(__x86_64__) || defined(_M_X64)) \
&& !defined(__BMI2__)
# define DYNAMIC_BMI2 1
#else
# define DYNAMIC_BMI2 0
#endif
#endif

/* prefetch
* can be disabled, by declaring NO_PREFETCH build macro */
#if defined(NO_PREFETCH)
Expand Down Expand Up @@ -221,16 +204,6 @@
# endif
#endif

/* compat. with non-clang compilers */
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif

/* compat. with non-clang compilers */
#ifndef __has_feature
# define __has_feature(x) 0
#endif

/* C-language Attributes are added in C23. */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
Expand Down Expand Up @@ -264,24 +237,6 @@
# endif
#endif

/* detects whether we are being compiled under msan */
#ifndef ZSTD_MEMORY_SANITIZER
# if __has_feature(memory_sanitizer)
# define ZSTD_MEMORY_SANITIZER 1
# else
# define ZSTD_MEMORY_SANITIZER 0
# endif
#endif

/* detects whether we are being compiled undef dfsan */
#ifndef ZSTD_DATAFLOW_SANITIZER
# if __has_feature(dataflow_sanitizer)
# define ZSTD_DATAFLOW_SANITIZER 1
# else
# define ZSTD_DATAFLOW_SANITIZER 0
# endif
#endif

#if ZSTD_MEMORY_SANITIZER
/* Not all platforms that support msan provide sanitizers/msan_interface.h.
* We therefore declare the functions we need ourselves, rather than trying to
Expand All @@ -303,17 +258,6 @@ void __msan_poison(const volatile void *a, size_t size);
intptr_t __msan_test_shadow(const volatile void *x, size_t size);
#endif

/* detects whether we are being compiled under asan */
#ifndef ZSTD_ADDRESS_SANITIZER
# if __has_feature(address_sanitizer)
# define ZSTD_ADDRESS_SANITIZER 1
# elif defined(__SANITIZE_ADDRESS__)
# define ZSTD_ADDRESS_SANITIZER 1
# else
# define ZSTD_ADDRESS_SANITIZER 0
# endif
#endif

#if ZSTD_ADDRESS_SANITIZER
/* Not all platforms that support asan provide sanitizers/asan_interface.h.
* We therefore declare the functions we need ourselves, rather than trying to
Expand Down
48 changes: 12 additions & 36 deletions lib/decompress/huf_decompress.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,7 @@
#error "Cannot force the use of the X1 and X2 decoders at the same time!"
#endif

/* Only use assembly on Linux / MacOS.
* Disable when MSAN is enabled.
*/
#if defined(__linux__) || defined(__linux) || defined(__APPLE__)
# if ZSTD_MEMORY_SANITIZER
# define HUF_ASM_SUPPORTED 0
# elif ZSTD_DATAFLOW_SANITIZER
# define HUF_ASM_SUPPORTED 0
# else
# define HUF_ASM_SUPPORTED 1
# endif
#else
# define HUF_ASM_SUPPORTED 0
#endif

/* HUF_DISABLE_ASM: Disables all ASM implementations. */
#if !defined(HUF_DISABLE_ASM) && \
HUF_ASM_SUPPORTED && \
defined(__x86_64__) && (DYNAMIC_BMI2 || defined(__BMI2__))
# define HUF_ENABLE_ASM_X86_64_BMI2 1
#else
# define HUF_ENABLE_ASM_X86_64_BMI2 0
#endif

#if HUF_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2
# define HUF_ASM_X86_64_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE
#else
# define HUF_ASM_X86_64_BMI2_ATTRS
Expand All @@ -80,13 +56,13 @@
#endif
#define HUF_ASM_DECL HUF_EXTERN_C

#if DYNAMIC_BMI2 || (HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
#if DYNAMIC_BMI2 || (ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
# define HUF_NEED_BMI2_FUNCTION 1
#else
# define HUF_NEED_BMI2_FUNCTION 0
#endif

#if !(HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
#if !(ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
# define HUF_NEED_DEFAULT_FUNCTION 1
#else
# define HUF_NEED_DEFAULT_FUNCTION 0
Expand Down Expand Up @@ -162,7 +138,7 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
return dtd;
}

#if HUF_ENABLE_ASM_X86_64_BMI2
#if ZSTD_ENABLE_ASM_X86_64_BMI2

static size_t HUF_initDStream(BYTE const* ip) {
BYTE const lastByte = ip[7];
Expand Down Expand Up @@ -685,7 +661,7 @@ size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize,
}
#endif

#if HUF_ENABLE_ASM_X86_64_BMI2
#if ZSTD_ENABLE_ASM_X86_64_BMI2

HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args);

Expand Down Expand Up @@ -741,7 +717,7 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm(
/* decoded size */
return dstSize;
}
#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */
#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */

typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,
const void *cSrc,
Expand All @@ -755,7 +731,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize,
{
#if DYNAMIC_BMI2
if (bmi2) {
# if HUF_ENABLE_ASM_X86_64_BMI2
# if ZSTD_ENABLE_ASM_X86_64_BMI2
return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
# else
return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
Expand All @@ -765,7 +741,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize,
(void)bmi2;
#endif

#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
#else
return HUF_decompress4X1_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
Expand Down Expand Up @@ -1401,7 +1377,7 @@ size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize,
}
#endif

#if HUF_ENABLE_ASM_X86_64_BMI2
#if ZSTD_ENABLE_ASM_X86_64_BMI2

HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args);

Expand Down Expand Up @@ -1453,14 +1429,14 @@ HUF_decompress4X2_usingDTable_internal_bmi2_asm(
/* decoded size */
return dstSize;
}
#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */
#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */

static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
size_t cSrcSize, HUF_DTable const* DTable, int bmi2)
{
#if DYNAMIC_BMI2
if (bmi2) {
# if HUF_ENABLE_ASM_X86_64_BMI2
# if ZSTD_ENABLE_ASM_X86_64_BMI2
return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
# else
return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
Expand All @@ -1470,7 +1446,7 @@ static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize,
(void)bmi2;
#endif

#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
#else
return HUF_decompress4X2_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
Expand Down
4 changes: 3 additions & 1 deletion lib/decompress/huf_decompress_amd64.S
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#if !defined(HUF_DISABLE_ASM) && defined(__x86_64__)
#include "../common/portability_macros.h"

#if ZSTD_ENABLE_ASM_X86_64_BMI2

/* Stack marking
* ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
Expand Down
2 changes: 1 addition & 1 deletion lib/libzstd.mk
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ZSTD_LEGACY_FILES :=
ZSTD_DECOMPRESS_AMD64_ASM_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*_amd64.S))

ifneq ($(ZSTD_NO_ASM), 0)
CPPFLAGS += -DHUF_DISABLE_ASM
CPPFLAGS += -DZSTD_DISABLE_ASM
else
# Unconditionally add the ASM files they are disabled by
# macros in the .S file.
Expand Down

0 comments on commit 9b9936b

Please sign in to comment.