⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archinfo_x86.c

📁 基于Blas CLapck的.用过的人知道是干啥的
💻 C
字号:
/* *             Automatically Tuned Linear Algebra Software v@(ver) *                    (C) Copyright 2006 R. Clint Whaley * * Code contributers : R. Clint Whaley, Dean Gaudet * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *   1. Redistributions of source code must retain the above copyright *      notice, this list of conditions and the following disclaimer. *   2. Redistributions in binary form must reproduce the above copyright *      notice, this list of conditions, and the following disclaimer in the *      documentation and/or other materials provided with the distribution. *   3. The name of the ATLAS group or the names of its contributers may *      not be used to endorse or promote products derived from this *      software without specific written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * *//* * This code written for ATLAS use by R. Clint Whaley based on code and info * submitted by Dean Gaudet, with the later help of the following websites: *   http://www.sandpile.org/ia32/cpuid.htm *   http://en.wikipedia.org/wiki/CPUID */#include <stdio.h>#include <string.h>#include <stdlib.h>#include "atlconf.h"#define uint unsigned int/* * This routine returns the contents of registers set by the cpuid instruction * in the array res: *   res[0] : eax *   res[1] : ebx *   res[2] : ecx *   res[3] : edx */void do_cpuid(uint *res, uint level);/* result defines */#define EAX 0#define EBX 1#define ECX 2#define EDX 3/* My driver, based on Dean's */int ProbeArch(char *vendor, unsigned *family, unsigned *model, int *x86_64)/* * Returns 0 on success, non-zero on error */{   uint r[4];   uint max_level;   uint *vp = (uint*) vendor;   *x86_64 = 0;/* * In this call, we ask for max supported cpuid support, and return if * we can't get any usuable info.  Also sets ebx,edx and ecx (16 chars of data) * to vendor ID string */   do_cpuid(r, 0);   max_level = r[EAX];   if (!max_level)      return(1);/* * Copy vendor string as 3 ints rather than 16 char, then null-term at 12 */   *vp = r[EBX];   vp[1] = r[EDX];   vp[2] = r[ECX];   vendor[12] = '\0';/* * Find processor family and model, ouput EAX */   do_cpuid(r, 1);   *family = (r[EAX] >> 8) & 0xf;      /* base family in bits 11-8 */   if (*family == 0xf || *family == 0) /* extended family is added in */       *family += ((r[EAX] >> 20) & 0xff);   *model = (r[0] >> 4) & 0xf;         /* model in bits 7-4 */   if (*model == 0xf)                  /* extended model is concatenated */      *model |= ((r[0] >> 12) & 0xf0);/* * Find out if we have extended cpuid level, and if so, see if we've got * x86-64 capability or not */   do_cpuid(r, 0x80000000);   if (r[0] >= 0x80000001)   {      do_cpuid(r, 0x80000001);      *x86_64 = (r[EDX] & (1<<29)) != 0;   /* x86-64 in bit 29 */   }   return(0);}/* * constants used to check family + extended family */#define EF_486       4        /* also AMD 5x86 and Cyrix 5x86 */#define EF_P5        5        /* P5, K5 and K6 */#define EF_P6        6        /* P6, Core and K7 (athlon) */#define EF_ITAN0     7        /* Itanium */#define EF_K8_P4_EFF 0x00F    /* P4, Hammer, Efficien */#define EF_K8_ITAN   0x01F    /* Hammer, Itanium */#define EF_K8        0x02F    /* Hammer */#define EF_ITAN      0x020    /* Itanium */enum FAM {ERR,         /* cannot decipher */          i486,        /* 486 & AMD 5x86 and Cyrix 5x86 */          P5,          /* Original Pentium and AMD K5 & K6 */          P6,          /* Intel PIII, Core and AMD K7 (orig athlon) */          P7,          /* Intel P4, AMD hammer, Efficeon */          ITAN};       /* Intel Itanium */enum FAM GetFamily(int efam)  /* efam = (family+ext fam) from cpuid *//* * Translates CPUID (family+extended family) to FAM enum type */{   enum FAM iret;   switch (efam)   {   case EF_486:               /* also AMD 5x86 and Cyrix 5x86 */      iret = i486;      break;   case EF_P5:                /* P5, K5 and K6 */      iret = P5;      break;   case EF_P6:                /* P6, Core and K7 (athlon) */      iret = P6;      break;   case EF_K8_P4_EFF:         /* P4, Hammer, Efficien */      iret = P7;      break;   case EF_K8_ITAN:           /* Hammer, Itanium */   case EF_K8:                /* Hammer */      iret = P7;      break;   case EF_ITAN:              /* Itanium */   case EF_ITAN0:             /* Itanium */      iret = ITAN;      break;   default:      iret = ERR;   }   return (iret);}enum VEND {VERR, Intel, AMD, TM};enum VEND str2vend(char *vendor)/* * Translates vendor string to enum type */{   enum VEND iret;   if (strstr(vendor, "GenuineIntel") != NULL)      iret = Intel;   else if (strstr(vendor, "AuthenticAMD") != NULL)      iret = AMD;   else if (strstr(vendor, "GenuineTMx86") != NULL)      iret = TM;   else      iret = VERR;   return(iret);}/* * Specific chip (family, but disambiguated using vendor string */enum CHIP {CERR, Pentium, IntP6, Pentium4, Itanium, K7, Hammer,           Crusoe, Efficeon};enum CHIP Family2Chip(char *vendor, enum FAM family)/* * Disambiguates family based on vendor string */{   enum CHIP iret=CERR;   enum VEND ivend;/* * Figure out the vendor */   ivend = str2vend(vendor);   if (ivend == VERR)      return(CERR);   switch(family)   {   case   i486:        /* 486 & AMD 5x86 and Cyrix 5x86; unsupported */      break;   case   P5:          /* Original Pentium and AMD K5 & K6 */      if (ivend == Intel)         iret = Pentium;      break;   case   P6:          /* Intel PIII, Core and AMD K7 (orig athlon) */      if (ivend == Intel)         iret = IntP6;      else if (ivend == AMD)         iret = K7;      else if (ivend == TM)         iret = Crusoe;      break;   case   P7:          /* Intel P4, AMD hammer, Efficeon */      if (ivend == Intel)         iret = Pentium4;      else if (ivend == AMD)         iret = Hammer;      else if (ivend == TM)         iret = Efficeon;      break;   case   ITAN:        /* Intel Itanium */      iret = Itanium;      break;   default:      iret = CERR;   }   return(iret);}enum MACHTYPE Chip2Mach(enum CHIP chip, int model, int x8664)/* * translates chip and cpuid's model to config's machine enum */{   enum MACHTYPE iret=MACHOther;   switch(chip)   {   case Pentium:      switch(model)      {      case 1:         iret = IntP5;         break;      case 4:      case 8:         iret = IntP5MMX;         break;      default:         iret = MACHOther;      }      break;   case IntP6:  /* includes PPRO, PII, PIII, Core and Pentium-M */      switch(model)      {      case 0:      case 1:         iret = IntPPRO;         break;      case 3:      case 5:      case 6:         iret = IntPII;         break;      case 7:      case 8:      case 10:      case 11:         iret = IntPIII;         break;      case  9:      case 13:         iret = IntPM;      case 14:         iret = IntCoreDuo;         break;      case 15:         iret = IntCore2Duo;         break;      default:         iret = MACHOther;      }      break;   case Pentium4:      switch(model)      {      case 0:      case 1:      case 2:         iret = IntP4;         break;      case 3:      case 4:         iret = IntP4E;         break;      default:         iret = MACHOther;      }      break;   case Itanium:      switch(model)      {      case 7:         iret = IA64Itan;         break;      case 0x1F:         iret = IA64Itan2;         break;      default:         iret = MACHOther;      }      break;   case K7:      switch(model)      {      case 4:      case 6:      case 8:      case 10:         iret = AmdAthlon;         break;      default:         iret = MACHOther;      }      break;   case Hammer:      iret = AmdHammer;      break;   case Efficeon:      iret = TMEff;      break;   case Crusoe:  /* unsupported */   default:      iret = MACHOther;   }   return(iret);}void PrintUsage(char *name, int i){   fprintf(stderr, "USAGE: %s -v (verb) -b (@ bits) -a (arch) -n (ncpu) -c <ncache> -C <lvl> (cache size) -m (Mhz) -t (cpu throttling)\n", name);   exit(i);}int GetFlags(int nargs, char **args, int *CacheLevel){   int i, flag = 0;   *CacheLevel = 0;   for (i=1; i < nargs; i++)   {      if (args[i][0] != '-') PrintUsage(args[0], i);      switch(args[i][1])      {      case 'n':         flag |= Pncpu;         break;      case 'c':         flag |= Pncache;         break;      case 'C':         if (++i > nargs)            PrintUsage(args[0], i);         *CacheLevel = atoi(args[i]);         break;      case 'v':         flag |= Pverb;         break;      case 'm':         flag |= PMhz;         break;      case 'a':         flag |= Parch;         break;      case 'b':         flag |= P64;         break;      case 't':         flag |= Pthrottle;         break;      default:         PrintUsage(args[0], i);      }   }   if (!flag)     flag = Parch | P64;   return(flag);}main(int nargs, char **args){   int ierr, x86_64, flags, CacheLevel;   unsigned family, model;   char *cpu="UNKNOWN", vendor[13];   enum FAM fam;   enum CHIP chip;   enum MACHTYPE mach;   flags = GetFlags(nargs, args, &CacheLevel);   cpu = NULL;   vendor[0] = '\0';   ierr = ProbeArch(vendor, &family, &model, &x86_64);/* * If ProbeArch worked, translate vendor+family+model to ATLAS config-name */   if (!ierr)   {       fam = GetFamily(family);       if (fam)       {          chip = Family2Chip(vendor, fam);          if (chip)          {             mach = Chip2Mach(chip, model, x86_64);             if (!mach) ierr = 300;          }          else ierr = 200;       }       else ierr = 100;   }   if (ierr)   {      fprintf(stderr, "ERROR: enum fam=%d, chip=%d, mach=%d\n",              fam, chip, mach);      printf("ERROR %d: vendor='%s', family=%d, model=%d, x86_64=%d\n",             ierr, vendor, family, model, x86_64);   }   else   {/* *    If verbatim set, print strings as well as enums */      if (flags & Parch)      {         if (flags & Pverb)            printf("cpu: %s\n", machnam[mach]);         printf("MACHTYPE=%d\n", mach);      }      if (flags & P64)         printf("PTR BITS=%d\n", x86_64 ? 64 : 32);/* *    Not sure how to detect this.  cpuid has some features that might work, *    will need to experiment later */      if (flags & Pthrottle)         printf("CPU THROTTLE=0\n");/* *    These guys can't be supported by cpuid, AFAIK */      if ((flags & PMhz) || (flags & Pncpu))         printf("Mhz/ncpu=0\n");/* *    Cache info could be returned, but I'm lazy, so don't */      if ((flags & Pncache) || (flags & PCacheSize))         printf("ncache/CacheSize=0\n");      if ((flags & (~Pverb)) == 0)         printf("family=%d, model=%d, cpu='%s', Ptr bits=%d, arch#=%d\n",                family, model, machnam[mach], x86_64?64:32, mach);   }   exit(ierr);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -