-rw-r--r-- 2655 lib25519-20221222/cpuid/amd64.c raw
#include <stdio.h> #define CPUID(func,leaf,a,b,c,d) \ __asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(func),"c"(leaf):) __attribute__((visibility("default"))) void lib25519_cpuid(unsigned int *result,long long resultlen) { unsigned int a,b,c,d; unsigned int cpuidmax,extendedcpuidmax; int havexgetbv = 0; CPUID(0,0,a,b,c,d); cpuidmax = a; if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; CPUID(0x80000000,0,a,b,c,d); extendedcpuidmax = a; a = b = c = d = 0; if (extendedcpuidmax >= 0x80000002) CPUID(0x80000002,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; if (extendedcpuidmax >= 0x80000003) CPUID(0x80000003,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; if (extendedcpuidmax >= 0x80000004) CPUID(0x80000004,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; if (cpuidmax >= 1) CPUID(1,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } /* 27=osxsave; 28=avx */ if (((1<<27)|(1<<28)) == (((1<<27)|(1<<28)) & c)) havexgetbv = 1; a = b = c = d = 0; if (cpuidmax >= 7) CPUID(7,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; if (extendedcpuidmax >= 0x80000001) CPUID(0x80000001,0,a,b,c,d); if (resultlen > 0) { *result++ = a; --resultlen; } if (resultlen > 0) { *result++ = b; --resultlen; } if (resultlen > 0) { *result++ = c; --resultlen; } if (resultlen > 0) { *result++ = d; --resultlen; } a = b = c = d = 0; if (havexgetbv) asm(".byte 15;.byte 1;.byte 208":"=a"(a),"=d"(d):"c"(0)); if (resultlen > 0) { *result++ = a; --resultlen; } while (resultlen > 0) { *result++ = 0; --resultlen; } }