diff options
Diffstat (limited to 'src/hwf-x86.c')
-rw-r--r-- | src/hwf-x86.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/hwf-x86.c b/src/hwf-x86.c index 399952c4..fbd63315 100644 --- a/src/hwf-x86.c +++ b/src/hwf-x86.c @@ -174,6 +174,7 @@ detect_x86_gnuc (void) unsigned int features; unsigned int os_supports_avx_avx2_registers = 0; unsigned int max_cpuid_level; + unsigned int fms, family, model; unsigned int result = 0; (void)os_supports_avx_avx2_registers; @@ -236,8 +237,37 @@ detect_x86_gnuc (void) /* Detect Intel features, that might also be supported by other vendors. */ - /* Get CPU info and Intel feature flags (ECX). */ - get_cpuid(1, NULL, NULL, &features, NULL); + /* Get CPU family/model/stepping (EAX) and Intel feature flags (ECX). */ + get_cpuid(1, &fms, NULL, &features, NULL); + + family = ((fms & 0xf00) >> 8) + ((fms & 0xff00000) >> 20); + model = ((fms & 0xf0) >> 4) + ((fms & 0xf0000) >> 12); + + if ((result & HWF_INTEL_CPU) && family == 6) + { + /* These Intel Core processor models have SHLD/SHRD instruction that + * can do integer rotation faster actual ROL/ROR instructions. */ + switch (model) + { + case 0x2A: + case 0x2D: + case 0x3A: + case 0x3C: + case 0x3F: + case 0x45: + case 0x46: + case 0x3D: + case 0x4F: + case 0x56: + case 0x47: + case 0x4E: + case 0x5E: + case 0x55: + case 0x66: + result |= HWF_INTEL_FAST_SHLD; + break; + } + } #ifdef ENABLE_PCLMUL_SUPPORT /* Test bit 1 for PCLMUL. */ |