00001 #ifndef CRYPTOPP_CPU_H
00002 #define CRYPTOPP_CPU_H
00003
00004 #include "config.h"
00005
00006 #ifdef CRYPTOPP_MSVC6PP_OR_LATER
00007 #include <emmintrin.h>
00008 #endif
00009
00010 NAMESPACE_BEGIN(CryptoPP)
00011
00012 #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || (_MSC_VER >= 1400 && CRYPTOPP_BOOL_X64)
00013
00014 #define CRYPTOPP_CPUID_AVAILABLE
00015
00016
00017 extern CRYPTOPP_DLL bool g_x86DetectionDone;
00018 extern CRYPTOPP_DLL bool g_hasSSE2;
00019 extern CRYPTOPP_DLL bool g_hasMMX;
00020 extern CRYPTOPP_DLL bool g_hasSSSE3;
00021 extern CRYPTOPP_DLL bool g_isP4;
00022 extern CRYPTOPP_DLL word32 g_cacheLineSize;
00023 CRYPTOPP_DLL void DetectX86Features();
00024
00025 CRYPTOPP_DLL bool CpuId(word32 input, word32 *output);
00026
00027 #if CRYPTOPP_BOOL_X64
00028 inline bool HasSSE2() {return true;}
00029 inline bool HasMMX() {return true;}
00030 #else
00031
00032 inline bool HasSSE2()
00033 {
00034 if (!g_x86DetectionDone)
00035 DetectX86Features();
00036 return g_hasSSE2;
00037 }
00038
00039 inline bool HasMMX()
00040 {
00041 if (!g_x86DetectionDone)
00042 DetectX86Features();
00043 return g_hasMMX;
00044 }
00045
00046 #endif
00047
00048 inline bool HasSSSE3()
00049 {
00050 if (!g_x86DetectionDone)
00051 DetectX86Features();
00052 return g_hasSSSE3;
00053 }
00054
00055 inline bool IsP4()
00056 {
00057 if (!g_x86DetectionDone)
00058 DetectX86Features();
00059 return g_isP4;
00060 }
00061
00062 inline int GetCacheLineSize()
00063 {
00064 if (!g_x86DetectionDone)
00065 DetectX86Features();
00066 return g_cacheLineSize;
00067 }
00068
00069 #else
00070
00071 inline int GetCacheLineSize()
00072 {
00073 return CRYPTOPP_L1_CACHE_LINE_SIZE;
00074 }
00075
00076 inline bool HasSSSE3() {return false;}
00077 inline bool IsP4() {return false;}
00078
00079
00080 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_X64
00081 inline bool HasSSE2() {return true;}
00082 inline bool HasMMX() {return true;}
00083 #else
00084 inline bool HasSSE2() {return false;}
00085 inline bool HasMMX() {return false;}
00086 #endif
00087
00088 #endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE || _MSC_VER >= 1400
00089
00090 #if defined(__GNUC__)
00091
00092 #define GNU_AS1(x) #x ";"
00093 #define GNU_AS2(x, y) #x ", " #y ";"
00094 #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";"
00095 #define GNU_ASL(x) "\n" #x ":"
00096 #define GNU_ASJ(x, y, z) #x " " #y #z ";"
00097 #define AS1(x) GNU_AS1(x)
00098 #define AS2(x, y) GNU_AS2(x, y)
00099 #define AS3(x, y, z) GNU_AS3(x, y, z)
00100 #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
00101 #define ASL(x) GNU_ASL(x)
00102 #define ASJ(x, y, z) GNU_ASJ(x, y, z)
00103 #define ASC(x, y) #x " " #y ";"
00104 #define CRYPTOPP_NAKED
00105 #else
00106 #define AS1(x) __asm {x}
00107 #define AS2(x, y) __asm {x, y}
00108 #define AS3(x, y, z) __asm {x, y, z}
00109 #define ASS(x, y, a, b, c, d) __asm {x, y, _MM_SHUFFLE(a, b, c, d)}
00110 #define ASL(x) __asm {label##x:}
00111 #define ASJ(x, y, z) __asm {x label##y}
00112 #define ASC(x, y) __asm {x label##y}
00113 #define CRYPTOPP_NAKED __declspec(naked)
00114 #endif
00115
00116
00117 #define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
00118
00119 #if CRYPTOPP_BOOL_X86
00120 #define WORD_SZ 4
00121 #define WORD_REG(x) e##x
00122 #define WORD_PTR DWORD PTR
00123 #define AS_PUSH(x) AS1(push e##x)
00124 #define AS_POP(x) AS1(pop e##x)
00125 #elif CRYPTOPP_BOOL_X64
00126 #define WORD_SZ 8
00127 #define WORD_REG(x) r##x
00128 #define WORD_PTR QWORD PTR
00129 #define AS_PUSH(x) AS1(pushq r##x)
00130 #define AS_POP(x) AS1(popq r##x)
00131 #endif
00132
00133 NAMESPACE_END
00134
00135 #endif