• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

cpu.h

00001 #ifndef CRYPTOPP_CPU_H
00002 #define CRYPTOPP_CPU_H
00003 
00004 #ifdef CRYPTOPP_GENERATE_X64_MASM
00005 
00006 #define CRYPTOPP_X86_ASM_AVAILABLE
00007 #define CRYPTOPP_BOOL_X64 1
00008 #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1
00009 #define NAMESPACE_END
00010 
00011 #else
00012 
00013 #include "config.h"
00014 
00015 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
00016 #include <emmintrin.h>
00017 #endif
00018 
00019 #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
00020 #if !defined(__GNUC__) || defined(__SSSE3__) || defined(__INTEL_COMPILER)
00021 #include <tmmintrin.h>
00022 #else
00023 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00024 _mm_shuffle_epi8 (__m128i a, __m128i b)
00025 {
00026         asm ("pshufb %1, %0" : "+x"(a) : "xm"(b));
00027         return a;
00028 }
00029 #endif
00030 #if !defined(__GNUC__) || defined(__SSE4_1__) || defined(__INTEL_COMPILER)
00031 #include <smmintrin.h>
00032 #else
00033 __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00034 _mm_extract_epi32 (__m128i a, const int i)
00035 {
00036         int r;
00037         asm ("pextrd %2, %1, %0" : "=rm"(r) : "x"(a), "i"(i));
00038         return r;
00039 }
00040 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00041 _mm_insert_epi32 (__m128i a, int b, const int i)
00042 {
00043         asm ("pinsrd %2, %1, %0" : "+x"(a) : "rm"(b), "i"(i));
00044         return a;
00045 }
00046 #endif
00047 #if !defined(__GNUC__) || (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER)
00048 #include <wmmintrin.h>
00049 #else
00050 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00051 _mm_clmulepi64_si128 (__m128i a, __m128i b, const int i)
00052 {
00053         asm ("pclmulqdq %2, %1, %0" : "+x"(a) : "xm"(b), "i"(i));
00054         return a;
00055 }
00056 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00057 _mm_aeskeygenassist_si128 (__m128i a, const int i)
00058 {
00059         __m128i r;
00060         asm ("aeskeygenassist %2, %1, %0" : "=x"(r) : "xm"(a), "i"(i));
00061         return r;
00062 }
00063 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00064 _mm_aesimc_si128 (__m128i a)
00065 {
00066         __m128i r;
00067         asm ("aesimc %1, %0" : "=x"(r) : "xm"(a));
00068         return r;
00069 }
00070 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00071 _mm_aesenc_si128 (__m128i a, __m128i b)
00072 {
00073         asm ("aesenc %1, %0" : "+x"(a) : "xm"(b));
00074         return a;
00075 }
00076 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00077 _mm_aesenclast_si128 (__m128i a, __m128i b)
00078 {
00079         asm ("aesenclast %1, %0" : "+x"(a) : "xm"(b));
00080         return a;
00081 }
00082 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00083 _mm_aesdec_si128 (__m128i a, __m128i b)
00084 {
00085         asm ("aesdec %1, %0" : "+x"(a) : "xm"(b));
00086         return a;
00087 }
00088 __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
00089 _mm_aesdeclast_si128 (__m128i a, __m128i b)
00090 {
00091         asm ("aesdeclast %1, %0" : "+x"(a) : "xm"(b));
00092         return a;
00093 }
00094 #endif
00095 #endif
00096 
00097 NAMESPACE_BEGIN(CryptoPP)
00098 
00099 #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64
00100 
00101 #define CRYPTOPP_CPUID_AVAILABLE
00102 
00103 // these should not be used directly
00104 extern CRYPTOPP_DLL bool g_x86DetectionDone;
00105 extern CRYPTOPP_DLL bool g_hasSSSE3;
00106 extern CRYPTOPP_DLL bool g_hasAESNI;
00107 extern CRYPTOPP_DLL bool g_hasCLMUL;
00108 extern CRYPTOPP_DLL bool g_isP4;
00109 extern CRYPTOPP_DLL word32 g_cacheLineSize;
00110 CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features();
00111 CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 *output);
00112 
00113 #if CRYPTOPP_BOOL_X64
00114 inline bool HasSSE2()   {return true;}
00115 inline bool HasISSE()   {return true;}
00116 inline bool HasMMX()    {return true;}
00117 #else
00118 
00119 extern CRYPTOPP_DLL bool g_hasSSE2;
00120 extern CRYPTOPP_DLL bool g_hasISSE;
00121 extern CRYPTOPP_DLL bool g_hasMMX;
00122 
00123 inline bool HasSSE2()
00124 {
00125         if (!g_x86DetectionDone)
00126                 DetectX86Features();
00127         return g_hasSSE2;
00128 }
00129 
00130 inline bool HasISSE()
00131 {
00132         if (!g_x86DetectionDone)
00133                 DetectX86Features();
00134         return g_hasISSE;
00135 }
00136 
00137 inline bool HasMMX()
00138 {
00139         if (!g_x86DetectionDone)
00140                 DetectX86Features();
00141         return g_hasMMX;
00142 }
00143 
00144 #endif
00145 
00146 inline bool HasSSSE3()
00147 {
00148         if (!g_x86DetectionDone)
00149                 DetectX86Features();
00150         return g_hasSSSE3;
00151 }
00152 
00153 inline bool HasAESNI()
00154 {
00155         if (!g_x86DetectionDone)
00156                 DetectX86Features();
00157         return g_hasAESNI;
00158 }
00159 
00160 inline bool HasCLMUL()
00161 {
00162         if (!g_x86DetectionDone)
00163                 DetectX86Features();
00164         return g_hasCLMUL;
00165 }
00166 
00167 inline bool IsP4()
00168 {
00169         if (!g_x86DetectionDone)
00170                 DetectX86Features();
00171         return g_isP4;
00172 }
00173 
00174 inline int GetCacheLineSize()
00175 {
00176         if (!g_x86DetectionDone)
00177                 DetectX86Features();
00178         return g_cacheLineSize;
00179 }
00180 
00181 #else
00182 
00183 inline int GetCacheLineSize()
00184 {
00185         return CRYPTOPP_L1_CACHE_LINE_SIZE;
00186 }
00187 
00188 #endif
00189 
00190 #endif
00191 
00192 #ifdef CRYPTOPP_GENERATE_X64_MASM
00193         #define AS1(x) x*newline*
00194         #define AS2(x, y) x, y*newline*
00195         #define AS3(x, y, z) x, y, z*newline*
00196         #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline*
00197         #define ASL(x) label##x:*newline*
00198         #define ASJ(x, y, z) x label##y*newline*
00199         #define ASC(x, y) x label##y*newline*
00200         #define AS_HEX(y) 0##y##h
00201 #elif defined(_MSC_VER) || defined(__BORLANDC__)
00202         #define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
00203         #define AS1(x) __asm {x}
00204         #define AS2(x, y) __asm {x, y}
00205         #define AS3(x, y, z) __asm {x, y, z}
00206         #define ASS(x, y, a, b, c, d) __asm {x, y, (a)*64+(b)*16+(c)*4+(d)}
00207         #define ASL(x) __asm {label##x:}
00208         #define ASJ(x, y, z) __asm {x label##y}
00209         #define ASC(x, y) __asm {x label##y}
00210         #define CRYPTOPP_NAKED __declspec(naked)
00211         #define AS_HEX(y) 0x##y
00212 #else
00213         #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY
00214         // define these in two steps to allow arguments to be expanded
00215         #define GNU_AS1(x) #x ";"
00216         #define GNU_AS2(x, y) #x ", " #y ";"
00217         #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";"
00218         #define GNU_ASL(x) "\n" #x ":"
00219         #define GNU_ASJ(x, y, z) #x " " #y #z ";"
00220         #define AS1(x) GNU_AS1(x)
00221         #define AS2(x, y) GNU_AS2(x, y)
00222         #define AS3(x, y, z) GNU_AS3(x, y, z)
00223         #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";"
00224         #define ASL(x) GNU_ASL(x)
00225         #define ASJ(x, y, z) GNU_ASJ(x, y, z)
00226         #define ASC(x, y) #x " " #y ";"
00227         #define CRYPTOPP_NAKED
00228         #define AS_HEX(y) 0x##y
00229 #endif
00230 
00231 #define IF0(y)
00232 #define IF1(y) y
00233 
00234 #ifdef CRYPTOPP_GENERATE_X64_MASM
00235 #define ASM_MOD(x, y) ((x) MOD (y))
00236 #define XMMWORD_PTR XMMWORD PTR
00237 #else
00238 // GNU assembler doesn't seem to have mod operator
00239 #define ASM_MOD(x, y) ((x)-((x)/(y))*(y))
00240 // GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM
00241 #define XMMWORD_PTR
00242 #endif
00243 
00244 #if CRYPTOPP_BOOL_X86
00245         #define AS_REG_1 ecx
00246         #define AS_REG_2 edx
00247         #define AS_REG_3 esi
00248         #define AS_REG_4 edi
00249         #define AS_REG_5 eax
00250         #define AS_REG_6 ebx
00251         #define AS_REG_7 ebp
00252         #define AS_REG_1d ecx
00253         #define AS_REG_2d edx
00254         #define AS_REG_3d esi
00255         #define AS_REG_4d edi
00256         #define AS_REG_5d eax
00257         #define AS_REG_6d ebx
00258         #define AS_REG_7d ebp
00259         #define WORD_SZ 4
00260         #define WORD_REG(x)     e##x
00261         #define WORD_PTR DWORD PTR
00262         #define AS_PUSH_IF86(x) AS1(push e##x)
00263         #define AS_POP_IF86(x) AS1(pop e##x)
00264         #define AS_JCXZ jecxz
00265 #elif CRYPTOPP_BOOL_X64
00266         #ifdef CRYPTOPP_GENERATE_X64_MASM
00267                 #define AS_REG_1 rcx
00268                 #define AS_REG_2 rdx
00269                 #define AS_REG_3 r8
00270                 #define AS_REG_4 r9
00271                 #define AS_REG_5 rax
00272                 #define AS_REG_6 r10
00273                 #define AS_REG_7 r11
00274                 #define AS_REG_1d ecx
00275                 #define AS_REG_2d edx
00276                 #define AS_REG_3d r8d
00277                 #define AS_REG_4d r9d
00278                 #define AS_REG_5d eax
00279                 #define AS_REG_6d r10d
00280                 #define AS_REG_7d r11d
00281         #else
00282                 #define AS_REG_1 rdi
00283                 #define AS_REG_2 rsi
00284                 #define AS_REG_3 rdx
00285                 #define AS_REG_4 rcx
00286                 #define AS_REG_5 r8
00287                 #define AS_REG_6 r9
00288                 #define AS_REG_7 r10
00289                 #define AS_REG_1d edi
00290                 #define AS_REG_2d esi
00291                 #define AS_REG_3d edx
00292                 #define AS_REG_4d ecx
00293                 #define AS_REG_5d r8d
00294                 #define AS_REG_6d r9d
00295                 #define AS_REG_7d r10d
00296         #endif
00297         #define WORD_SZ 8
00298         #define WORD_REG(x)     r##x
00299         #define WORD_PTR QWORD PTR
00300         #define AS_PUSH_IF86(x)
00301         #define AS_POP_IF86(x)
00302         #define AS_JCXZ jrcxz
00303 #endif
00304 
00305 // helper macro for stream cipher output
00306 #define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\
00307         AS2(    test    inputPtr, inputPtr)\
00308         ASC(    jz,             labelPrefix##3)\
00309         AS2(    test    inputPtr, 15)\
00310         ASC(    jnz,    labelPrefix##7)\
00311         AS2(    pxor    xmm##x0, [inputPtr+p0*16])\
00312         AS2(    pxor    xmm##x1, [inputPtr+p1*16])\
00313         AS2(    pxor    xmm##x2, [inputPtr+p2*16])\
00314         AS2(    pxor    xmm##x3, [inputPtr+p3*16])\
00315         AS2(    add             inputPtr, increment*16)\
00316         ASC(    jmp,    labelPrefix##3)\
00317         ASL(labelPrefix##7)\
00318         AS2(    movdqu  xmm##t, [inputPtr+p0*16])\
00319         AS2(    pxor    xmm##x0, xmm##t)\
00320         AS2(    movdqu  xmm##t, [inputPtr+p1*16])\
00321         AS2(    pxor    xmm##x1, xmm##t)\
00322         AS2(    movdqu  xmm##t, [inputPtr+p2*16])\
00323         AS2(    pxor    xmm##x2, xmm##t)\
00324         AS2(    movdqu  xmm##t, [inputPtr+p3*16])\
00325         AS2(    pxor    xmm##x3, xmm##t)\
00326         AS2(    add             inputPtr, increment*16)\
00327         ASL(labelPrefix##3)\
00328         AS2(    test    outputPtr, 15)\
00329         ASC(    jnz,    labelPrefix##8)\
00330         AS2(    movdqa  [outputPtr+p0*16], xmm##x0)\
00331         AS2(    movdqa  [outputPtr+p1*16], xmm##x1)\
00332         AS2(    movdqa  [outputPtr+p2*16], xmm##x2)\
00333         AS2(    movdqa  [outputPtr+p3*16], xmm##x3)\
00334         ASC(    jmp,    labelPrefix##9)\
00335         ASL(labelPrefix##8)\
00336         AS2(    movdqu  [outputPtr+p0*16], xmm##x0)\
00337         AS2(    movdqu  [outputPtr+p1*16], xmm##x1)\
00338         AS2(    movdqu  [outputPtr+p2*16], xmm##x2)\
00339         AS2(    movdqu  [outputPtr+p3*16], xmm##x3)\
00340         ASL(labelPrefix##9)\
00341         AS2(    add             outputPtr, increment*16)
00342 
00343 NAMESPACE_END
00344 
00345 #endif

Generated on Mon Aug 9 2010 15:56:33 for Crypto++ by  doxygen 1.7.1