Blame thirdparty/openblas/xianyi-OpenBLAS-e6e87a2/driver/others/dynamic.c

kusano 2b45e8
/*********************************************************************/
kusano 2b45e8
/* Copyright 2009, 2010 The University of Texas at Austin.           */
kusano 2b45e8
/* All rights reserved.                                              */
kusano 2b45e8
/*                                                                   */
kusano 2b45e8
/* Redistribution and use in source and binary forms, with or        */
kusano 2b45e8
/* without modification, are permitted provided that the following   */
kusano 2b45e8
/* conditions are met:                                               */
kusano 2b45e8
/*                                                                   */
kusano 2b45e8
/*   1. Redistributions of source code must retain the above         */
kusano 2b45e8
/*      copyright notice, this list of conditions and the following  */
kusano 2b45e8
/*      disclaimer.                                                  */
kusano 2b45e8
/*                                                                   */
kusano 2b45e8
/*   2. Redistributions in binary form must reproduce the above      */
kusano 2b45e8
/*      copyright notice, this list of conditions and the following  */
kusano 2b45e8
/*      disclaimer in the documentation and/or other materials       */
kusano 2b45e8
/*      provided with the distribution.                              */
kusano 2b45e8
/*                                                                   */
kusano 2b45e8
/*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
kusano 2b45e8
/*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
kusano 2b45e8
/*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
kusano 2b45e8
/*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
kusano 2b45e8
/*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
kusano 2b45e8
/*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
kusano 2b45e8
/*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
kusano 2b45e8
/*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
kusano 2b45e8
/*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
kusano 2b45e8
/*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
kusano 2b45e8
/*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
kusano 2b45e8
/*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
kusano 2b45e8
/*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
kusano 2b45e8
/*    POSSIBILITY OF SUCH DAMAGE.                                    */
kusano 2b45e8
/*                                                                   */
kusano 2b45e8
/* The views and conclusions contained in the software and           */
kusano 2b45e8
/* documentation are those of the authors and should not be          */
kusano 2b45e8
/* interpreted as representing official policies, either expressed   */
kusano 2b45e8
/* or implied, of The University of Texas at Austin.                 */
kusano 2b45e8
/*********************************************************************/
kusano 2b45e8
kusano 2b45e8
#include "common.h"
kusano 2b45e8
kusano 2b45e8
#ifdef ARCH_X86
kusano 2b45e8
#define EXTERN extern
kusano 2b45e8
#else
kusano 2b45e8
#define EXTERN
kusano 2b45e8
#endif
kusano 2b45e8
kusano 2b45e8
EXTERN gotoblas_t  gotoblas_KATMAI;
kusano 2b45e8
EXTERN gotoblas_t  gotoblas_COPPERMINE;
kusano 2b45e8
EXTERN gotoblas_t  gotoblas_NORTHWOOD;
kusano 2b45e8
EXTERN gotoblas_t  gotoblas_BANIAS;
kusano 2b45e8
EXTERN gotoblas_t  gotoblas_ATHLON;
kusano 2b45e8
kusano 2b45e8
extern gotoblas_t  gotoblas_PRESCOTT;
kusano 2b45e8
extern gotoblas_t  gotoblas_ATOM;
kusano 2b45e8
extern gotoblas_t  gotoblas_NANO;
kusano 2b45e8
extern gotoblas_t  gotoblas_CORE2;
kusano 2b45e8
extern gotoblas_t  gotoblas_PENRYN;
kusano 2b45e8
extern gotoblas_t  gotoblas_DUNNINGTON;
kusano 2b45e8
extern gotoblas_t  gotoblas_NEHALEM;
kusano 2b45e8
extern gotoblas_t  gotoblas_OPTERON;
kusano 2b45e8
extern gotoblas_t  gotoblas_OPTERON_SSE3;
kusano 2b45e8
extern gotoblas_t  gotoblas_BARCELONA;
kusano 2b45e8
kusano 2b45e8
#define VENDOR_INTEL      1
kusano 2b45e8
#define VENDOR_AMD        2
kusano 2b45e8
#define VENDOR_CENTAUR    3
kusano 2b45e8
#define VENDOR_UNKNOWN   99
kusano 2b45e8
kusano 2b45e8
#define BITMASK(a, b, c) ((((a) >> (b)) & (c)))
kusano 2b45e8
kusano 2b45e8
static int get_vendor(void){
kusano 2b45e8
  int eax, ebx, ecx, edx;
kusano 2b45e8
  char vendor[13];
kusano 2b45e8
kusano 2b45e8
  cpuid(0, &eax, &ebx, &ecx, &edx);
kusano 2b45e8
  
kusano 2b45e8
  *(int *)(&vendor[0]) = ebx;
kusano 2b45e8
  *(int *)(&vendor[4]) = edx;
kusano 2b45e8
  *(int *)(&vendor[8]) = ecx;
kusano 2b45e8
  vendor[12] = (char)0;
kusano 2b45e8
kusano 2b45e8
  if (!strcmp(vendor, "GenuineIntel")) return VENDOR_INTEL;
kusano 2b45e8
  if (!strcmp(vendor, "AuthenticAMD")) return VENDOR_AMD;
kusano 2b45e8
  if (!strcmp(vendor, "CentaurHauls")) return VENDOR_CENTAUR;
kusano 2b45e8
kusano 2b45e8
  if ((eax == 0) || ((eax & 0x500) != 0)) return VENDOR_INTEL;
kusano 2b45e8
kusano 2b45e8
  return VENDOR_UNKNOWN;
kusano 2b45e8
}
kusano 2b45e8
kusano 2b45e8
static gotoblas_t *get_coretype(void){
kusano 2b45e8
kusano 2b45e8
  int eax, ebx, ecx, edx;
kusano 2b45e8
  int family, exfamily, model, vendor, exmodel;
kusano 2b45e8
kusano 2b45e8
  cpuid(1, &eax, &ebx, &ecx, &edx);
kusano 2b45e8
kusano 2b45e8
  family   = BITMASK(eax,  8, 0x0f);
kusano 2b45e8
  exfamily = BITMASK(eax, 20, 0xff);
kusano 2b45e8
  model    = BITMASK(eax,  4, 0x0f);
kusano 2b45e8
  exmodel  = BITMASK(eax, 16, 0x0f);
kusano 2b45e8
kusano 2b45e8
  vendor = get_vendor();
kusano 2b45e8
kusano 2b45e8
  if (vendor == VENDOR_INTEL){
kusano 2b45e8
    switch (family) {
kusano 2b45e8
    case 0x6:
kusano 2b45e8
      switch (exmodel) {
kusano 2b45e8
      case 0:
kusano 2b45e8
	if (model <= 0x7) return &gotoblas_KATMAI;
kusano 2b45e8
	if ((model == 0x8) || (model == 0xa) || (model == 0xb)) return &gotoblas_COPPERMINE;
kusano 2b45e8
	if ((model == 0x9) || (model == 0xd)) return &gotoblas_BANIAS;
kusano 2b45e8
	if (model == 14) return &gotoblas_BANIAS;
kusano 2b45e8
	if (model == 15) return &gotoblas_CORE2;
kusano 2b45e8
	return NULL;
kusano 2b45e8
kusano 2b45e8
      case 1:
kusano 2b45e8
	if (model == 6) return &gotoblas_CORE2;
kusano 2b45e8
	if (model == 7) return &gotoblas_PENRYN;
kusano 2b45e8
	if (model == 13) return &gotoblas_DUNNINGTON;
kusano 2b45e8
	if ((model == 10) || (model == 11) || (model == 14) || (model == 15)) return &gotoblas_NEHALEM;
kusano 2b45e8
	if (model == 12) return &gotoblas_ATOM;
kusano 2b45e8
	return NULL;
kusano 2b45e8
kusano 2b45e8
	  case 2:
kusano 2b45e8
		  //Intel Core (Clarkdale) / Core (Arrandale)
kusano 2b45e8
		  // Pentium (Clarkdale) / Pentium Mobile (Arrandale)
kusano 2b45e8
		  // Xeon (Clarkdale), 32nm
kusano 2b45e8
		  if (model ==  5) return &gotoblas_NEHALEM;
kusano 2b45e8
		  
kusano 2b45e8
		  //Intel Xeon Processor 5600 (Westmere-EP)
kusano 2b45e8
		  if (model == 12) return &gotoblas_NEHALEM;
kusano 2b45e8
		  return NULL;
kusano 2b45e8
      }
kusano 2b45e8
      case 0xf:
kusano 2b45e8
      if (model <= 0x2) return &gotoblas_NORTHWOOD;
kusano 2b45e8
      return &gotoblas_PRESCOTT;
kusano 2b45e8
    }
kusano 2b45e8
  }
kusano 2b45e8
kusano 2b45e8
  if (vendor == VENDOR_AMD){
kusano 2b45e8
    if (family <= 0xe) return &gotoblas_ATHLON;
kusano 2b45e8
    if (family == 0xf){
kusano 2b45e8
      if ((exfamily == 0) || (exfamily == 2)) {
kusano 2b45e8
	if (ecx & (1 <<  0)) return &gotoblas_OPTERON_SSE3; 
kusano 2b45e8
	else return &gotoblas_OPTERON;
kusano 2b45e8
      }  else {
kusano 2b45e8
	return &gotoblas_BARCELONA;
kusano 2b45e8
      }
kusano 2b45e8
    }
kusano 2b45e8
  }
kusano 2b45e8
kusano 2b45e8
  if (vendor == VENDOR_CENTAUR) {
kusano 2b45e8
    switch (family) {
kusano 2b45e8
    case 0x6:
kusano 2b45e8
      return &gotoblas_NANO;
kusano 2b45e8
      break;
kusano 2b45e8
    }
kusano 2b45e8
  }
kusano 2b45e8
  
kusano 2b45e8
  return NULL;
kusano 2b45e8
}
kusano 2b45e8
kusano 2b45e8
static char *corename[] = {
kusano 2b45e8
    "Unknown",
kusano 2b45e8
    "Katmai",
kusano 2b45e8
    "Coppermine",
kusano 2b45e8
    "Northwood",
kusano 2b45e8
    "Prescott",
kusano 2b45e8
    "Banias",
kusano 2b45e8
    "Atom",
kusano 2b45e8
    "Core2",
kusano 2b45e8
    "Penryn",
kusano 2b45e8
    "Dunnington",
kusano 2b45e8
    "Nehalem",
kusano 2b45e8
    "Athlon",
kusano 2b45e8
    "Opteron",
kusano 2b45e8
    "Opteron(SSE3)",
kusano 2b45e8
    "Barcelona",
kusano 2b45e8
    "Nano",
kusano 2b45e8
};
kusano 2b45e8
kusano 2b45e8
char *gotoblas_corename(void) {
kusano 2b45e8
kusano 2b45e8
  if (gotoblas == &gotoblas_KATMAI)       return corename[ 1];
kusano 2b45e8
  if (gotoblas == &gotoblas_COPPERMINE)   return corename[ 2];
kusano 2b45e8
  if (gotoblas == &gotoblas_NORTHWOOD)    return corename[ 3];
kusano 2b45e8
  if (gotoblas == &gotoblas_PRESCOTT)     return corename[ 4];
kusano 2b45e8
  if (gotoblas == &gotoblas_BANIAS)       return corename[ 5];
kusano 2b45e8
  if (gotoblas == &gotoblas_ATOM)         return corename[ 6];
kusano 2b45e8
  if (gotoblas == &gotoblas_CORE2)        return corename[ 7];
kusano 2b45e8
  if (gotoblas == &gotoblas_PENRYN)       return corename[ 8];
kusano 2b45e8
  if (gotoblas == &gotoblas_DUNNINGTON)   return corename[ 9];
kusano 2b45e8
  if (gotoblas == &gotoblas_NEHALEM)      return corename[10];
kusano 2b45e8
  if (gotoblas == &gotoblas_ATHLON)       return corename[11];
kusano 2b45e8
  if (gotoblas == &gotoblas_OPTERON_SSE3) return corename[12]; 
kusano 2b45e8
  if (gotoblas == &gotoblas_OPTERON)      return corename[13];
kusano 2b45e8
  if (gotoblas == &gotoblas_BARCELONA)    return corename[14];
kusano 2b45e8
  if (gotoblas == &gotoblas_NANO)         return corename[15];
kusano 2b45e8
  
kusano 2b45e8
  return corename[0];
kusano 2b45e8
}
kusano 2b45e8
kusano 2b45e8
void gotoblas_dynamic_init(void) {
kusano 2b45e8
  
kusano 2b45e8
  if (gotoblas) return;
kusano 2b45e8
kusano 2b45e8
  gotoblas = get_coretype();
kusano 2b45e8
  
kusano 2b45e8
#ifdef ARCH_X86
kusano 2b45e8
  if (gotoblas == NULL) gotoblas = &gotoblas_KATMAI;
kusano 2b45e8
#else
kusano 2b45e8
  if (gotoblas == NULL) gotoblas = &gotoblas_PRESCOTT;
kusano 2b45e8
#endif
kusano 2b45e8
  
kusano 2b45e8
  if (gotoblas && gotoblas -> init) {
kusano 2b45e8
    gotoblas -> init();
kusano 2b45e8
  } else {
kusano 2b45e8
    fprintf(stderr, "GotoBLAS : Architecture Initialization failed. No initialization function found.\n");
kusano 2b45e8
    exit(1);
kusano 2b45e8
  }
kusano 2b45e8
  
kusano 2b45e8
}
kusano 2b45e8
kusano 2b45e8
void gotoblas_dynamic_quit(void) {
kusano 2b45e8
  
kusano 2b45e8
  gotoblas = NULL;
kusano 2b45e8
kusano 2b45e8
}