fix compile with -msse2 on systems without memalign()

pull/2/head
weidai 2004-07-18 09:23:13 +00:00
parent 7001c6d388
commit d617e3d925
4 changed files with 66 additions and 22 deletions

View File

@ -61,14 +61,17 @@
// Defining this will cause Crypto++ to make only one call to CryptAcquireContext.
#define WORKAROUND_MS_BUG_Q258000
// Avoid putting "CryptoPP::" in front of everything in Doxygen output
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
// Avoid putting "CryptoPP::" in front of everything in Doxygen output
# define CryptoPP
# define NAMESPACE_BEGIN(x)
# define NAMESPACE_END
// Get Doxygen to generate better documentation for these typedefs
# define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
#else
# define NAMESPACE_BEGIN(x) namespace x {
# define NAMESPACE_END }
# define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif
#define ANONYMOUS_NAMESPACE_BEGIN namespace {
#define USING_NAMESPACE(x) using namespace x;
@ -233,7 +236,7 @@ NAMESPACE_END
# define OS_RNG_AVAILABLE
#endif
#ifdef CRYPTOPP_UNIX_AVAILABLE
#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define NONBLOCKING_RNG_AVAILABLE
# define BLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
@ -246,6 +249,14 @@ NAMESPACE_END
# define THREADS_AVAILABLE
#endif
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#endif
#if defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
# define CRYPTOPP_MEMALIGN_AVAILABLE
#endif
#endif // NO_OS_DEPENDENCE
// ***************** DLL related ********************

View File

@ -20,14 +20,18 @@
#ifdef SSE2_INTRINSICS_AVAILABLE
#ifdef __GNUC__
#include <xmmintrin.h>
#include <malloc.h>
#include <signal.h>
#include <setjmp.h>
#ifdef CRYPTOPP_MEMALIGN_AVAILABLE
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#else
#include <emmintrin.h>
#endif
#elif defined(_MSC_VER) && defined(_M_IX86)
#pragma message("You do no seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.")
#pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.")
#elif defined(__GNUC__) && defined(__i386__)
#warning "You do not have GCC 3.3 or later, or did not specify -msse2 compiler option, so use of SSE2 intrinsics will be disabled."
#endif
@ -44,26 +48,40 @@ bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger,
static const char s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0);
#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER)
#ifdef SSE2_INTRINSICS_AVAILABLE
template <class T>
CPP_TYPENAME AllocatorBase<T>::pointer AlignedAllocator<T>::allocate(size_type n, const void *)
{
CheckSize(n);
if (n == 0)
return NULL;
#ifdef SSE2_INTRINSICS_AVAILABLE
if (n >= 4)
{
void *p;
#ifdef __GNUC__
while (!(p = memalign(16, sizeof(T)*n)))
#else
#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
while (!(p = _mm_malloc(sizeof(T)*n, 16)))
#elif defined(CRYPTOPP_MEMALIGN_AVAILABLE)
while (!(p = memalign(16, sizeof(T)*n)))
#elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16)
while (!(p = malloc(sizeof(T)*n)))
#else
while (!(p = (byte *)malloc(sizeof(T)*n + 8))) // assume malloc alignment is at least 8
#endif
CallNewHandler();
#ifdef CRYPTOPP_NO_ALIGNED_ALLOC
assert(m_pBlock == NULL);
m_pBlock = p;
if (!IsAlignedOn(p, 16))
{
assert(IsAlignedOn(p, 8));
p = (byte *)p + 8;
}
#endif
assert(IsAlignedOn(p, 16));
return (T*)p;
}
#endif
return new T[n];
}
@ -71,15 +89,19 @@ template <class T>
void AlignedAllocator<T>::deallocate(void *p, size_type n)
{
memset(p, 0, n*sizeof(T));
#ifdef SSE2_INTRINSICS_AVAILABLE
if (n >= 4)
#ifdef __GNUC__
free(p);
#else
{
#ifdef CRYPTOPP_MM_MALLOC_AVAILABLE
_mm_free(p);
#elif defined(CRYPTOPP_NO_ALIGNED_ALLOC)
assert(m_pBlock == p || (byte *)m_pBlock+8 == p);
free(m_pBlock);
m_pBlock = NULL;
#else
free(p);
#endif
}
else
#endif
delete [] (T *)p;
}
#endif

View File

@ -14,11 +14,13 @@
#ifdef _M_IX86
#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500))
#define SSE2_INTRINSICS_AVAILABLE
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(_MSC_VER)
// _mm_free seems to be the only way to tell if the Processor Pack is installed or not
#include <malloc.h>
#if defined(_mm_free)
#define SSE2_INTRINSICS_AVAILABLE
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#endif
#endif
#endif
@ -32,10 +34,7 @@
NAMESPACE_BEGIN(CryptoPP)
#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER)
// Defined this class for MSVC even if processor pack is not installed,
// so that the library can be compiled with processor pack, and calling app
// compiled without it.
#if defined(SSE2_INTRINSICS_AVAILABLE)
template <class T>
class AlignedAllocator : public AllocatorBase<T>
{
@ -48,11 +47,17 @@ NAMESPACE_BEGIN(CryptoPP)
{
return StandardReallocate(*this, p, oldSize, newSize, preserve);
}
#if !(defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) || defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE))
#define CRYPTOPP_NO_ALIGNED_ALLOC
AlignedAllocator() : m_pBlock(NULL) {}
protected:
void *m_pBlock;
#endif
};
template class CRYPTOPP_DLL AlignedAllocator<word>;
typedef SecBlock<word, AlignedAllocator<word> > SecAlignedWordBlock;
#else
typedef SecWordBlock SecAlignedWordBlock;
#endif

View File

@ -59,9 +59,11 @@ typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize
if (preserve)
{
typename A::pointer newPointer = a.allocate(newSize, NULL);
A b;
typename A::pointer newPointer = b.allocate(newSize, NULL);
memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
a.deallocate(p, oldSize);
std::swap(a, b);
return newPointer;
}
else
@ -181,7 +183,11 @@ public:
return p;
}
return StandardReallocate(*this, p, oldSize, newSize, preserve);
pointer newPointer = allocate(newSize, NULL);
if (preserve)
memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
deallocate(p, oldSize);
return newPointer;
}
size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);}