Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) Facebook, Inc.
0003  * All rights reserved.
0004  *
0005  * This source code is licensed under both the BSD-style license (found in the
0006  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
0007  * in the COPYING file in the root directory of this source tree).
0008  * You may select, at your option, one of the above-listed licenses.
0009  */
0010 
0011 #ifndef ZSTD_COMMON_CPU_H
0012 #define ZSTD_COMMON_CPU_H
0013 
0014 /*
0015  * Implementation taken from folly/CpuId.h
0016  * https://github.com/facebook/folly/blob/master/folly/CpuId.h
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     /* The following block like the normal cpuid branch below, but gcc
0036      * reserves ebx for use of its pic register so we must specially
0037      * handle the save and restore to avoid clobbering the register
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 /* cpuid(1): Processor Info and Feature Bits. */
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 /* cpuid(7): Extended Features. */
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 /* ZSTD_COMMON_CPU_H */