diff --git a/config.h b/config.h index de93c841..498d917f 100644 --- a/config.h +++ b/config.h @@ -602,19 +602,21 @@ NAMESPACE_END // An old Apple G5 with GCC 4.01 has AltiVec, but its only Power4 or so. // We need Power7 or above, so the makefile defines CRYPTOPP_DISABLE_ALTIVEC. -#if !defined(CRYPTOPP_ALTIVEC_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC) && !defined(CRYPTOPP_DISABLE_ASM) -# if defined(__ALTIVEC__) || (CRYPTOPP_XLC_VERSION >= 100000) || (CRYPTOPP_GCC_VERSION >= 40000) +#if !defined(CRYPTOPP_POWER7_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC) && !defined(CRYPTOPP_DISABLE_ASM) +# if defined(_ARCH_PWR7) || (CRYPTOPP_XLC_VERSION >= 100000) || (CRYPTOPP_GCC_VERSION >= 40000) # define CRYPTOPP_ALTIVEC_AVAILABLE 1 +# define CRYPTOPP_POWER7_AVAILABLE 1 # endif #endif -#if !defined(CRYPTOPP_POWER8_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) && defined(CRYPTOPP_ALTIVEC_AVAILABLE) +#if !defined(CRYPTOPP_POWER8_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC) && !defined(CRYPTOPP_DISABLE_ASM) # if defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || (CRYPTOPP_GCC_VERSION >= 40800) +# define CRYPTOPP_ALTIVEC_AVAILABLE 1 # define CRYPTOPP_POWER8_AVAILABLE 1 # endif #endif -#if !defined(CRYPTOPP_POWER8_CRYPTO_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) && defined(CRYPTOPP_ALTIVEC_AVAILABLE) +#if !defined(CRYPTOPP_POWER8_CRYPTO_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC) && !defined(CRYPTOPP_DISABLE_ASM) # if defined(__CRYPTO__) || defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || (CRYPTOPP_GCC_VERSION >= 40800) # define CRYPTOPP_POWER8_AES_AVAILABLE 1 //# define CRYPTOPP_POWER8_SHA_AVAILABLE 1 diff --git a/cpu.cpp b/cpu.cpp index c6149a4b..edd0c192 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -625,11 +625,12 @@ void DetectArmFeatures() #elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) bool CRYPTOPP_SECTION_INIT g_PowerpcDetectionDone = false; -bool CRYPTOPP_SECTION_INIT g_hasAltivec = false, CRYPTOPP_SECTION_INIT g_hasPower8 = false; +bool CRYPTOPP_SECTION_INIT g_hasAltivec = false, CRYPTOPP_SECTION_INIT g_hasPower7 = false, CRYPTOPP_SECTION_INIT g_hasPower8 = false; bool CRYPTOPP_SECTION_INIT g_hasAES = false, CRYPTOPP_SECTION_INIT g_hasSHA256 = false, CRYPTOPP_SECTION_INIT g_hasSHA512 = false; word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; extern bool CPU_ProbeAltivec(); +extern bool CPU_ProbePower7(); extern bool CPU_ProbePower8(); extern bool CPU_ProbeAES(); extern bool CPU_ProbeSHA256(); @@ -657,17 +658,15 @@ inline bool CPU_QueryAltivec() return false; } -#if 0 inline bool CPU_QueryPower7() { // Power7 and ISA 2.06 #if defined(__linux__) - if (getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) + if (getauxval(AT_HWCAP2) & PPC_FEATURE_ARCH_2_06) return true; #endif return false; } -#endif inline bool CPU_QueryPower8() { @@ -722,6 +721,7 @@ void DetectPowerpcFeatures() // The CPU_ProbeXXX's return false for OSes which // can't tolerate SIGILL-based probes, like Apple g_hasAltivec = CPU_QueryAltivec() || CPU_ProbeAltivec(); + g_hasPower7 = CPU_QueryPower7() || CPU_ProbePower7(); g_hasPower8 = CPU_QueryPower8() || CPU_ProbePower8(); //g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL(); g_hasAES = CPU_QueryAES() || CPU_ProbeAES(); @@ -736,7 +736,7 @@ void DetectPowerpcFeatures() g_cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); #endif - if (!g_cacheLineSize) + if (g_cacheLineSize <= 0) g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; g_PowerpcDetectionDone = true; diff --git a/cpu.h b/cpu.h index 35710a93..66336489 100644 --- a/cpu.h +++ b/cpu.h @@ -407,8 +407,11 @@ void CRYPTOPP_API DetectPowerpcFeatures(); //! \returns true if the hardware is capable of Altivec at runtime, false otherwise. //! \details Altivec instructions are available under most modern PowerPCs. //! \details Runtime support requires compile time support. When compiling with GCC, you may -//! need to compile with -mcpu=power8; while IBM XL C/C++ compilers require -//! -qarch=pwr8 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +//! need to compile with -mcpu=power7; while IBM XL C/C++ compilers require +//! -qarch=pwr7 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +//! \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned +//! loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the +//! GNUmakefile sets -DCRYPTOPP_DISABLE_ALTIVEC. //! \note This function is only available on PowerPC and PowerPC-64 platforms inline bool HasAltivec() { @@ -423,6 +426,26 @@ inline bool HasAltivec() //! \details Runtime support requires compile time support. When compiling with GCC, you may //! need to compile with -mcpu=power8; while IBM XL C/C++ compilers require //! -qarch=pwr8 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +//! \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned +//! loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the +//! GNUmakefile sets -DCRYPTOPP_DISABLE_ALTIVEC. +//! \note This function is only available on PowerPC and PowerPC-64 platforms +inline bool HasPower7() +{ + if (!g_PowerpcDetectionDone) + DetectPowerpcFeatures(); + return g_hasPower7; +} + +//! \brief Determine if a PowerPC processor has Power8 available +//! \returns true if the hardware is capable of Power8 at runtime, false otherwise. +//! \details Altivec instructions are available under most modern PowerPCs. +//! \details Runtime support requires compile time support. When compiling with GCC, you may +//! need to compile with -mcpu=power8; while IBM XL C/C++ compilers require +//! -qarch=pwr8 -qaltivec. Also see PowerPC's _ALTIVEC_ preprocessor macro. +//! \details Atilvec was first available on Power4 platforms. However Crypto++ releies on unaligned +//! loads and stores which is a Power7 feature. If the platform lacks Power7 extensions, then the +//! GNUmakefile sets -DCRYPTOPP_DISABLE_ALTIVEC. //! \note This function is only available on PowerPC and PowerPC-64 platforms inline bool HasPower8() { diff --git a/ppc-simd.cpp b/ppc-simd.cpp index b2d7b11c..471ca06b 100644 --- a/ppc-simd.cpp +++ b/ppc-simd.cpp @@ -97,12 +97,11 @@ bool CPU_ProbeAltivec() #endif // CRYPTOPP_ALTIVEC_AVAILABLE } -#if 0 bool CPU_ProbePower7() { #if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) return false; -#elif (CRYPTOPP_POWER7_AVAILABLE) && 0 +#elif (CRYPTOPP_POWER7_AVAILABLE) # if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY) // longjmp and clobber warnings. Volatile is required. @@ -121,7 +120,11 @@ bool CPU_ProbePower7() result = false; else { - // TODO + byte b1[19] = {255, 255, 255, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, b2[17]; + const uint8x16_p8 v1 = (uint8x16_p8)VectorLoad(0, b1+3); + VectorStore(v1, b2+1); + + result = (0 == std::memcmp(b1+3, b2+1, 16)); } sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); @@ -132,7 +135,6 @@ bool CPU_ProbePower7() return false; #endif // CRYPTOPP_POWER7_AVAILABLE } -#endif bool CPU_ProbePower8() { diff --git a/validat1.cpp b/validat1.cpp index b5062418..cd6dc837 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -376,14 +376,15 @@ bool TestSettings() std::cout << ", hasAES == " << hasAES << ", hasSHA1 == " << hasSHA1 << ", hasSHA2 == " << hasSHA2 << "\n"; #elif (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) - bool hasAltivec = HasAltivec(); - bool hasPower8 = HasPower8(); - bool hasAES = HasAES(); - bool hasSHA256 = HasSHA256(); - bool hasSHA512 = HasSHA512(); + const bool hasAltivec = HasAltivec(); + const bool hasPower7 = HasPower7(); + const bool hasPower8 = HasPower8(); + const bool hasAES = HasAES(); + const bool hasSHA256 = HasSHA256(); + const bool hasSHA512 = HasSHA512(); std::cout << "passed: "; - std::cout << "hasAltivec == " << hasAltivec << ", hasPower8 == " << hasPower8; + std::cout << "hasAltivec == " << hasAltivec << ", hasPower7 == " << hasPower7 << ", hasPower8 == " << hasPower8; std::cout << ", hasAES == " << hasAES << ", hasSHA256 == " << hasSHA256 << ", hasSHA512 == " << hasSHA512 << "\n"; #endif