Specialized defines to work with/around Clang integrated assembler. The two defines are WORKAROUND_LLVM_BUG_18916 and CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER. Once the 18916 bug is fixed, the other issues around the integrated assembler will remain

This commit is contained in:
Jeffrey Walton 2015-07-22 03:48:10 -04:00
parent 931ec17224
commit 6d0dd41eb0
7 changed files with 72 additions and 30 deletions

View File

@ -25,9 +25,9 @@ ifeq ($(PREFIX),)
PREFIX = /usr
endif
# Sadly, we can't actually use GCC_PRAGMA_AWARE because of GCC bug 53431.
# Its a shame because GCC has so much to offer by the way of analysis.
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
# Sadly, we can't actually use GCC_PRAGMA_AWARE with GCC because of GCC bug 53431.
# Its a shame because GCC has so much to offer by the way of analysis. Clang works
# as expected, though. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53431
ifneq ($(CLANG_COMPILER),0)
CXXFLAGS += -Wall
endif
@ -36,26 +36,41 @@ ifeq ($(IS_X86),1)
GCC42_OR_LATER = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version (4.[2-9]|[5-9])")
ICC111_OR_LATER = $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\) ([2-9][0-9]|1[2-9]|11\.[1-9])")
GAS210_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.[1-9][0-9]|[3-9])")
GAS217_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.1[7-9]|2\.[2-9]|[3-9])")
GAS219_OR_LATER = $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])")
GAS210_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.[1-9][0-9]|[3-9])")
GAS217_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.1[7-9]|2\.[2-9]|[3-9])")
GAS219_OR_LATER ?= $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])")
# Enable PIC for x86_64 targets
ifneq ($(IS_X86_64),0)
CXXFLAGS += -fPIC
endif # PIC for x86_64 targets
# Undefined Behavior Sanitzier (Clang and G++)
# Undefined Behavior Sanitizer (Clang 3.2 and GCC 4.8 and above)
ifeq ($(findstring ubsan,$(MAKECMDGOALS)),ubsan)
CXXFLAGS += -fsanitize=undefined
# CXXFLAGS += -fsanitize-undefined-trap-on-error
# CXXFLAGS += -fsanitize-undefined-trap-on-error
endif # UBsan
# Address Sanitzier (Clang and G++)
# Address Sanitizer (Clang 3.2 and GCC 4.8 and above)
ifeq ($(findstring asan,$(MAKECMDGOALS)),asan)
CXXFLAGS += -fsanitize=address
endif # Asan
# Test CXXFLAGS in case the user passed the flags directly through it
ASAN = 0
UBSAN = 0
ifeq ($(findstring -fsanitize=address,$(CXXFLAGS)),-fsanitize=address)
ASAN = 1
endif
ifeq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),-fsanitize=undefined)
UBSAN = 1
endif
# Enforce Sanitizer business logic...
ifeq ($(ASAN)$(UBSAN),11)
$(error Asan and UBsan are mutually exclusive)
endif
# Cygwin work arounds
ifneq ($(IS_CYGWIN),0)
@ -70,7 +85,7 @@ CXXFLAGS := $(subst -fPIC,,$(CXXFLAGS))
endif # -fPIC
# -O3 fails to link with GCC 4.5.3
IS_GCC45 = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version 4\.5\.")
IS_GCC45 = $(shell $(CXX) -v 2>&1 | $(EGREP) -i -c "^gcc version 4\.5\.[0-9]")
ifneq ($(IS_GCC45),0)
ifeq ($(findstring -O3,$(CXXFLAGS)),-O3)
CXXFLAGS := $(subst -O3,-O2,$(CXXFLAGS))

View File

@ -71,7 +71,15 @@
// Define this if you are working around Clang's integrated assembler bug by
// disabling the assembler (https://llvm.org/bugs/show_bug.cgi?id=18916).
// #define CRYPTOPP_CLANG_NO_INTEGRATED_AS
// When the LLVM project fixes it, then we turn it on/off automatically.
#define WORKAROUND_LLVM_BUG_18916
// Define this if you are working with Clang's integrated assembler. As far as we know,
// the only way to tell is `$(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1`. The
// integrated assembler will return `clang: error: unsupported argument '-v' option`.
#if defined(__clang__)
#define CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER
#endif
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
// Avoid putting "CryptoPP::" in front of everything in Doxygen output

31
cpu.h
View File

@ -209,6 +209,23 @@ inline int GetCacheLineSize()
#define ASC(x, y) __asm {x label##y}
#define CRYPTOPP_NAKED __declspec(naked)
#define AS_HEX(y) 0x##y
#elif defined(__clang__) && defined(CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER)
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
// define these in two steps to allow arguments to be expanded
#define GNU_AS1(x) "\n\t" #x ";"
#define GNU_AS2(x, y) "\n\t" #x ", " #y ";"
#define GNU_AS3(x, y, z) "\n\t" #x ", " #y ", " #z ";"
#define GNU_ASL(x) "\n\t#x:"
#define GNU_ASJ(x, y, z) "\n\t#x " #y #z ";"
#define AS1(x) GNU_AS1(x)
#define AS2(x, y) GNU_AS2(x, y)
#define AS3(x, y, z) GNU_AS3(x, y, z)
#define ASS(x, y, a, b, c, d) "\n\t" #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
#define ASL(x) GNU_ASL(x)
#define ASJ(x, y, z) GNU_ASJ(x, y, z)
#define ASC(x, y) "\n\t" #x " " #y ";"
#define CRYPTOPP_NAKED
#define AS_HEX(y) 0x##y
#else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
// define these in two steps to allow arguments to be expanded
@ -229,15 +246,15 @@ inline int GetCacheLineSize()
#endif
// https://llvm.org/bugs/show_bug.cgi?id=18916
#if defined(__clang__)
# define GNU_ATT_SYNTAX ".att_syntax;"
# define GNU_INTEL_SYNTAX ".intel_syntax;"
#if defined(__clang__) && defined(WORKAROUND_LLVM_BUG_18916)
# define GNU_AS_ATT_SYNTAX ".att_syntax;"
# define GNU_AS_INTEL_SYNTAX ".intel_syntax;" "\n"
#elif defined(__GNUC__)
# define GNU_ATT_SYNTAX ".att_syntax prefix;"
# define GNU_INTEL_SYNTAX ".intel_syntax noprefix;"
# define GNU_AS_ATT_SYNTAX ".att_syntax prefix;"
# define GNU_AS_INTEL_SYNTAX ".intel_syntax noprefix;"
#else
# define GNU_ATT_SYNTAX ".att_syntax prefix;"
# define GNU_INTEL_SYNTAX ".intel_syntax noprefix;"
# define GNU_AS_ATT_SYNTAX ".att_syntax prefix;"
# define GNU_AS_INTEL_SYNTAX ".intel_syntax noprefix;"
#endif
#define IF0(y)

View File

@ -538,7 +538,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
word result;
__asm__ __volatile__
(
".intel_syntax;"
".intel_syntax;" "\n"
AS1( neg %1)
ASJ( jz, 1, f)
AS2( mov %0,[%3+8*%1])
@ -557,7 +557,7 @@ int Baseline_Add(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
".att_syntax;"
".att_syntax;" "\n"
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
@ -589,12 +589,12 @@ int Baseline_Sub(size_t N, word *C, const word *A, const word *B)
ASL(1)
AS2( mov %0, 0)
AS2( adc %0, %0)
".att_syntax;"
".att_syntax;" "\n"
: "=&r" (result), "+c" (N)
: "r" (C+N), "r" (A+N), "r" (B+N)
: "memory", "cc"
);
return (int)result;
return static_cast<int>(result);
}
#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && CRYPTOPP_BOOL_X86
CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B)
@ -2978,10 +2978,8 @@ static Integer StringToInteger(const T *str)
unsigned int length;
for (length = 0; str[length] != 0; length++) {}
Integer v;
if (length == 0)
return v;
return Integer::Zero();
switch (str[length-1])
{
@ -3002,8 +3000,12 @@ static Integer StringToInteger(const T *str)
}
if (length > 2 && str[0] == '0' && str[1] == 'x')
{
radix = 16;
str += 2, length -= 2;
}
Integer v;
for (unsigned i=0; i<length; i++)
{
int digit;

View File

@ -841,7 +841,7 @@ CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state
#if defined(__GNUC__)
AS1( pop ebx)
GNU_AS_ATT_SYNTAX
ASSL(GNU_AS_ATT_SYNTAX)
:
: "a" (SHA512_K), "c" (state), "d" (data)
: "%esi", "%edi", "memory", "cc"

View File

@ -38,7 +38,7 @@ void Tiger::Transform (word64 *digest, const word64 *X)
#ifdef __GNUC__
__asm__ __volatile__
(
GNU_AS_INTEL_SYNTAX
// GNU_AS_INTEL_SYNTAX
AS1( push ebx)
#else
#if _MSC_VER < 1300
@ -194,7 +194,7 @@ void Tiger::Transform (word64 *digest, const word64 *X)
AS1( emms)
#ifdef __GNUC__
AS1( pop ebx)
GNU_AS_ATT_SYNTAX
ASSL(GNU_AS_ATT_SYNTAX)
:
: "a" (digest), "S" (X), "d" (table)
: "%ecx", "%edi", "memory", "cc"

View File

@ -158,7 +158,7 @@ VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64,
(
AS2( mov %%ebx, %0)
AS2( mov %1, %%ebx)
GNU_AS_INTEL_SYNTAX
// GNU_AS_INTEL_SYNTAX
#else
#if _MSC_VER < 1300 || defined(__INTEL_COMPILER)
char isFirstBlock = m_isFirstBlock;
@ -377,7 +377,7 @@ VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64,
AS1( pop ebp)
AS1( emms)
#ifdef __GNUC__
GNU_AS_ATT_SYNTAX
ASSL(GNU_AS_ATT_SYNTAX)
AS2( mov %0, %%ebx)
: "=m" (temp)
: "m" (L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4)