OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [i386/] [driver-i386.c] - Diff between revs 154 and 816

Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
/* Subroutines for the gcc driver.
/* Subroutines for the gcc driver.
   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
the Free Software Foundation; either version 3, or (at your option)
any later version.
any later version.
 
 
GCC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include <stdlib.h>
#include <stdlib.h>
 
 
const char *host_detect_local_cpu (int argc, const char **argv);
const char *host_detect_local_cpu (int argc, const char **argv);
 
 
#ifdef GCC_VERSION
#ifdef GCC_VERSION
#define cpuid(num,a,b,c,d) \
#define cpuid(num,a,b,c,d) \
  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
                : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
                : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
                : "0" (num))
                : "0" (num))
 
 
#define bit_CMPXCHG8B (1 << 8)
#define bit_CMPXCHG8B (1 << 8)
#define bit_CMOV (1 << 15)
#define bit_CMOV (1 << 15)
#define bit_MMX (1 << 23)
#define bit_MMX (1 << 23)
#define bit_SSE (1 << 25)
#define bit_SSE (1 << 25)
#define bit_SSE2 (1 << 26)
#define bit_SSE2 (1 << 26)
 
 
#define bit_SSE3 (1 << 0)
#define bit_SSE3 (1 << 0)
#define bit_CMPXCHG16B (1 << 13)
#define bit_CMPXCHG16B (1 << 13)
 
 
#define bit_3DNOW (1 << 31)
#define bit_3DNOW (1 << 31)
#define bit_3DNOWP (1 << 30)
#define bit_3DNOWP (1 << 30)
#define bit_LM (1 << 29)
#define bit_LM (1 << 29)
 
 
/* This will be called by the spec parser in gcc.c when it sees
/* This will be called by the spec parser in gcc.c when it sees
   a %:local_cpu_detect(args) construct.  Currently it will be called
   a %:local_cpu_detect(args) construct.  Currently it will be called
   with either "arch" or "tune" as argument depending on if -march=native
   with either "arch" or "tune" as argument depending on if -march=native
   or -mtune=native is to be substituted.
   or -mtune=native is to be substituted.
 
 
   It returns a string containing new command line parameters to be
   It returns a string containing new command line parameters to be
   put at the place of the above two options, depending on what CPU
   put at the place of the above two options, depending on what CPU
   this is executed.  E.g. "-march=k8" on an AMD64 machine
   this is executed.  E.g. "-march=k8" on an AMD64 machine
   for -march=native.
   for -march=native.
 
 
   ARGC and ARGV are set depending on the actual arguments given
   ARGC and ARGV are set depending on the actual arguments given
   in the spec.  */
   in the spec.  */
const char *host_detect_local_cpu (int argc, const char **argv)
const char *host_detect_local_cpu (int argc, const char **argv)
{
{
  const char *cpu = NULL;
  const char *cpu = NULL;
  enum processor_type processor = PROCESSOR_I386;
  enum processor_type processor = PROCESSOR_I386;
  unsigned int eax, ebx, ecx, edx;
  unsigned int eax, ebx, ecx, edx;
  unsigned int max_level;
  unsigned int max_level;
  unsigned int vendor;
  unsigned int vendor;
  unsigned int ext_level;
  unsigned int ext_level;
  unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0;
  unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0;
  unsigned char has_sse2 = 0, has_sse3 = 0, has_cmov = 0;
  unsigned char has_sse2 = 0, has_sse3 = 0, has_cmov = 0;
  unsigned char has_longmode = 0, has_cmpxchg8b = 0;
  unsigned char has_longmode = 0, has_cmpxchg8b = 0;
  unsigned char is_amd = 0;
  unsigned char is_amd = 0;
  unsigned int family = 0;
  unsigned int family = 0;
  bool arch;
  bool arch;
 
 
  if (argc < 1)
  if (argc < 1)
    return NULL;
    return NULL;
 
 
  arch = strcmp (argv[0], "arch") == 0;
  arch = strcmp (argv[0], "arch") == 0;
  if (!arch && strcmp (argv[0], "tune"))
  if (!arch && strcmp (argv[0], "tune"))
    return NULL;
    return NULL;
 
 
#ifndef __x86_64__
#ifndef __x86_64__
  /* See if we can use cpuid.  */
  /* See if we can use cpuid.  */
  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
                "pushl %0; popfl; pushfl; popl %0; popfl"
                "pushl %0; popfl; pushfl; popl %0; popfl"
                : "=&r" (eax), "=&r" (ebx)
                : "=&r" (eax), "=&r" (ebx)
                : "i" (0x00200000));
                : "i" (0x00200000));
 
 
  if (((eax ^ ebx) & 0x00200000) == 0)
  if (((eax ^ ebx) & 0x00200000) == 0)
    goto done;
    goto done;
#endif
#endif
 
 
  processor = PROCESSOR_PENTIUM;
  processor = PROCESSOR_PENTIUM;
 
 
  /* Check the highest input value for eax.  */
  /* Check the highest input value for eax.  */
  cpuid (0, eax, ebx, ecx, edx);
  cpuid (0, eax, ebx, ecx, edx);
  max_level = eax;
  max_level = eax;
  /* We only look at the first four characters.  */
  /* We only look at the first four characters.  */
  vendor = ebx;
  vendor = ebx;
  if (max_level == 0)
  if (max_level == 0)
    goto done;
    goto done;
 
 
  cpuid (1, eax, ebx, ecx, edx);
  cpuid (1, eax, ebx, ecx, edx);
  has_cmpxchg8b = !!(edx & bit_CMPXCHG8B);
  has_cmpxchg8b = !!(edx & bit_CMPXCHG8B);
  has_cmov = !!(edx & bit_CMOV);
  has_cmov = !!(edx & bit_CMOV);
  has_mmx = !!(edx & bit_MMX);
  has_mmx = !!(edx & bit_MMX);
  has_sse = !!(edx & bit_SSE);
  has_sse = !!(edx & bit_SSE);
  has_sse2 = !!(edx & bit_SSE2);
  has_sse2 = !!(edx & bit_SSE2);
  has_sse3 = !!(ecx & bit_SSE3);
  has_sse3 = !!(ecx & bit_SSE3);
  /* We don't care for extended family.  */
  /* We don't care for extended family.  */
  family = (eax >> 8) & ~(1 << 4);
  family = (eax >> 8) & ~(1 << 4);
 
 
  cpuid (0x80000000, eax, ebx, ecx, edx);
  cpuid (0x80000000, eax, ebx, ecx, edx);
  ext_level = eax;
  ext_level = eax;
  if (ext_level >= 0x80000000)
  if (ext_level >= 0x80000000)
    {
    {
      cpuid (0x80000001, eax, ebx, ecx, edx);
      cpuid (0x80000001, eax, ebx, ecx, edx);
      has_3dnow = !!(edx & bit_3DNOW);
      has_3dnow = !!(edx & bit_3DNOW);
      has_3dnowp = !!(edx & bit_3DNOWP);
      has_3dnowp = !!(edx & bit_3DNOWP);
      has_longmode = !!(edx & bit_LM);
      has_longmode = !!(edx & bit_LM);
    }
    }
 
 
  is_amd = vendor == *(unsigned int*)"Auth";
  is_amd = vendor == *(unsigned int*)"Auth";
 
 
  if (is_amd)
  if (is_amd)
    {
    {
      if (has_mmx)
      if (has_mmx)
        processor = PROCESSOR_K6;
        processor = PROCESSOR_K6;
      if (has_3dnowp)
      if (has_3dnowp)
        processor = PROCESSOR_ATHLON;
        processor = PROCESSOR_ATHLON;
      if (has_sse2 || has_longmode)
      if (has_sse2 || has_longmode)
        processor = PROCESSOR_K8;
        processor = PROCESSOR_K8;
    }
    }
  else
  else
    {
    {
      switch (family)
      switch (family)
        {
        {
        case 5:
        case 5:
          /* Default is PROCESSOR_PENTIUM.  */
          /* Default is PROCESSOR_PENTIUM.  */
          break;
          break;
        case 6:
        case 6:
          processor = PROCESSOR_PENTIUMPRO;
          processor = PROCESSOR_PENTIUMPRO;
          break;
          break;
        case 15:
        case 15:
          processor = PROCESSOR_PENTIUM4;
          processor = PROCESSOR_PENTIUM4;
          break;
          break;
        default:
        default:
          /* We have no idea.  Use something reasonable.  */
          /* We have no idea.  Use something reasonable.  */
          if (arch)
          if (arch)
            {
            {
              if (has_sse3)
              if (has_sse3)
                {
                {
                  if (has_longmode)
                  if (has_longmode)
                    cpu = "nocona";
                    cpu = "nocona";
                  else
                  else
                    cpu = "prescott";
                    cpu = "prescott";
                }
                }
              else if (has_sse2)
              else if (has_sse2)
                cpu = "pentium4";
                cpu = "pentium4";
              else if (has_cmov)
              else if (has_cmov)
                cpu = "pentiumpro";
                cpu = "pentiumpro";
              else if (has_mmx)
              else if (has_mmx)
                cpu = "pentium-mmx";
                cpu = "pentium-mmx";
              else if (has_cmpxchg8b)
              else if (has_cmpxchg8b)
                cpu = "pentium";
                cpu = "pentium";
              else
              else
                cpu = "i386";
                cpu = "i386";
            }
            }
          else
          else
            cpu = "generic";
            cpu = "generic";
          goto done;
          goto done;
          break;
          break;
        }
        }
    }
    }
 
 
  switch (processor)
  switch (processor)
    {
    {
    case PROCESSOR_I386:
    case PROCESSOR_I386:
      cpu = "i386";
      cpu = "i386";
      break;
      break;
    case PROCESSOR_I486:
    case PROCESSOR_I486:
      cpu = "i486";
      cpu = "i486";
      break;
      break;
    case PROCESSOR_PENTIUM:
    case PROCESSOR_PENTIUM:
      if (has_mmx)
      if (has_mmx)
        cpu = "pentium-mmx";
        cpu = "pentium-mmx";
      else
      else
        cpu = "pentium";
        cpu = "pentium";
      break;
      break;
    case PROCESSOR_PENTIUMPRO:
    case PROCESSOR_PENTIUMPRO:
      if (arch)
      if (arch)
        {
        {
          if (has_sse3)
          if (has_sse3)
            {
            {
              if (has_longmode)
              if (has_longmode)
                {
                {
                  /* It is Core 2 Duo.  */
                  /* It is Core 2 Duo.  */
                  cpu = "nocona";
                  cpu = "nocona";
                }
                }
              else
              else
                {
                {
                  /* It is Core Duo.  */
                  /* It is Core Duo.  */
                  cpu = "prescott";
                  cpu = "prescott";
                }
                }
            }
            }
          else if (has_sse2)
          else if (has_sse2)
            {
            {
              /* It is Pentium M.  */
              /* It is Pentium M.  */
              cpu = "pentium4";
              cpu = "pentium4";
            }
            }
          else if (has_sse)
          else if (has_sse)
            {
            {
              /* It is Pentium III.  */
              /* It is Pentium III.  */
              cpu = "pentium3";
              cpu = "pentium3";
            }
            }
          else if (has_mmx)
          else if (has_mmx)
            {
            {
              /* It is Pentium II.  */
              /* It is Pentium II.  */
              cpu = "pentium2";
              cpu = "pentium2";
            }
            }
          else
          else
            {
            {
              /* Default to Pentium Pro.  */
              /* Default to Pentium Pro.  */
              cpu = "pentiumpro";
              cpu = "pentiumpro";
            }
            }
        }
        }
      else
      else
        {
        {
          /* For -mtune, we default to -mtune=generic.  */
          /* For -mtune, we default to -mtune=generic.  */
          cpu = "generic";
          cpu = "generic";
        }
        }
      break;
      break;
    case PROCESSOR_K6:
    case PROCESSOR_K6:
      if (has_3dnow)
      if (has_3dnow)
        cpu = "k6-3";
        cpu = "k6-3";
      else
      else
        cpu = "k6";
        cpu = "k6";
      break;
      break;
    case PROCESSOR_ATHLON:
    case PROCESSOR_ATHLON:
      if (has_sse)
      if (has_sse)
        cpu = "athlon-4";
        cpu = "athlon-4";
      else
      else
        cpu = "athlon";
        cpu = "athlon";
      break;
      break;
    case PROCESSOR_PENTIUM4:
    case PROCESSOR_PENTIUM4:
      if (has_sse3)
      if (has_sse3)
        {
        {
          if (has_longmode)
          if (has_longmode)
            cpu = "nocona";
            cpu = "nocona";
          else
          else
            cpu = "prescott";
            cpu = "prescott";
        }
        }
      else
      else
        cpu = "pentium4";
        cpu = "pentium4";
      break;
      break;
    case PROCESSOR_K8:
    case PROCESSOR_K8:
      cpu = "k8";
      cpu = "k8";
      break;
      break;
    case PROCESSOR_NOCONA:
    case PROCESSOR_NOCONA:
      cpu = "nocona";
      cpu = "nocona";
      break;
      break;
    case PROCESSOR_GENERIC32:
    case PROCESSOR_GENERIC32:
    case PROCESSOR_GENERIC64:
    case PROCESSOR_GENERIC64:
      cpu = "generic";
      cpu = "generic";
      break;
      break;
    default:
    default:
      abort ();
      abort ();
      break;
      break;
    }
    }
 
 
done:
done:
  return concat ("-m", argv[0], "=", cpu, NULL);
  return concat ("-m", argv[0], "=", cpu, NULL);
}
}
#else
#else
/* If we aren't compiling with GCC we just provide a minimal
/* If we aren't compiling with GCC we just provide a minimal
   default value.  */
   default value.  */
const char *host_detect_local_cpu (int argc, const char **argv)
const char *host_detect_local_cpu (int argc, const char **argv)
{
{
  const char *cpu;
  const char *cpu;
  bool arch;
  bool arch;
 
 
  if (argc < 1)
  if (argc < 1)
    return NULL;
    return NULL;
 
 
  arch = strcmp (argv[0], "arch") == 0;
  arch = strcmp (argv[0], "arch") == 0;
  if (!arch && strcmp (argv[0], "tune"))
  if (!arch && strcmp (argv[0], "tune"))
    return NULL;
    return NULL;
 
 
  if (arch)
  if (arch)
    {
    {
      /* FIXME: i386 is wrong for 64bit compiler.  How can we tell if
      /* FIXME: i386 is wrong for 64bit compiler.  How can we tell if
         we are generating 64bit or 32bit code?  */
         we are generating 64bit or 32bit code?  */
      cpu = "i386";
      cpu = "i386";
    }
    }
  else
  else
    cpu = "generic";
    cpu = "generic";
 
 
  return concat ("-m", argv[0], "=", cpu, NULL);
  return concat ("-m", argv[0], "=", cpu, NULL);
}
}
#endif /* GCC_VERSION */
#endif /* GCC_VERSION */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.