[Gmp-commit] /var/hg/gmp: 2 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Sun Dec 13 23:12:55 UTC 2015
details: /var/hg/gmp/rev/bbb7dd6b920e
changeset: 17001:bbb7dd6b920e
user: Torbjorn Granlund <torbjorng at google.com>
date: Mon Dec 14 00:12:46 2015 +0100
description:
Handle more BMI2 crippled CPUs.
details: /var/hg/gmp/rev/f2ffa3868121
changeset: 17002:f2ffa3868121
user: Torbjorn Granlund <torbjorng at google.com>
date: Mon Dec 14 00:12:52 2015 +0100
description:
ChangeLog
diffstat:
ChangeLog | 6 +++++
mpn/x86_64/fat/fat.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 58 insertions(+), 2 deletions(-)
diffs (98 lines):
diff -r 6e002fd72c22 -r f2ffa3868121 ChangeLog
--- a/ChangeLog Sun Dec 13 23:53:44 2015 +0100
+++ b/ChangeLog Mon Dec 14 00:12:52 2015 +0100
@@ -1,3 +1,9 @@
+2015-12-14 Torbjörn Granlund <torbjorng at google.com>
+
+ * mpn/x86_64/fat/fat.c (gmp_workaround_skylake_cpuid_bug):
+ New function.
+ (__gmpn_cpuvec_init): Handle more BMI2 crippled CPUs.
+
2015-12-13 Torbjörn Granlund <torbjorng at google.com>
* config.sub: Fix spelling of kabylake.
diff -r 6e002fd72c22 -r f2ffa3868121 mpn/x86_64/fat/fat.c
--- a/mpn/x86_64/fat/fat.c Sun Dec 13 23:53:44 2015 +0100
+++ b/mpn/x86_64/fat/fat.c Mon Dec 14 00:12:52 2015 +0100
@@ -206,6 +206,49 @@
asm routines only operate correctly up to their own defined threshold,
not an arbitrary value. */
+static int
+gmp_workaround_skylake_cpuid_bug ()
+{
+ char feature_string[49];
+ char processor_name_string[49];
+ static const char *bad_cpus[] = {" G44", " G45", " G39" /* , "6600" */ };
+ int i;
+
+ /* Example strings: */
+ /* "Intel(R) Pentium(R) CPU G4400 @ 3.30GHz" */
+ /* "Intel(R) Core(TM) i5-6600K CPU @ 3.50GHz" */
+ /* ^ ^ ^ */
+ /* 0x80000002 0x80000003 0x80000004 */
+ /* We match out just the 0x80000003 part here. */
+
+ /* In their infinitive wisdom, Intel decided to use one register order for
+ the vendor string, and another for the processor name string. We shuffle
+ things about here, rather than write a new variant of our assembly cpuid.
+ */
+
+ unsigned int eax, ebx, ecx, edx;
+ eax = __gmpn_cpuid (feature_string, 0x80000003);
+ ebx = ((unsigned int *)feature_string)[0];
+ edx = ((unsigned int *)feature_string)[1];
+ ecx = ((unsigned int *)feature_string)[2];
+
+ ((unsigned int *) (processor_name_string))[0] = eax;
+ ((unsigned int *) (processor_name_string))[1] = ebx;
+ ((unsigned int *) (processor_name_string))[2] = ecx;
+ ((unsigned int *) (processor_name_string))[3] = edx;
+
+ processor_name_string[16] = 0;
+
+ for (i = 0; i < sizeof (bad_cpus) / sizeof (char *); i++)
+ {
+ if (strstr (processor_name_string, bad_cpus[i]) != 0)
+ return 1;
+ }
+ return 0;
+}
+
+enum {BMI2_BIT = 8};
+
void
__gmpn_cpuvec_init (void)
{
@@ -311,8 +354,9 @@
/* Some Haswells lack BMI2. Let them appear as Sandybridges for
now. */
__gmpn_cpuid (dummy_string, 7);
- if ((dummy_string[0 + 8 / 8] & (1 << (8 % 8))) != 0)
- CPUVEC_SETUP_coreihwl;
+ if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
+ break;
+ CPUVEC_SETUP_coreihwl;
break;
case 0x3d: /* Broadwell */
case 0x47: /* Broadwell */
@@ -321,6 +365,8 @@
CPUVEC_SETUP_core2;
CPUVEC_SETUP_coreinhm;
CPUVEC_SETUP_coreisbr;
+ if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
+ break;
CPUVEC_SETUP_coreihwl;
CPUVEC_SETUP_coreibwl;
break;
@@ -332,6 +378,10 @@
CPUVEC_SETUP_core2;
CPUVEC_SETUP_coreinhm;
CPUVEC_SETUP_coreisbr;
+ if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
+ break;
+ if (gmp_workaround_skylake_cpuid_bug ())
+ break;
CPUVEC_SETUP_coreihwl;
CPUVEC_SETUP_coreibwl;
CPUVEC_SETUP_skylake;
More information about the gmp-commit
mailing list