0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef ZSTD_COMMON_CPU_H
0012 #define ZSTD_COMMON_CPU_H
0013
0014
0015
0016
0017
0018
0019 #include "mem.h"
0020
0021
0022 typedef struct {
0023 U32 f1c;
0024 U32 f1d;
0025 U32 f7b;
0026 U32 f7c;
0027 } ZSTD_cpuid_t;
0028
0029 MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
0030 U32 f1c = 0;
0031 U32 f1d = 0;
0032 U32 f7b = 0;
0033 U32 f7c = 0;
0034 #if defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
0035
0036
0037
0038
0039 U32 n;
0040 __asm__(
0041 "pushl %%ebx\n\t"
0042 "cpuid\n\t"
0043 "popl %%ebx\n\t"
0044 : "=a"(n)
0045 : "a"(0)
0046 : "ecx", "edx");
0047 if (n >= 1) {
0048 U32 f1a;
0049 __asm__(
0050 "pushl %%ebx\n\t"
0051 "cpuid\n\t"
0052 "popl %%ebx\n\t"
0053 : "=a"(f1a), "=c"(f1c), "=d"(f1d)
0054 : "a"(1));
0055 }
0056 if (n >= 7) {
0057 __asm__(
0058 "pushl %%ebx\n\t"
0059 "cpuid\n\t"
0060 "movl %%ebx, %%eax\n\t"
0061 "popl %%ebx"
0062 : "=a"(f7b), "=c"(f7c)
0063 : "a"(7), "c"(0)
0064 : "edx");
0065 }
0066 #elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
0067 U32 n;
0068 __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
0069 if (n >= 1) {
0070 U32 f1a;
0071 __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
0072 }
0073 if (n >= 7) {
0074 U32 f7a;
0075 __asm__("cpuid"
0076 : "=a"(f7a), "=b"(f7b), "=c"(f7c)
0077 : "a"(7), "c"(0)
0078 : "edx");
0079 }
0080 #endif
0081 {
0082 ZSTD_cpuid_t cpuid;
0083 cpuid.f1c = f1c;
0084 cpuid.f1d = f1d;
0085 cpuid.f7b = f7b;
0086 cpuid.f7c = f7c;
0087 return cpuid;
0088 }
0089 }
0090
0091 #define X(name, r, bit) \
0092 MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
0093 return ((cpuid.r) & (1U << bit)) != 0; \
0094 }
0095
0096
0097 #define C(name, bit) X(name, f1c, bit)
0098 C(sse3, 0)
0099 C(pclmuldq, 1)
0100 C(dtes64, 2)
0101 C(monitor, 3)
0102 C(dscpl, 4)
0103 C(vmx, 5)
0104 C(smx, 6)
0105 C(eist, 7)
0106 C(tm2, 8)
0107 C(ssse3, 9)
0108 C(cnxtid, 10)
0109 C(fma, 12)
0110 C(cx16, 13)
0111 C(xtpr, 14)
0112 C(pdcm, 15)
0113 C(pcid, 17)
0114 C(dca, 18)
0115 C(sse41, 19)
0116 C(sse42, 20)
0117 C(x2apic, 21)
0118 C(movbe, 22)
0119 C(popcnt, 23)
0120 C(tscdeadline, 24)
0121 C(aes, 25)
0122 C(xsave, 26)
0123 C(osxsave, 27)
0124 C(avx, 28)
0125 C(f16c, 29)
0126 C(rdrand, 30)
0127 #undef C
0128 #define D(name, bit) X(name, f1d, bit)
0129 D(fpu, 0)
0130 D(vme, 1)
0131 D(de, 2)
0132 D(pse, 3)
0133 D(tsc, 4)
0134 D(msr, 5)
0135 D(pae, 6)
0136 D(mce, 7)
0137 D(cx8, 8)
0138 D(apic, 9)
0139 D(sep, 11)
0140 D(mtrr, 12)
0141 D(pge, 13)
0142 D(mca, 14)
0143 D(cmov, 15)
0144 D(pat, 16)
0145 D(pse36, 17)
0146 D(psn, 18)
0147 D(clfsh, 19)
0148 D(ds, 21)
0149 D(acpi, 22)
0150 D(mmx, 23)
0151 D(fxsr, 24)
0152 D(sse, 25)
0153 D(sse2, 26)
0154 D(ss, 27)
0155 D(htt, 28)
0156 D(tm, 29)
0157 D(pbe, 31)
0158 #undef D
0159
0160
0161 #define B(name, bit) X(name, f7b, bit)
0162 B(bmi1, 3)
0163 B(hle, 4)
0164 B(avx2, 5)
0165 B(smep, 7)
0166 B(bmi2, 8)
0167 B(erms, 9)
0168 B(invpcid, 10)
0169 B(rtm, 11)
0170 B(mpx, 14)
0171 B(avx512f, 16)
0172 B(avx512dq, 17)
0173 B(rdseed, 18)
0174 B(adx, 19)
0175 B(smap, 20)
0176 B(avx512ifma, 21)
0177 B(pcommit, 22)
0178 B(clflushopt, 23)
0179 B(clwb, 24)
0180 B(avx512pf, 26)
0181 B(avx512er, 27)
0182 B(avx512cd, 28)
0183 B(sha, 29)
0184 B(avx512bw, 30)
0185 B(avx512vl, 31)
0186 #undef B
0187 #define C(name, bit) X(name, f7c, bit)
0188 C(prefetchwt1, 0)
0189 C(avx512vbmi, 1)
0190 #undef C
0191
0192 #undef X
0193
0194 #endif