|
Packit |
5c3484 |
/* x86_64 fat binary initializers.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Contributed to the GNU project by Kevin Ryde (original x86_32 code) and
|
|
Packit |
5c3484 |
Torbjorn Granlund (port to x86_64)
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
THE FUNCTIONS AND VARIABLES IN THIS FILE ARE FOR INTERNAL USE ONLY.
|
|
Packit |
5c3484 |
THEY'RE ALMOST CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR
|
|
Packit |
5c3484 |
COMPLETELY IN FUTURE GNU MP RELEASES.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
Copyright 2003, 2004, 2009, 2011-2015 Free Software Foundation, Inc.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This file is part of the GNU MP Library.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is free software; you can redistribute it and/or modify
|
|
Packit |
5c3484 |
it under the terms of either:
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU Lesser General Public License as published by the Free
|
|
Packit |
5c3484 |
Software Foundation; either version 3 of the License, or (at your
|
|
Packit |
5c3484 |
option) any later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
* the GNU General Public License as published by the Free Software
|
|
Packit |
5c3484 |
Foundation; either version 2 of the License, or (at your option) any
|
|
Packit |
5c3484 |
later version.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
or both in parallel, as here.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The GNU MP Library is distributed in the hope that it will be useful, but
|
|
Packit |
5c3484 |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit |
5c3484 |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
Packit |
5c3484 |
for more details.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
You should have received copies of the GNU General Public License and the
|
|
Packit |
5c3484 |
GNU Lesser General Public License along with the GNU MP Library. If not,
|
|
Packit |
5c3484 |
see https://www.gnu.org/licenses/. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include <stdio.h> /* for printf */
|
|
Packit |
5c3484 |
#include <stdlib.h> /* for getenv */
|
|
Packit |
5c3484 |
#include <string.h>
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#include "gmp.h"
|
|
Packit |
5c3484 |
#include "gmp-impl.h"
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Change this to "#define TRACE(x) x" for some traces. */
|
|
Packit |
5c3484 |
#define TRACE(x)
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* fat_entry.asm */
|
|
Packit |
5c3484 |
long __gmpn_cpuid (char [12], int);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#if WANT_FAKE_CPUID
|
|
Packit |
5c3484 |
/* The "name"s in the table are values for the GMP_CPU_TYPE environment
|
|
Packit |
5c3484 |
variable. Anything can be used, but for now it's the canonical cpu types
|
|
Packit |
5c3484 |
as per config.guess/config.sub. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#define __gmpn_cpuid fake_cpuid
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
#define MAKE_FMS(family, model) \
|
|
Packit |
5c3484 |
((((family) & 0xf) << 8) + (((family) & 0xff0) << 20) \
|
|
Packit |
5c3484 |
+ (((model) & 0xf) << 4) + (((model) & 0xf0) << 12))
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
static struct {
|
|
Packit |
5c3484 |
const char *name;
|
|
Packit |
5c3484 |
const char *vendor;
|
|
Packit |
5c3484 |
unsigned fms;
|
|
Packit |
5c3484 |
} fake_cpuid_table[] = {
|
|
Packit |
5c3484 |
{ "core2", "GenuineIntel", MAKE_FMS (6, 0xf) },
|
|
Packit |
5c3484 |
{ "nehalem", "GenuineIntel", MAKE_FMS (6, 0x1a) },
|
|
Packit |
5c3484 |
{ "nhm", "GenuineIntel", MAKE_FMS (6, 0x1a) },
|
|
Packit |
5c3484 |
{ "atom", "GenuineIntel", MAKE_FMS (6, 0x1c) },
|
|
Packit |
5c3484 |
{ "westmere", "GenuineIntel", MAKE_FMS (6, 0x25) },
|
|
Packit |
5c3484 |
{ "wsm", "GenuineIntel", MAKE_FMS (6, 0x25) },
|
|
Packit |
5c3484 |
{ "sandybridge","GenuineIntel", MAKE_FMS (6, 0x2a) },
|
|
Packit |
5c3484 |
{ "sbr", "GenuineIntel", MAKE_FMS (6, 0x2a) },
|
|
Packit |
5c3484 |
{ "silvermont", "GenuineIntel", MAKE_FMS (6, 0x37) },
|
|
Packit |
5c3484 |
{ "slm", "GenuineIntel", MAKE_FMS (6, 0x37) },
|
|
Packit |
5c3484 |
{ "haswell", "GenuineIntel", MAKE_FMS (6, 0x3c) },
|
|
Packit |
5c3484 |
{ "hwl", "GenuineIntel", MAKE_FMS (6, 0x3c) },
|
|
Packit |
5c3484 |
{ "broadwell", "GenuineIntel", MAKE_FMS (6, 0x3d) },
|
|
Packit |
5c3484 |
{ "bwl", "GenuineIntel", MAKE_FMS (6, 0x3d) },
|
|
Packit |
5c3484 |
{ "skylake", "GenuineIntel", MAKE_FMS (6, 0x5e) },
|
|
Packit |
5c3484 |
{ "sky", "GenuineIntel", MAKE_FMS (6, 0x5e) },
|
|
Packit |
5c3484 |
{ "pentium4", "GenuineIntel", MAKE_FMS (15, 3) },
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
{ "k8", "AuthenticAMD", MAKE_FMS (15, 0) },
|
|
Packit |
5c3484 |
{ "k10", "AuthenticAMD", MAKE_FMS (16, 0) },
|
|
Packit |
5c3484 |
{ "bobcat", "AuthenticAMD", MAKE_FMS (20, 1) },
|
|
Packit |
5c3484 |
{ "bulldozer", "AuthenticAMD", MAKE_FMS (21, 1) },
|
|
Packit |
5c3484 |
{ "piledriver", "AuthenticAMD", MAKE_FMS (21, 2) },
|
|
Packit |
5c3484 |
{ "steamroller","AuthenticAMD", MAKE_FMS (21, 0x30) },
|
|
Packit |
5c3484 |
{ "excavator", "AuthenticAMD", MAKE_FMS (21, 0x60) },
|
|
Packit |
5c3484 |
{ "jaguar", "AuthenticAMD", MAKE_FMS (22, 1) },
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
{ "nano", "CentaurHauls", MAKE_FMS (6, 15) },
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
static int
|
|
Packit |
5c3484 |
fake_cpuid_lookup (void)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
char *s;
|
|
Packit |
5c3484 |
int i;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
s = getenv ("GMP_CPU_TYPE");
|
|
Packit |
5c3484 |
if (s == NULL)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
printf ("Need GMP_CPU_TYPE environment variable for fake cpuid\n");
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
for (i = 0; i < numberof (fake_cpuid_table); i++)
|
|
Packit |
5c3484 |
if (strcmp (s, fake_cpuid_table[i].name) == 0)
|
|
Packit |
5c3484 |
return i;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
printf ("GMP_CPU_TYPE=%s unknown\n", s);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
static long
|
|
Packit |
5c3484 |
fake_cpuid (char dst[12], unsigned int id)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
int i = fake_cpuid_lookup();
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
switch (id) {
|
|
Packit |
5c3484 |
case 0:
|
|
Packit |
5c3484 |
memcpy (dst, fake_cpuid_table[i].vendor, 12);
|
|
Packit |
5c3484 |
return 0;
|
|
Packit |
5c3484 |
case 1:
|
|
Packit |
5c3484 |
return fake_cpuid_table[i].fms;
|
|
Packit |
5c3484 |
case 7:
|
|
Packit |
5c3484 |
dst[0] = 0xff; /* BMI1, AVX2, etc */
|
|
Packit |
5c3484 |
dst[1] = 0xff; /* BMI2, etc */
|
|
Packit |
5c3484 |
return 0;
|
|
Packit |
5c3484 |
case 0x80000001:
|
|
Packit |
5c3484 |
dst[4 + 29 / 8] = (1 << (29 % 8)); /* "long" mode */
|
|
Packit |
5c3484 |
return 0;
|
|
Packit |
5c3484 |
default:
|
|
Packit |
5c3484 |
printf ("fake_cpuid(): oops, unknown id %d\n", id);
|
|
Packit |
5c3484 |
abort ();
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
#endif
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
typedef DECL_preinv_divrem_1 ((*preinv_divrem_1_t));
|
|
Packit |
5c3484 |
typedef DECL_preinv_mod_1 ((*preinv_mod_1_t));
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
struct cpuvec_t __gmpn_cpuvec = {
|
|
Packit |
5c3484 |
__MPN(add_n_init),
|
|
Packit |
5c3484 |
__MPN(addlsh1_n_init),
|
|
Packit |
5c3484 |
__MPN(addlsh2_n_init),
|
|
Packit |
5c3484 |
__MPN(addmul_1_init),
|
|
Packit |
5c3484 |
__MPN(addmul_2_init),
|
|
Packit |
5c3484 |
__MPN(bdiv_dbm1c_init),
|
|
Packit |
5c3484 |
__MPN(cnd_add_n_init),
|
|
Packit |
5c3484 |
__MPN(cnd_sub_n_init),
|
|
Packit |
5c3484 |
__MPN(com_init),
|
|
Packit |
5c3484 |
__MPN(copyd_init),
|
|
Packit |
5c3484 |
__MPN(copyi_init),
|
|
Packit |
5c3484 |
__MPN(divexact_1_init),
|
|
Packit |
5c3484 |
__MPN(divrem_1_init),
|
|
Packit |
5c3484 |
__MPN(gcd_1_init),
|
|
Packit |
5c3484 |
__MPN(lshift_init),
|
|
Packit |
5c3484 |
__MPN(lshiftc_init),
|
|
Packit |
5c3484 |
__MPN(mod_1_init),
|
|
Packit |
5c3484 |
__MPN(mod_1_1p_init),
|
|
Packit |
5c3484 |
__MPN(mod_1_1p_cps_init),
|
|
Packit |
5c3484 |
__MPN(mod_1s_2p_init),
|
|
Packit |
5c3484 |
__MPN(mod_1s_2p_cps_init),
|
|
Packit |
5c3484 |
__MPN(mod_1s_4p_init),
|
|
Packit |
5c3484 |
__MPN(mod_1s_4p_cps_init),
|
|
Packit |
5c3484 |
__MPN(mod_34lsub1_init),
|
|
Packit |
5c3484 |
__MPN(modexact_1c_odd_init),
|
|
Packit |
5c3484 |
__MPN(mul_1_init),
|
|
Packit |
5c3484 |
__MPN(mul_basecase_init),
|
|
Packit |
5c3484 |
__MPN(mullo_basecase_init),
|
|
Packit |
5c3484 |
__MPN(preinv_divrem_1_init),
|
|
Packit |
5c3484 |
__MPN(preinv_mod_1_init),
|
|
Packit |
5c3484 |
__MPN(redc_1_init),
|
|
Packit |
5c3484 |
__MPN(redc_2_init),
|
|
Packit |
5c3484 |
__MPN(rshift_init),
|
|
Packit |
5c3484 |
__MPN(sqr_basecase_init),
|
|
Packit |
5c3484 |
__MPN(sub_n_init),
|
|
Packit |
5c3484 |
__MPN(sublsh1_n_init),
|
|
Packit |
5c3484 |
__MPN(submul_1_init),
|
|
Packit |
5c3484 |
0
|
|
Packit |
5c3484 |
};
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
int __gmpn_cpuvec_initialized = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* The following setups start with generic x86, then overwrite with
|
|
Packit |
5c3484 |
specifics for a chip, and higher versions of that chip.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
The arrangement of the setups here will normally be the same as the $path
|
|
Packit |
5c3484 |
selections in configure.in for the respective chips.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
This code is reentrant and thread safe. We always calculate the same
|
|
Packit |
5c3484 |
decided_cpuvec, so if two copies of the code are running it doesn't
|
|
Packit |
5c3484 |
matter which completes first, both write the same to __gmpn_cpuvec.
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
We need to go via decided_cpuvec because if one thread has completed
|
|
Packit |
5c3484 |
__gmpn_cpuvec then it may be making use of the threshold values in that
|
|
Packit |
5c3484 |
vector. If another thread is still running __gmpn_cpuvec_init then we
|
|
Packit |
5c3484 |
don't want it to write different values to those fields since some of the
|
|
Packit |
5c3484 |
asm routines only operate correctly up to their own defined threshold,
|
|
Packit |
5c3484 |
not an arbitrary value. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
static int
|
|
Packit |
5c3484 |
gmp_workaround_skylake_cpuid_bug ()
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
char feature_string[49];
|
|
Packit |
5c3484 |
char processor_name_string[49];
|
|
Packit |
5c3484 |
static const char *bad_cpus[] = {" G44", " G45", " G39" /* , "6600" */ };
|
|
Packit |
5c3484 |
int i;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Example strings: */
|
|
Packit |
5c3484 |
/* "Intel(R) Pentium(R) CPU G4400 @ 3.30GHz" */
|
|
Packit |
5c3484 |
/* "Intel(R) Core(TM) i5-6600K CPU @ 3.50GHz" */
|
|
Packit |
5c3484 |
/* ^ ^ ^ */
|
|
Packit |
5c3484 |
/* 0x80000002 0x80000003 0x80000004 */
|
|
Packit |
5c3484 |
/* We match out just the 0x80000003 part here. */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* In their infinitive wisdom, Intel decided to use one register order for
|
|
Packit |
5c3484 |
the vendor string, and another for the processor name string. We shuffle
|
|
Packit |
5c3484 |
things about here, rather than write a new variant of our assembly cpuid.
|
|
Packit |
5c3484 |
*/
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
unsigned int eax, ebx, ecx, edx;
|
|
Packit |
5c3484 |
eax = __gmpn_cpuid (feature_string, 0x80000003);
|
|
Packit |
5c3484 |
ebx = ((unsigned int *)feature_string)[0];
|
|
Packit |
5c3484 |
edx = ((unsigned int *)feature_string)[1];
|
|
Packit |
5c3484 |
ecx = ((unsigned int *)feature_string)[2];
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
((unsigned int *) (processor_name_string))[0] = eax;
|
|
Packit |
5c3484 |
((unsigned int *) (processor_name_string))[1] = ebx;
|
|
Packit |
5c3484 |
((unsigned int *) (processor_name_string))[2] = ecx;
|
|
Packit |
5c3484 |
((unsigned int *) (processor_name_string))[3] = edx;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
processor_name_string[16] = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
for (i = 0; i < sizeof (bad_cpus) / sizeof (char *); i++)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
if (strstr (processor_name_string, bad_cpus[i]) != 0)
|
|
Packit |
5c3484 |
return 1;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
return 0;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
enum {BMI2_BIT = 8};
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
void
|
|
Packit |
5c3484 |
__gmpn_cpuvec_init (void)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
struct cpuvec_t decided_cpuvec;
|
|
Packit |
5c3484 |
char vendor_string[13];
|
|
Packit |
5c3484 |
char dummy_string[12];
|
|
Packit |
5c3484 |
long fms;
|
|
Packit |
5c3484 |
int family, model;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
TRACE (printf ("__gmpn_cpuvec_init:\n"));
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
memset (&decided_cpuvec, '\0', sizeof (decided_cpuvec));
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
CPUVEC_SETUP_x86_64;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_fat;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
__gmpn_cpuid (vendor_string, 0);
|
|
Packit |
5c3484 |
vendor_string[12] = 0;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
fms = __gmpn_cpuid (dummy_string, 1);
|
|
Packit |
5c3484 |
family = ((fms >> 8) & 0xf) + ((fms >> 20) & 0xff);
|
|
Packit |
5c3484 |
model = ((fms >> 4) & 0xf) + ((fms >> 12) & 0xf0);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Check extended feature flags */
|
|
Packit |
5c3484 |
__gmpn_cpuid (dummy_string, 0x80000001);
|
|
Packit |
5c3484 |
if ((dummy_string[4 + 29 / 8] & (1 << (29 % 8))) == 0)
|
|
Packit |
5c3484 |
abort (); /* longmode-capable-bit turned off! */
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/*********************************************************/
|
|
Packit |
5c3484 |
/*** WARNING: keep this list in sync with config.guess ***/
|
|
Packit |
5c3484 |
/*********************************************************/
|
|
Packit |
5c3484 |
if (strcmp (vendor_string, "GenuineIntel") == 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
switch (family)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
case 6:
|
|
Packit |
5c3484 |
switch (model)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
case 0x0f: /* Conroe Merom Kentsfield Allendale */
|
|
Packit |
5c3484 |
case 0x10:
|
|
Packit |
5c3484 |
case 0x11:
|
|
Packit |
5c3484 |
case 0x12:
|
|
Packit |
5c3484 |
case 0x13:
|
|
Packit |
5c3484 |
case 0x14:
|
|
Packit |
5c3484 |
case 0x15:
|
|
Packit |
5c3484 |
case 0x16:
|
|
Packit |
5c3484 |
case 0x17: /* PNR Wolfdale Yorkfield */
|
|
Packit |
5c3484 |
case 0x18:
|
|
Packit |
5c3484 |
case 0x19:
|
|
Packit |
5c3484 |
case 0x1d: /* PNR Dunnington */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x1c: /* Atom Silverthorne */
|
|
Packit |
5c3484 |
case 0x26: /* Atom Lincroft */
|
|
Packit |
5c3484 |
case 0x27: /* Atom Saltwell? */
|
|
Packit |
5c3484 |
case 0x36: /* Atom Cedarview/Saltwell */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_atom;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x1a: /* NHM Gainestown */
|
|
Packit |
5c3484 |
case 0x1b:
|
|
Packit |
5c3484 |
case 0x1e: /* NHM Lynnfield/Jasper */
|
|
Packit |
5c3484 |
case 0x1f:
|
|
Packit |
5c3484 |
case 0x20:
|
|
Packit |
5c3484 |
case 0x21:
|
|
Packit |
5c3484 |
case 0x22:
|
|
Packit |
5c3484 |
case 0x23:
|
|
Packit |
5c3484 |
case 0x24:
|
|
Packit |
5c3484 |
case 0x25: /* WSM Clarkdale/Arrandale */
|
|
Packit |
5c3484 |
case 0x28:
|
|
Packit |
5c3484 |
case 0x29:
|
|
Packit |
5c3484 |
case 0x2b:
|
|
Packit |
5c3484 |
case 0x2c: /* WSM Gulftown */
|
|
Packit |
5c3484 |
case 0x2e: /* NHM Beckton */
|
|
Packit |
5c3484 |
case 0x2f: /* WSM Eagleton */
|
|
Packit |
5c3484 |
case 0x37: /* Silvermont */
|
|
Packit |
5c3484 |
case 0x4a: /* Silvermont */
|
|
Packit |
5c3484 |
case 0x4c: /* Airmont */
|
|
Packit |
5c3484 |
case 0x4d: /* Silvermont/Avoton */
|
|
Packit |
5c3484 |
case 0x5a: /* Silvermont */
|
|
Packit |
5c3484 |
case 0x5c: /* Goldmont */
|
|
Packit |
5c3484 |
case 0x5f: /* Goldmont */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreinhm;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x2a: /* SB */
|
|
Packit |
5c3484 |
case 0x2d: /* SBC-EP */
|
|
Packit |
5c3484 |
case 0x3a: /* IBR */
|
|
Packit |
5c3484 |
case 0x3e: /* IBR Ivytown */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreinhm;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreisbr;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
case 0x3c: /* Haswell client */
|
|
Packit |
5c3484 |
case 0x3f: /* Haswell server */
|
|
Packit |
5c3484 |
case 0x45: /* Haswell ULT */
|
|
Packit |
5c3484 |
case 0x46: /* Crystal Well */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreinhm;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreisbr;
|
|
Packit |
5c3484 |
/* Some Haswells lack BMI2. Let them appear as Sandybridges for
|
|
Packit |
5c3484 |
now. */
|
|
Packit |
5c3484 |
__gmpn_cpuid (dummy_string, 7);
|
|
Packit |
5c3484 |
if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreihwl;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
case 0x3d: /* Broadwell */
|
|
Packit |
5c3484 |
case 0x47: /* Broadwell */
|
|
Packit |
5c3484 |
case 0x4f: /* Broadwell server */
|
|
Packit |
5c3484 |
case 0x56: /* Broadwell microserver */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreinhm;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreisbr;
|
|
Packit |
5c3484 |
if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreihwl;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreibwl;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
case 0x4e: /* Skylake client */
|
|
Packit |
5c3484 |
case 0x55: /* Skylake server */
|
|
Packit |
5c3484 |
case 0x5e: /* Skylake */
|
|
Packit |
5c3484 |
case 0x8e: /* Kabylake */
|
|
Packit |
5c3484 |
case 0x9e: /* Kabylake */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_core2;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreinhm;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreisbr;
|
|
Packit |
5c3484 |
if ((dummy_string[0 + BMI2_BIT / 8] & (1 << (BMI2_BIT % 8))) == 0)
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
if (gmp_workaround_skylake_cpuid_bug ())
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreihwl;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_coreibwl;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_skylake;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 15:
|
|
Packit |
5c3484 |
CPUVEC_SETUP_pentium4;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
else if (strcmp (vendor_string, "AuthenticAMD") == 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
switch (family)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
case 0x0f: /* k8 */
|
|
Packit |
5c3484 |
case 0x11: /* "fam 11h", mix of k8 and k10 */
|
|
Packit |
5c3484 |
case 0x13:
|
|
Packit |
5c3484 |
case 0x17:
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k8;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x10: /* k10 */
|
|
Packit |
5c3484 |
case 0x12: /* k10 (llano) */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k8;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k10;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x14: /* bobcat */
|
|
Packit |
5c3484 |
case 0x16: /* jaguar */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k8;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k10;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_bobcat;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
case 0x15: /* bulldozer, piledriver, steamroller, excavator */
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k8;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_k10;
|
|
Packit |
5c3484 |
CPUVEC_SETUP_bd1;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
else if (strcmp (vendor_string, "CentaurHauls") == 0)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
switch (family)
|
|
Packit |
5c3484 |
{
|
|
Packit |
5c3484 |
case 6:
|
|
Packit |
5c3484 |
if (model >= 15)
|
|
Packit |
5c3484 |
CPUVEC_SETUP_nano;
|
|
Packit |
5c3484 |
break;
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
}
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* There's no x86 generic mpn_preinv_divrem_1 or mpn_preinv_mod_1.
|
|
Packit |
5c3484 |
Instead default to the plain versions from whichever CPU we detected.
|
|
Packit |
5c3484 |
The function arguments are compatible, no need for any glue code. */
|
|
Packit |
5c3484 |
if (decided_cpuvec.preinv_divrem_1 == NULL)
|
|
Packit |
5c3484 |
decided_cpuvec.preinv_divrem_1 =(preinv_divrem_1_t)decided_cpuvec.divrem_1;
|
|
Packit |
5c3484 |
if (decided_cpuvec.preinv_mod_1 == NULL)
|
|
Packit |
5c3484 |
decided_cpuvec.preinv_mod_1 =(preinv_mod_1_t) decided_cpuvec.mod_1;
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
ASSERT_CPUVEC (decided_cpuvec);
|
|
Packit |
5c3484 |
CPUVEC_INSTALL (decided_cpuvec);
|
|
Packit |
5c3484 |
|
|
Packit |
5c3484 |
/* Set this once the threshold fields are ready.
|
|
Packit |
5c3484 |
Use volatile to prevent it getting moved. */
|
|
Packit |
5c3484 |
*((volatile int *) &__gmpn_cpuvec_initialized) = 1;
|
|
Packit |
5c3484 |
}
|