Add VectorLoad and VectorStore test code

Applies to POWER4 and above only
pull/703/head
Jeffrey Walton 2018-08-06 22:19:59 -04:00
parent a4ebb75538
commit d4428d7f1c
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
5 changed files with 121 additions and 2 deletions

View File

@ -1210,6 +1210,9 @@ test.o : test.cpp
endif endif
endif endif
validat%.o : validat%.cpp
$(CXX) $(strip $(CXXFLAGS) $(ALTIVEC_FLAG) -c) $<
%.dllonly.o : %.cpp %.dllonly.o : %.cpp
$(CXX) $(strip $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c) $< -o $@ $(CXX) $(strip $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c) $< -o $@

View File

@ -408,7 +408,7 @@ inline void VectorStore(const T& src, int off, byte dest[16])
#endif #endif
} }
#else // not CRYPTOPP_POWER7_AVAILABLE #else // ########## Not CRYPTOPP_POWER7_AVAILABLE ##########
// POWER7 is not available. Slow Altivec loads and stores. // POWER7 is not available. Slow Altivec loads and stores.
inline uint32x4_p VectorLoad(const byte src[16]) inline uint32x4_p VectorLoad(const byte src[16])
@ -426,10 +426,21 @@ inline uint32x4_p VectorLoad(const byte src[16])
const uint8x16_p high = vec_ld(15, src); const uint8x16_p high = vec_ld(15, src);
data = vec_perm(low, high, perm); data = vec_perm(low, high, perm);
} }
}
/// \brief Loads a vector from a byte array
/// \param src the byte array
/// \details Loads a vector in big endian format from a byte array.
/// VectorLoadBE will swap endianess on little endian systems.
/// \note VectorLoadBE() does not require an aligned array.
/// \sa Reverse(), VectorLoadBE(), VectorLoad()
/// \since Crypto++ 6.0
inline uint32x4_p VectorLoadBE(const uint8_t src[16])
{
#if defined(CRYPTOPP_BIG_ENDIAN) #if defined(CRYPTOPP_BIG_ENDIAN)
return (uint32x4_p)data; return (uint32x4_p)VectorLoad(src);
#else #else
const uint8x16_p data = (uint8x16_p)VectorLoad(src);
const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
return (uint32x4_p)vec_perm(data, data, mask); return (uint32x4_p)vec_perm(data, data, mask);
#endif #endif
@ -463,6 +474,26 @@ inline void VectorStore(const uint32x4_p data, byte dest[16])
} }
} }
/// \brief Stores a vector to a byte array
/// \tparam T vector type
/// \param src the vector
/// \param dest the byte array
/// \details Stores a vector in big endian format to a byte array.
/// VectorStoreBE will swap endianess on little endian systems.
/// \note VectorStoreBE does not require an aligned array.
/// \sa Reverse(), VectorLoadBE(), VectorLoad()
/// \since Crypto++ 6.0
template <class T>
inline void VectorStoreBE(const T& src, uint8_t dest[16])
{
#if defined(CRYPTOPP_BIG_ENDIAN)
VectorStore(src, dest);
#else
const uint8x16_p mask = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0};
VectorStore(vec_perm(src, src, mask), dest);
#endif
}
#endif // POWER4/POWER7 load and store #endif // POWER4/POWER7 load and store
// POWER8 crypto // POWER8 crypto

View File

@ -993,6 +993,10 @@ bool Validate(int alg, bool thorough, const char *seedInput)
case 9994: result = TestHuffmanCodes(); break; case 9994: result = TestHuffmanCodes(); break;
// http://github.com/weidai11/cryptopp/issues/346 // http://github.com/weidai11/cryptopp/issues/346
case 9993: result = TestASN1Parse(); break; case 9993: result = TestASN1Parse(); break;
# if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
case 9992: result = TestAltivecOps(); break;
# endif
#endif #endif
default: return false; default: return false;

View File

@ -14,6 +14,10 @@
#include "gzip.h" #include "gzip.h"
#include "zlib.h" #include "zlib.h"
#if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
# include "ppc-simd.h"
#endif
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
@ -1058,5 +1062,79 @@ bool TestHuffmanCodes()
} }
#endif #endif
#if defined(CRYPTOPP_EXTENDED_VALIDATION)
# if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
bool TestAltivecOps()
{
std::cout << "\nTesting Altivec operations...\n\n";
bool pass=true;
if (HasAltivec() == false)
{
std::cout << "\nAltivec not available, skipping test." << std::endl;
return true;
}
//********** Unaligned loads and stores **********//
CRYPTOPP_ALIGN_DATA(16)
byte dest[20], src[20] = {23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4};
const byte exp1[16] ={22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7};
const byte exp2[16] ={21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6};
const byte exp3[16] ={20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5};
VectorStore(VectorLoad(src), dest);
pass = (0 == std::memcmp(src, dest, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStore(VectorLoad(src+1), dest+1);
pass = (0 == std::memcmp(exp1, dest+1, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStore(VectorLoad(src+2), dest+2);
pass = (0 == std::memcmp(exp2, dest+2, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStore(VectorLoad(src+3), dest+3);
pass = (0 == std::memcmp(exp3, dest+3, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStoreBE(VectorLoadBE(src), dest);
pass = (0 == std::memcmp(src, dest, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStoreBE(VectorLoadBE(src+1), dest+1);
pass = (0 == std::memcmp(exp1, dest+1, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStoreBE(VectorLoadBE(src+2), dest+2);
pass = (0 == std::memcmp(exp2, dest+2, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStoreBE(VectorLoadBE(src+3), dest+3);
pass = (0 == std::memcmp(exp3, dest+3, 16)) && pass;
CRYPTOPP_ASSERT(pass);
#if defined(CRYPTOPP_LITTLE_ENDIAN)
VectorStore(VectorLoadBE(src), dest);
pass = (0 != std::memcmp(src, dest, 16)) && pass;
CRYPTOPP_ASSERT(pass);
VectorStoreBE(VectorLoad(src), dest);
pass = (0 != std::memcmp(src, dest, 16)) && pass;
CRYPTOPP_ASSERT(pass);
#endif
if (!pass)
std::cout << "FAILED:";
else
std::cout << "passed:";
std::cout << " Altivec loads and stores" << std::endl;
return pass;
}
#endif
#endif
NAMESPACE_END // Test NAMESPACE_END // Test
NAMESPACE_END // CryptoPP NAMESPACE_END // CryptoPP

View File

@ -154,6 +154,9 @@ bool TestCompressors();
bool TestEncryptors(); bool TestEncryptors();
bool TestMersenne(); bool TestMersenne();
bool TestSharing(); bool TestSharing();
# if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
bool TestAltivecOps();
# endif
#endif #endif
class FixedRNG : public RandomNumberGenerator class FixedRNG : public RandomNumberGenerator