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] - Blame information for rev 825

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Subroutines for the gcc driver.
2
   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3
 
4
This file is part of GCC.
5
 
6
GCC is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 3, or (at your option)
9
any later version.
10
 
11
GCC is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GCC; see the file COPYING3.  If not see
18
<http://www.gnu.org/licenses/>.  */
19
 
20
#include "config.h"
21
#include "system.h"
22
#include "coretypes.h"
23
#include "tm.h"
24
#include <stdlib.h>
25
 
26
const char *host_detect_local_cpu (int argc, const char **argv);
27
 
28
#ifdef GCC_VERSION
29
#define cpuid(num,a,b,c,d) \
30
  asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
31
                : "=a" (a), "=r" (b), "=c" (c), "=d" (d)  \
32
                : "0" (num))
33
 
34
#define bit_CMPXCHG8B (1 << 8)
35
#define bit_CMOV (1 << 15)
36
#define bit_MMX (1 << 23)
37
#define bit_SSE (1 << 25)
38
#define bit_SSE2 (1 << 26)
39
 
40
#define bit_SSE3 (1 << 0)
41
#define bit_CMPXCHG16B (1 << 13)
42
 
43
#define bit_3DNOW (1 << 31)
44
#define bit_3DNOWP (1 << 30)
45
#define bit_LM (1 << 29)
46
 
47
/* This will be called by the spec parser in gcc.c when it sees
48
   a %:local_cpu_detect(args) construct.  Currently it will be called
49
   with either "arch" or "tune" as argument depending on if -march=native
50
   or -mtune=native is to be substituted.
51
 
52
   It returns a string containing new command line parameters to be
53
   put at the place of the above two options, depending on what CPU
54
   this is executed.  E.g. "-march=k8" on an AMD64 machine
55
   for -march=native.
56
 
57
   ARGC and ARGV are set depending on the actual arguments given
58
   in the spec.  */
59
const char *host_detect_local_cpu (int argc, const char **argv)
60
{
61
  const char *cpu = NULL;
62
  enum processor_type processor = PROCESSOR_I386;
63
  unsigned int eax, ebx, ecx, edx;
64
  unsigned int max_level;
65
  unsigned int vendor;
66
  unsigned int ext_level;
67
  unsigned char has_mmx = 0, has_3dnow = 0, has_3dnowp = 0, has_sse = 0;
68
  unsigned char has_sse2 = 0, has_sse3 = 0, has_cmov = 0;
69
  unsigned char has_longmode = 0, has_cmpxchg8b = 0;
70
  unsigned char is_amd = 0;
71
  unsigned int family = 0;
72
  bool arch;
73
 
74
  if (argc < 1)
75
    return NULL;
76
 
77
  arch = strcmp (argv[0], "arch") == 0;
78
  if (!arch && strcmp (argv[0], "tune"))
79
    return NULL;
80
 
81
#ifndef __x86_64__
82
  /* See if we can use cpuid.  */
83
  asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
84
                "pushl %0; popfl; pushfl; popl %0; popfl"
85
                : "=&r" (eax), "=&r" (ebx)
86
                : "i" (0x00200000));
87
 
88
  if (((eax ^ ebx) & 0x00200000) == 0)
89
    goto done;
90
#endif
91
 
92
  processor = PROCESSOR_PENTIUM;
93
 
94
  /* Check the highest input value for eax.  */
95
  cpuid (0, eax, ebx, ecx, edx);
96
  max_level = eax;
97
  /* We only look at the first four characters.  */
98
  vendor = ebx;
99
  if (max_level == 0)
100
    goto done;
101
 
102
  cpuid (1, eax, ebx, ecx, edx);
103
  has_cmpxchg8b = !!(edx & bit_CMPXCHG8B);
104
  has_cmov = !!(edx & bit_CMOV);
105
  has_mmx = !!(edx & bit_MMX);
106
  has_sse = !!(edx & bit_SSE);
107
  has_sse2 = !!(edx & bit_SSE2);
108
  has_sse3 = !!(ecx & bit_SSE3);
109
  /* We don't care for extended family.  */
110
  family = (eax >> 8) & ~(1 << 4);
111
 
112
  cpuid (0x80000000, eax, ebx, ecx, edx);
113
  ext_level = eax;
114
  if (ext_level >= 0x80000000)
115
    {
116
      cpuid (0x80000001, eax, ebx, ecx, edx);
117
      has_3dnow = !!(edx & bit_3DNOW);
118
      has_3dnowp = !!(edx & bit_3DNOWP);
119
      has_longmode = !!(edx & bit_LM);
120
    }
121
 
122
  is_amd = vendor == *(unsigned int*)"Auth";
123
 
124
  if (is_amd)
125
    {
126
      if (has_mmx)
127
        processor = PROCESSOR_K6;
128
      if (has_3dnowp)
129
        processor = PROCESSOR_ATHLON;
130
      if (has_sse2 || has_longmode)
131
        processor = PROCESSOR_K8;
132
    }
133
  else
134
    {
135
      switch (family)
136
        {
137
        case 5:
138
          /* Default is PROCESSOR_PENTIUM.  */
139
          break;
140
        case 6:
141
          processor = PROCESSOR_PENTIUMPRO;
142
          break;
143
        case 15:
144
          processor = PROCESSOR_PENTIUM4;
145
          break;
146
        default:
147
          /* We have no idea.  Use something reasonable.  */
148
          if (arch)
149
            {
150
              if (has_sse3)
151
                {
152
                  if (has_longmode)
153
                    cpu = "nocona";
154
                  else
155
                    cpu = "prescott";
156
                }
157
              else if (has_sse2)
158
                cpu = "pentium4";
159
              else if (has_cmov)
160
                cpu = "pentiumpro";
161
              else if (has_mmx)
162
                cpu = "pentium-mmx";
163
              else if (has_cmpxchg8b)
164
                cpu = "pentium";
165
              else
166
                cpu = "i386";
167
            }
168
          else
169
            cpu = "generic";
170
          goto done;
171
          break;
172
        }
173
    }
174
 
175
  switch (processor)
176
    {
177
    case PROCESSOR_I386:
178
      cpu = "i386";
179
      break;
180
    case PROCESSOR_I486:
181
      cpu = "i486";
182
      break;
183
    case PROCESSOR_PENTIUM:
184
      if (has_mmx)
185
        cpu = "pentium-mmx";
186
      else
187
        cpu = "pentium";
188
      break;
189
    case PROCESSOR_PENTIUMPRO:
190
      if (arch)
191
        {
192
          if (has_sse3)
193
            {
194
              if (has_longmode)
195
                {
196
                  /* It is Core 2 Duo.  */
197
                  cpu = "nocona";
198
                }
199
              else
200
                {
201
                  /* It is Core Duo.  */
202
                  cpu = "prescott";
203
                }
204
            }
205
          else if (has_sse2)
206
            {
207
              /* It is Pentium M.  */
208
              cpu = "pentium4";
209
            }
210
          else if (has_sse)
211
            {
212
              /* It is Pentium III.  */
213
              cpu = "pentium3";
214
            }
215
          else if (has_mmx)
216
            {
217
              /* It is Pentium II.  */
218
              cpu = "pentium2";
219
            }
220
          else
221
            {
222
              /* Default to Pentium Pro.  */
223
              cpu = "pentiumpro";
224
            }
225
        }
226
      else
227
        {
228
          /* For -mtune, we default to -mtune=generic.  */
229
          cpu = "generic";
230
        }
231
      break;
232
    case PROCESSOR_K6:
233
      if (has_3dnow)
234
        cpu = "k6-3";
235
      else
236
        cpu = "k6";
237
      break;
238
    case PROCESSOR_ATHLON:
239
      if (has_sse)
240
        cpu = "athlon-4";
241
      else
242
        cpu = "athlon";
243
      break;
244
    case PROCESSOR_PENTIUM4:
245
      if (has_sse3)
246
        {
247
          if (has_longmode)
248
            cpu = "nocona";
249
          else
250
            cpu = "prescott";
251
        }
252
      else
253
        cpu = "pentium4";
254
      break;
255
    case PROCESSOR_K8:
256
      cpu = "k8";
257
      break;
258
    case PROCESSOR_NOCONA:
259
      cpu = "nocona";
260
      break;
261
    case PROCESSOR_GENERIC32:
262
    case PROCESSOR_GENERIC64:
263
      cpu = "generic";
264
      break;
265
    default:
266
      abort ();
267
      break;
268
    }
269
 
270
done:
271
  return concat ("-m", argv[0], "=", cpu, NULL);
272
}
273
#else
274
/* If we aren't compiling with GCC we just provide a minimal
275
   default value.  */
276
const char *host_detect_local_cpu (int argc, const char **argv)
277
{
278
  const char *cpu;
279
  bool arch;
280
 
281
  if (argc < 1)
282
    return NULL;
283
 
284
  arch = strcmp (argv[0], "arch") == 0;
285
  if (!arch && strcmp (argv[0], "tune"))
286
    return NULL;
287
 
288
  if (arch)
289
    {
290
      /* FIXME: i386 is wrong for 64bit compiler.  How can we tell if
291
         we are generating 64bit or 32bit code?  */
292
      cpu = "i386";
293
    }
294
  else
295
    cpu = "generic";
296
 
297
  return concat ("-m", argv[0], "=", cpu, NULL);
298
}
299
#endif /* GCC_VERSION */

powered by: WebSVN 2.1.0

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