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