From fa25129ac981ceed9569496c02b83771b394fa40 Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 13 Feb 2009 12:18:26 +0000 Subject: [PATCH] port to Sun Studio 12's 64-bit C++ Compiler 5.9 Patch 124864-09 2008/12/16 --- GNUmakefile | 3 ++- algparam.cpp | 12 +++++++++-- algparam.h | 58 +++++++++++++++++++++++++++------------------------- config.h | 17 ++++++++------- eccrypto.cpp | 5 ----- eprecomp.cpp | 5 ----- esign.cpp | 2 +- integer.cpp | 28 ++++++++++++++----------- luc.cpp | 2 +- nbtheory.cpp | 3 +-- nbtheory.h | 3 +-- rabin.cpp | 2 +- rsa.cpp | 2 +- rw.cpp | 2 +- 14 files changed, 73 insertions(+), 71 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index ed6b309a..8d022449 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,4 +1,5 @@ CXXFLAGS = -DNDEBUG -g -O2 +#CXXFLAGS = -g # -fPIC is supported. Please report any breakage of -fPIC as a bug. # CXXFLAGS += -fPIC # the following options reduce code size, but breaks link or makes link very slow on some systems @@ -79,7 +80,7 @@ endif ifeq ($(UNAME),SunOS) LDLIBS += -lnsl -lsocket ifeq ($(CXX),CC) # override flags for CC (Solaris native C++ compiler) -CXXFLAGS = -DNDEBUG -O -g -native +CXXFLAGS = -DNDEBUG -O -g0 -native -template=no%extdef -m$(shell isainfo -b) LDFLAGS = ifeq ($(ISX86),1) # SSE2 intrinsics should work in Sun Studio 12, but we're not using SSE2 intrinsics anymore diff --git a/algparam.cpp b/algparam.cpp index 3c556408..c9da677d 100644 --- a/algparam.cpp +++ b/algparam.cpp @@ -23,7 +23,8 @@ bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_inf if (strcmp(name, "ValueNames") == 0) { ThrowIfTypeMismatch(name, typeid(std::string), valueType); - GetParent().GetVoidValue(name, valueType, pValue); + if (m_next.get()) + m_next->GetVoidValue(name, valueType, pValue); (*reinterpret_cast(pValue) += m_name) += ";"; return true; } @@ -33,8 +34,15 @@ bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_inf m_used = true; return true; } + else if (m_next.get()) + return m_next->GetVoidValue(name, valueType, pValue); else - return GetParent().GetVoidValue(name, valueType, pValue); + return false; +} + +bool AlgorithmParameters::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return m_ptr->GetVoidValue(name, valueType, pValue); } NAMESPACE_END diff --git a/algparam.h b/algparam.h index d0903332..36cc16f5 100644 --- a/algparam.h +++ b/algparam.h @@ -276,21 +276,23 @@ public: } bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; - + protected: + friend class AlgorithmParameters; + virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0; - virtual const NameValuePairs & GetParent() const =0; const char *m_name; bool m_throwIfNotUsed; mutable bool m_used; + member_ptr m_next; }; template -class AlgorithmParametersBase2 : public AlgorithmParametersBase +class AlgorithmParametersTemplate : public AlgorithmParametersBase { public: - AlgorithmParametersBase2(const char *name, const T &value, bool throwIfNotUsed) : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) {} + AlgorithmParametersTemplate(const char *name, const T &value, bool throwIfNotUsed) : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) {} void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const { @@ -306,35 +308,35 @@ protected: T m_value; }; -template -class AlgorithmParameters : public AlgorithmParametersBase2 +class AlgorithmParameters : public NameValuePairs { public: - AlgorithmParameters(const PARENT &parent, const char *name, const T &value, bool throwIfNotUsed) - : AlgorithmParametersBase2(name, value, throwIfNotUsed), m_parent(parent) - {} - - AlgorithmParameters(const AlgorithmParameters ©) - : AlgorithmParametersBase2(copy), m_parent(copy.m_parent) + AlgorithmParameters(AlgorithmParameters &x) : m_ptr(x.m_ptr.release()) {} + + AlgorithmParameters(AlgorithmParametersBase *p) : m_ptr(p) {} + + template + AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed) { - copy.m_used = true; + member_ptr p(new AlgorithmParametersTemplate(name, value, throwIfNotUsed)); + p->m_next.reset(m_ptr.release()); + m_ptr.reset(p.release()); + return *this; } - template - AlgorithmParameters, R> operator()(const char *name, const R &value) const + template + AlgorithmParameters & operator()(const char *name, const T &value) { - return AlgorithmParameters, R>(*this, name, value, this->m_throwIfNotUsed); + member_ptr p(new AlgorithmParametersTemplate(name, value, m_ptr->m_throwIfNotUsed)); + p->m_next.reset(m_ptr.release()); + m_ptr.reset(p.release()); + return *this; } - template - AlgorithmParameters, R> operator()(const char *name, const R &value, bool throwIfNotUsed) const - { - return AlgorithmParameters, R>(*this, name, value, throwIfNotUsed); - } - -private: - const NameValuePairs & GetParent() const {return m_parent;} - PARENT m_parent; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +protected: + member_ptr m_ptr; }; //! Create an object that implements NameValuePairs for passing parameters @@ -343,12 +345,12 @@ private: such as MSVC 7.0 and earlier. \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by repeatedly using operator() on the object returned by MakeParameters, for example: - const NameValuePairs ¶meters = MakeParameters(name1, value1)(name2, value2)(name3, value3); + AlgorithmParameters parameters = MakeParameters(name1, value1)(name2, value2)(name3, value3); */ template -AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true) +AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true) { - return AlgorithmParameters(g_nullNameValuePairs, name, value, throwIfNotUsed); + return AlgorithmParameters(new AlgorithmParametersTemplate(name, value, throwIfNotUsed)); } #define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name) diff --git a/config.h b/config.h index ae7c5358..c6ee26c5 100644 --- a/config.h +++ b/config.h @@ -104,14 +104,13 @@ NAMESPACE_BEGIN(CryptoPP) typedef unsigned short word16; typedef unsigned int word32; -#if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) - #define WORD64_AVAILABLE - typedef unsigned long long word64; - #define W64LIT(x) x##LL -#elif defined(_MSC_VER) || defined(__BORLANDC__) - #define WORD64_AVAILABLE +#define WORD64_AVAILABLE +#if defined(_MSC_VER) || defined(__BORLANDC__) typedef unsigned __int64 word64; #define W64LIT(x) x##ui64 +#else + typedef unsigned long long word64; + #define W64LIT(x) x##ULL #endif // define large word type, used for file offsets and such @@ -129,7 +128,7 @@ typedef unsigned int word32; // define hword, word, and dword. these are used for multiprecision integer arithmetic // Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx -#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) +#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__)) typedef word32 hword; typedef word64 word; #else @@ -189,7 +188,7 @@ NAMESPACE_END #ifndef CRYPTOPP_ALIGN_DATA #if defined(CRYPTOPP_MSVC6PP_OR_LATER) #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x)) - #elif defined(__GNUC__) || __SUNPRO_CC > 0x580 + #elif defined(__GNUC__) || __SUNPRO_CC > 0x590 #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) #else #define CRYPTOPP_ALIGN_DATA(x) @@ -341,7 +340,7 @@ NAMESPACE_END #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS #endif -#define CRYPTOPP_VERSION 552 +#define CRYPTOPP_VERSION 553 // ***************** determine availability of OS features ******************** diff --git a/eccrypto.cpp b/eccrypto.cpp index f0ff9eeb..b80855ef 100644 --- a/eccrypto.cpp +++ b/eccrypto.cpp @@ -2,9 +2,6 @@ #include "pch.h" -// prevent Sun's CC compiler from including this file automatically -#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) - #ifndef CRYPTOPP_IMPORTS #include "eccrypto.h" @@ -646,5 +643,3 @@ void DL_PrivateKey_EC::DEREncodePrivateKey(BufferedTransformation &bt) const NAMESPACE_END #endif - -#endif diff --git a/eprecomp.cpp b/eprecomp.cpp index ce1b07fc..a061cf6c 100644 --- a/eprecomp.cpp +++ b/eprecomp.cpp @@ -2,9 +2,6 @@ #include "pch.h" -// prevent Sun's CC compiler from including this file automatically -#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) - #ifndef CRYPTOPP_IMPORTS #include "eprecomp.h" @@ -113,5 +110,3 @@ template T NAMESPACE_END #endif - -#endif diff --git a/esign.cpp b/esign.cpp index eb9ca468..8b42c1fa 100644 --- a/esign.cpp +++ b/esign.cpp @@ -94,7 +94,7 @@ void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const N const Integer minP = Integer(204) << (modulusSize/3-8); const Integer maxP = Integer::Power2(modulusSize/3)-1; - const NameValuePairs &primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME); + AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME); if (param.GetValue("Seed", seedParam)) { diff --git a/integer.cpp b/integer.cpp index 0926a0bf..7bbc51f5 100644 --- a/integer.cpp +++ b/integer.cpp @@ -108,20 +108,26 @@ static word AtomicInverseModPower2(word A) #define LowWord(a) a##0 #define HighWord(a) a##1 #ifdef _MSC_VER - #define MultiplyWords(p, a, b) p##0 = _umul128(a, b, &p##1); + #define MultiplyWordsLoHi(p0, p1, a, b) p0 = _umul128(a, b, &p1); #ifndef __INTEL_COMPILER #define Double3Words(c, d) d##1 = __shiftleft128(d##0, d##1, 1); d##0 = __shiftleft128(c, d##0, 1); c *= 2; #endif #elif defined(__DECCXX) - #define MultiplyWords(p, a, b) p##0 = a*b; p##1 = asm("umulh %a0, %a1, %v0", a, b); + #define MultiplyWordsLoHi(p0, p1, a, b) p0 = a*b; p1 = asm("umulh %a0, %a1, %v0", a, b); #elif defined(__x86_64__) - #define MultiplyWords(p, a, b) asm ("mulq %3" : "=a"(p##0), "=d"(p##1) : "a"(a), "g"(b) : "cc"); - #define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); - #define Double3Words(c, d) asm ("addq %0, %0; adcq %1, %1; adcq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc"); - #define Acc2WordsBy1(a, b) asm ("addq %2, %0; adcq $0, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b) : "cc"); - #define Acc2WordsBy2(a, b) asm ("addq %2, %0; adcq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc"); - #define Acc3WordsBy2(c, d, e) asm ("addq %5, %0; adcq %6, %1; adcq $0, %2;" : "+r"(c), "=r"(e##0), "=r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1) : "cc"); + #ifdef __SUNPRO_CC + // Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works + #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc"); + #else + #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); + #define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); + #define Double3Words(c, d) asm ("addq %0, %0; adcq %1, %1; adcq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc"); + #define Acc2WordsBy1(a, b) asm ("addq %2, %0; adcq $0, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b) : "cc"); + #define Acc2WordsBy2(a, b) asm ("addq %2, %0; adcq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc"); + #define Acc3WordsBy2(c, d, e) asm ("addq %5, %0; adcq %6, %1; adcq $0, %2;" : "+r"(c), "=r"(e##0), "=r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1) : "cc"); + #endif #endif + #define MultiplyWords(p, a, b) MultiplyWordsLoHi(p##0, p##1, a, b) #ifndef Double3Words #define Double3Words(c, d) d##1 = 2*d##1 + (d##0>>(WORD_BITS-1)); d##0 = 2*d##0 + (c>>(WORD_BITS-1)); c *= 2; #endif @@ -189,10 +195,8 @@ public: DWord r; #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE r.m_whole = (dword)a * b; - #elif defined(__x86_64__) - asm ("mulq %3" : "=a"(r.m_halfs.low), "=d"(r.m_halfs.high) : "a"(a), "g"(b) : "cc"); - #else - r.m_halfs.low = _umul128(a, b, &r.m_halfs.high); + #elif defined(MultiplyWordsLoHi) + MultiplyWordsLoHi(r.m_halfs.low, r.m_halfs.high, a, b); #endif return r; } diff --git a/luc.cpp b/luc.cpp index 85bd4623..43cd2ed2 100644 --- a/luc.cpp +++ b/luc.cpp @@ -118,7 +118,7 @@ void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const Nam throw InvalidArgument("InvertibleLUCFunction: invalid public exponent"); LUCPrimeSelector selector(m_e); - const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) ("PointerToPrimeSelector", selector.GetSelectorPointer()); m_p.GenerateRandom(rng, primeParam); m_q.GenerateRandom(rng, primeParam); diff --git a/nbtheory.cpp b/nbtheory.cpp index fdc6e8f5..77dd556e 100644 --- a/nbtheory.cpp +++ b/nbtheory.cpp @@ -262,8 +262,7 @@ static inline bool FastProbablePrimeTest(const Integer &n) return IsStrongProbablePrime(n,2); } -AlgorithmParameters, Integer>, Integer> - MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength) +AlgorithmParameters MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength) { if (productBitLength < 16) throw InvalidArgument("invalid bit length"); diff --git a/nbtheory.h b/nbtheory.h index 43e8ebda..c89de6f9 100644 --- a/nbtheory.h +++ b/nbtheory.h @@ -56,8 +56,7 @@ CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); -CRYPTOPP_DLL AlgorithmParameters, Integer>, Integer> - CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); +CRYPTOPP_DLL AlgorithmParameters CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); // ********** other number theoretic functions ************ diff --git a/rabin.cpp b/rabin.cpp index 2204ab5e..d496333b 100644 --- a/rabin.cpp +++ b/rabin.cpp @@ -84,7 +84,7 @@ void InvertibleRabinFunction::GenerateRandom(RandomNumberGenerator &rng, const N bool rFound=false, sFound=false; Integer t=2; - const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) ("EquivalentTo", 3)("Mod", 4); m_p.GenerateRandom(rng, primeParam); m_q.GenerateRandom(rng, primeParam); diff --git a/rsa.cpp b/rsa.cpp index c52673b3..8fab061f 100644 --- a/rsa.cpp +++ b/rsa.cpp @@ -115,7 +115,7 @@ void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const Nam throw InvalidArgument("InvertibleRSAFunction: invalid public exponent"); RSAPrimeSelector selector(m_e); - const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) (Name::PointerToPrimeSelector(), selector.GetSelectorPointer()); m_p.GenerateRandom(rng, primeParam); m_q.GenerateRandom(rng, primeParam); diff --git a/rw.cpp b/rw.cpp index c1306b39..cdd9f2d2 100644 --- a/rw.cpp +++ b/rw.cpp @@ -93,7 +93,7 @@ void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const Name if (modulusSize < 16) throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small"); - const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize); + AlgorithmParameters primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize); m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8))); m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8)));