mpir/cpuid.c

277 lines
8.4 KiB
C
Raw Normal View History

2009-07-15 11:53:17 -04:00
/*
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Copyright 2008 William Hart.
2011-04-04 08:15:56 -04:00
Copyright 2009,2010,2011 Jason Moxham
2009-07-15 11:53:17 -04:00
Copyright 2010 Gonzalo Tornaria
2010-01-13 13:10:38 -05:00
2009-07-15 11:53:17 -04:00
This file is part of the MPIR Library.
The MPIR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.
The MPIR Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the MPIR Library; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
2011-04-05 06:45:29 -04:00
#define WANT_FAKE_BUILD_CPU 0
#define WANT_FAKE_FAT_CPU 0
2011-04-05 06:45:29 -04:00
#define FAKE_BUILD_CPU_VENDOR "MPIRSNOTFAKE"
#define FAKE_BUILD_CPU_FAMILY 0
#define FAKE_BUILD_CPU_EXTFAMILY 0
#define FAKE_BUILD_CPU_MODEL 0
#define FAKE_BUILD_CPU_EXTMODEL 0
2011-04-05 06:45:29 -04:00
#define FAKE_FAT_CPU_VENDOR "MPIRSNOTFAKE"
#define FAKE_FAT_CPU_FAMILY 0
#define FAKE_FAT_CPU_EXTFAMILY 0
#define FAKE_FAT_CPU_MODEL 0
#define FAKE_FAT_CPU_EXTMODEL 0
#if INFAT
#define WANT_FAKE_CPU WANT_FAKE_FAT_CPU
#define FAKE_CPU_VENDOR FAKE_FAT_CPU_VENDOR
#define FAKE_CPU_FAMILY FAKE_FAT_CPU_FAMILY
#define FAKE_CPU_EXTFAMILY FAKE_FAT_CPU_EXTFAMILY
#define FAKE_CPU_MODEL FAKE_FAT_CPU_MODEL
#define FAKE_CPU_EXTMODEL FAKE_FAT_CPU_EXTMODEL
#endif
#if CONFIG_GUESS
#define WANT_FAKE_CPU WANT_FAKE_BUILD_CPU
#define FAKE_CPU_VENDOR FAKE_BUILD_CPU_VENDOR
#define FAKE_CPU_FAMILY FAKE_BUILD_CPU_FAMILY
#define FAKE_CPU_EXTFAMILY FAKE_BUILD_CPU_EXTFAMILY
#define FAKE_CPU_MODEL FAKE_BUILD_CPU_MODEL
#define FAKE_CPU_EXTMODEL FAKE_BUILD_CPU_EXTMODEL
#endif
2011-04-04 08:15:56 -04:00
2011-04-05 06:45:29 -04:00
#if WANT_FAKE_CPU
long fake_cpuid(char *p,unsigned int level)
{unsigned int eax,feat801=0,feat2=0,family,extfamily,model,extmodel;
char *vendor;
// can set feat801=1 for netburstlahf
// can set feat2=256 for prescott
vendor=FAKE_CPU_VENDOR;
family=FAKE_CPU_FAMILY;
extfamily=FAKE_CPU_EXTFAMILY;
model=FAKE_CPU_MODEL;
extmodel=FAKE_CPU_EXTMODEL;
memset(p,0,12);
if(level==0){strncpy(p,vendor,12);return 1;}
if(level==1){eax=0+(model<<4)+(family<<8)+(0<<12)+(extmodel<<16)+(extfamily<<20);memcpy(p,&feat2,4);return eax;}
if(level==0x80000000){return 1;}
if(level==0x80000001){memcpy(p+8,&feat801,4);return 0;}
return 0;}
#endif
2011-04-04 08:15:56 -04:00
#if WANT_FAKE_CPU
#define __gmpn_cpuid fake_cpuid
#else
#if CONFIG_GUESS
#define __gmpn_cpuid(_x,_y) cpuid(_x,_y,1,0,0)
#endif
#endif
#define FEAT_HAS_AVX 0x10000000
#if CONFIG_GUESS
2009-09-27 19:12:12 -04:00
// use's the stringinzing directive #x ie #x expands to "x"
#define CPUIS(x) modelstr=#x
char* __gmpn_cpu(int *vector){
#endif
#if INFAT
#define CPUIS(x) do{TRACE(printf(" "#x"\n"));CPUSETUP_##x;}while(0)
char* __gmpn_cpu(struct cpuvec_t *vector){
struct cpuvec_t decided_cpuvec;
#endif
char vendor_string[13];
char features[12];
long fms;
int family, model, stepping;
char *modelstr=0;
#if INFAT
memset (&decided_cpuvec, '\0', sizeof (decided_cpuvec));
CPUVEC_SETUP_fat;
#if FAT32
CPUVEC_SETUP_x86;
#endif
#if FAT64
CPUVEC_SETUP_x86_64;
#endif
#endif
__gmpn_cpuid (vendor_string, 0);
vendor_string[12] = 0;
fms = __gmpn_cpuid (features, 1);
family = ((fms >> 8) & 15) + ((fms >> 20) & 0xff);
model = ((fms >> 4) & 15) + ((fms >> 12) & 0xf0);
stepping = fms & 15;
2011-04-04 08:15:56 -04:00
#if CONFIG_GUESS_64BIT
modelstr = "x86_64";
#else
modelstr = "i486";// shouldn't we make this x86??
#endif
if (strcmp (vendor_string, "GenuineIntel") == 0)
{
switch (family)
{
#if CONFIG_GUESS_32BIT || FAT32
case 5:
if (model <= 2) CPUIS(pentium);
if (model >= 4) CPUIS(pentiummmx);
break;
#endif
case 6:
#if CONFIG_GUESS_32BIT || FAT32
if (model == 1) { CPUIS(pentiumpro);break;}
if (model <= 6) { CPUIS(pentium2);break;}
if (model <= 13){ CPUIS(pentium3);break;}
if (model == 14){ CPUIS(core);break;}
if (model == 16){ CPUIS(core);break;}
#endif
if (model == 15){ CPUIS(core2);break;}
if (model == 17){ CPUIS(penryn);break;}
if (model == 22){ CPUIS(core2);break;}
if (model == 23){ CPUIS(penryn);break;}
if (model == 25){ CPUIS(westmere);break;}
if (model == 26){ CPUIS(nehalem);break;}
if (model == 28){ CPUIS(atom);break;}// 45nm
if (model == 29){ CPUIS(penryn);break;}
if (model == 30){ CPUIS(nehalem);break;}
if (model == 31){ CPUIS(nehalem);break;}
if (model == 37){ CPUIS(westmere);break;}
if (model == 38){ CPUIS(atom);break;}// atom z670 tunnel creek
if (model == 39){ CPUIS(atom);break;}// Intel Atom Z2460 (Medfield platform, Penwell SoC, Saltwell core)
if (model == 42){
int feat = ((int *)features)[2];
if (feat & FEAT_HAS_AVX) { CPUIS(sandybridge);break;}
else { CPUIS(westmere);break;} /* Really a crippled sandybridge with no avx */
}
if (model == 43){ CPUIS(sandybridge);break;}
2010-12-05 06:10:26 -05:00
if (model == 44){ CPUIS(westmere);break;}
2012-03-13 03:22:11 -04:00
if (model == 45){ CPUIS(sandybridge);break;}
if (model == 46){ CPUIS(nehalem);break;}
if (model == 47){ CPUIS(westmere);break;}
if (model == 54){ CPUIS(atom);break;}//DualCore Intel Atom D2700, 2133 MHz (16 x 133) (Cedarview, Saltwell core) 32nm
if (model == 55){ CPUIS(atom);break;}
2015-06-09 17:42:30 -04:00
if (model == 58){ CPUIS(ivybridge);break;}
if (model == 60){
int feat = ((int *)features)[2];
if (feat & FEAT_HAS_AVX) { CPUIS(haswellavx);break; } /* Core i Haswell */
else { CPUIS(haswell);break; } /* Celeron/Pentium Haswell without AVX */
}
if (model == 61){ CPUIS(broadwell);break;}
2015-06-09 17:42:30 -04:00
if (model == 62){ CPUIS(ivybridge);break;}
if (model == 63){ CPUIS(haswellavx);break;}
if (model == 69){ CPUIS(haswellavx);break;}
if (model == 70){ CPUIS(haswellavx);break;}
2017-02-21 05:30:29 -05:00
if (model == 71){ CPUIS(broadwell);break;}
if (model == 78){ CPUIS(skylakeavx);break;}
if (model == 79){ CPUIS(broadwell);break;}
if (model == 94){
int feat = ((int *)features)[2];
if (feat & FEAT_HAS_AVX) { CPUIS(skylakeavx);break; } /* Core i Skylake */
else { CPUIS(skylake);break; } /* Celeron/Pentium Skylake without AVX2 */
}
break;
case 15:
#if CONFIG_GUESS_64BIT || FAT64
__gmpn_cpuid(features,0x80000001);
if ( features[8]&1 ){ CPUIS(netburstlahf);break;}
CPUIS(netburst);break;
#endif
#if CONFIG_GUESS_32BIT || FAT32
if (model <= 6) { CPUIS(pentium4);break;}
int feat = ((int *)features)[2];
if (feat & 1) { CPUIS(prescott);break;}
#endif
break;
}
}
else if (strcmp (vendor_string, "AuthenticAMD") == 0)
{
switch (family)
{
#if CONFIG_GUESS_32BIT || FAT32
case 5:
if (model <= 3) { CPUIS(k5);break;}
if (model <= 7) { CPUIS(k6);break;}
if (model <= 8) { CPUIS(k62);break;}
if (model <= 9) { CPUIS(k63);break;}
break;
case 6:
CPUIS(k7);
break;
#endif
case 15:
CPUIS(k8);
break;
case 16:
if (model == 2) { CPUIS(k10);break; }
if (model == 4) { CPUIS(k102);break; }
if (model == 5) { CPUIS(k102);break; }
if (model == 6) { CPUIS(k102);break; }
if (model == 8) { CPUIS(k102);break; }
if (model == 9) { CPUIS(k102);break; }
if (model == 10) { CPUIS(k102);break; }
break;
case 17:
CPUIS(k8);// low power k8
break;
case 18:
CPUIS(k103);// like k102 but with hardware divider, this is lano
break;
case 20:
CPUIS(bobcat);// fusion of bobcat and GPU
break;
case 21:
if (model == 1) { CPUIS(bulldozer); break; }
if (model == 2) { CPUIS(piledriver); break; }
if (model == 3) { CPUIS(piledriver); break; }
if (model == 16) { CPUIS(piledriver); break; }
if (model == 18) { CPUIS(piledriver); break; }
if (model == 19) { CPUIS(piledriver); break; }
break;
/*
case 22:
CPUIS(jaguar); ?????
break;
*/
}
}
else if (strcmp (vendor_string, "CentaurHauls") == 0)
{
switch (family)
{
case 6:
2009-09-27 19:12:12 -04:00
if (model == 15){CPUIS(nano);break;}
#if CONFIG_GUESS_32BIT || FAT32
if (model < 9) { CPUIS(viac3);break;}
CPUIS(viac32);break;
2009-09-27 19:12:12 -04:00
#endif
}
}
#if INFAT
*vector=decided_cpuvec;
#endif
return modelstr;}