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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [rs6000/] [driver-rs6000.c] - Blame information for rev 718

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

Line No. Rev Author Line
1 709 jeremybenn
/* Subroutines for the gcc driver.
2
   Copyright (C) 2007, 2008, 2009 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
#ifdef _AIX
27
# include <sys/systemcfg.h>
28
#endif
29
 
30
#ifdef __linux__
31
# include <link.h>
32
#endif
33
 
34
#if defined (__APPLE__) || (__FreeBSD__)
35
# include <sys/types.h>
36
# include <sys/sysctl.h>
37
#endif
38
 
39
const char *host_detect_local_cpu (int argc, const char **argv);
40
 
41
#if GCC_VERSION >= 0
42
 
43
/* Returns parameters that describe L1_ASSOC associative cache of size
44
   L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB.  */
45
 
46
static char *
47
describe_cache (unsigned l1_sizekb, unsigned l1_line,
48
                unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
49
{
50
  char l1size[1000], line[1000], l2size[1000];
51
 
52
  /* At the moment, gcc middle-end does not use the information about the
53
     associativity of the cache.  */
54
 
55
  sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb);
56
  sprintf (line, "--param l1-cache-line-size=%u", l1_line);
57
  sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb);
58
 
59
  return concat (l1size, " ", line, " ", l2size, " ", NULL);
60
}
61
 
62
#ifdef __APPLE__
63
 
64
/* Returns the description of caches on Darwin.  */
65
 
66
static char *
67
detect_caches_darwin (void)
68
{
69
  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
70
  size_t len = 4;
71
  static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE };
72
  static int l1_line_name[2] = { CTL_HW, HW_CACHELINE };
73
  static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE };
74
 
75
  sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0);
76
  sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0);
77
  sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0);
78
  l1_assoc = 0;
79
 
80
  return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc,
81
                         l2_sizekb / 1024);
82
}
83
 
84
static const char *
85
detect_processor_darwin (void)
86
{
87
  unsigned int proc;
88
  size_t len = 4;
89
 
90
  sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0);
91
 
92
  if (len > 0)
93
    switch (proc)
94
      {
95
      case 1:
96
        return "601";
97
      case 2:
98
        return "602";
99
      case 3:
100
        return "603";
101
      case 4:
102
      case 5:
103
        return "603e";
104
      case 6:
105
        return "604";
106
      case 7:
107
        return "604e";
108
      case 8:
109
        return "620";
110
      case 9:
111
        return "750";
112
      case 10:
113
        return "7400";
114
      case 11:
115
        return "7450";
116
      case 100:
117
        return "970";
118
      default:
119
        return "powerpc";
120
      }
121
 
122
  return "powerpc";
123
}
124
 
125
#endif /* __APPLE__ */
126
 
127
#ifdef __FreeBSD__
128
 
129
/* Returns the description of caches on FreeBSD PPC.  */
130
 
131
static char *
132
detect_caches_freebsd (void)
133
{
134
  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
135
  size_t len = 4;
136
 
137
  /* Currently, as of FreeBSD-7.0, there is only the cacheline_size
138
     available via sysctl.  */
139
  sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0);
140
 
141
  l1_sizekb = 32;
142
  l1_assoc = 0;
143
  l2_sizekb = 512;
144
 
145
  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
146
}
147
 
148
/* Currently returns default powerpc.  */
149
static const char *
150
detect_processor_freebsd (void)
151
{
152
  return "powerpc";
153
}
154
 
155
#endif /* __FreeBSD__  */
156
 
157
#ifdef __linux__
158
 
159
/* Returns AT_PLATFORM if present, otherwise generic PowerPC.  */
160
 
161
static const char *
162
elf_platform (void)
163
{
164
  int fd;
165
 
166
  fd = open ("/proc/self/auxv", O_RDONLY);
167
 
168
  if (fd != -1)
169
    {
170
      char buf[1024];
171
      ElfW(auxv_t) *av;
172
      ssize_t n;
173
 
174
      n = read (fd, buf, sizeof (buf));
175
      close (fd);
176
 
177
      if (n > 0)
178
        {
179
          for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
180
            switch (av->a_type)
181
              {
182
              case AT_PLATFORM:
183
                return (const char *) av->a_un.a_val;
184
 
185
              default:
186
                break;
187
              }
188
        }
189
    }
190
  return NULL;
191
}
192
 
193
/* Returns AT_PLATFORM if present, otherwise generic 32.  */
194
 
195
static int
196
elf_dcachebsize (void)
197
{
198
  int fd;
199
 
200
  fd = open ("/proc/self/auxv", O_RDONLY);
201
 
202
  if (fd != -1)
203
    {
204
      char buf[1024];
205
      ElfW(auxv_t) *av;
206
      ssize_t n;
207
 
208
      n = read (fd, buf, sizeof (buf));
209
      close (fd);
210
 
211
      if (n > 0)
212
        {
213
          for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
214
            switch (av->a_type)
215
              {
216
              case AT_DCACHEBSIZE:
217
                return av->a_un.a_val;
218
 
219
              default:
220
                break;
221
              }
222
        }
223
    }
224
  return 32;
225
}
226
 
227
/* Returns the description of caches on Linux.  */
228
 
229
static char *
230
detect_caches_linux (void)
231
{
232
  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
233
  const char *platform;
234
 
235
  platform = elf_platform ();
236
 
237
  if (platform != NULL)
238
    {
239
      l1_line = 128;
240
 
241
      if (platform[5] == '6')
242
        /* POWER6 and POWER6x */
243
        l1_sizekb = 64;
244
      else
245
        l1_sizekb = 32;
246
    }
247
  else
248
    {
249
      l1_line = elf_dcachebsize ();
250
      l1_sizekb = 32;
251
    }
252
 
253
  l1_assoc = 0;
254
  l2_sizekb = 512;
255
 
256
  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
257
}
258
 
259
static const char *
260
detect_processor_linux (void)
261
{
262
  const char *platform;
263
 
264
  platform = elf_platform ();
265
 
266
  if (platform != NULL)
267
    return platform;
268
  else
269
    return "powerpc";
270
}
271
 
272
#endif /* __linux__ */
273
 
274
#ifdef _AIX
275
/* Returns the description of caches on AIX.  */
276
 
277
static char *
278
detect_caches_aix (void)
279
{
280
  unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb;
281
 
282
  l1_sizekb = _system_configuration.dcache_size / 1024;
283
  l1_line = _system_configuration.dcache_line;
284
  l1_assoc = _system_configuration.dcache_asc;
285
  l2_sizekb = _system_configuration.L2_cache_size / 1024;
286
 
287
  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
288
}
289
 
290
 
291
/* Returns the processor implementation on AIX.  */
292
 
293
static const char *
294
detect_processor_aix (void)
295
{
296
  switch (_system_configuration.implementation)
297
    {
298
    case 0x0001:
299
      return "rios1";
300
 
301
    case 0x0002:
302
      return "rsc";
303
 
304
    case 0x0004:
305
      return "rios2";
306
 
307
    case 0x0008:
308
      return "601";
309
 
310
    case 0x0020:
311
      return "603";
312
 
313
    case 0x0010:
314
      return "604";
315
 
316
    case 0x0040:
317
      return "620";
318
 
319
    case 0x0080:
320
      return "630";
321
 
322
    case 0x0100:
323
    case 0x0200:
324
    case 0x0400:
325
      return "rs64";
326
 
327
    case 0x0800:
328
      return "power4";
329
 
330
    case 0x2000:
331
      if (_system_configuration.version == 0x0F0000)
332
        return "power5";
333
      else
334
        return "power5+";
335
 
336
    case 0x4000:
337
      return "power6";
338
 
339
    default:
340
      return "powerpc";
341
    }
342
}
343
#endif /* _AIX */
344
 
345
 
346
/*
347
 * Array to map -mcpu=native names to the switches passed to the assembler.
348
 * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here
349
 * should be made there as well.
350
 */
351
 
352
struct asm_name {
353
  const char *cpu;
354
  const char *asm_sw;
355
};
356
 
357
static const struct asm_name asm_names[] = {
358
#if defined (_AIX)
359
  { "power3",   "-m620" },
360
  { "power4",   "-mpwr4" },
361
  { "power5",   "-mpwr5" },
362
  { "power5+",  "-mpwr5x" },
363
  { "power6",   "-mpwr6" },
364
  { "power6x",  "-mpwr6" },
365
  { "power7",   "-mpwr7" },
366
  { "powerpc",  "-mppc" },
367
  { "rs64a",    "-mppc" },
368
  { "603",      "-m603" },
369
  { "603e",     "-m603" },
370
  { "604",      "-m604" },
371
  { "604e",     "-m604" },
372
  { "620",      "-m620" },
373
  { "630",      "-m620" },
374
  { "970",      "-m970" },
375
  { "G5",       "-m970" },
376
  { NULL,       "\
377
%{!maix64: \
378
%{mpowerpc64: -mppc64} \
379
%{maltivec: -m970} \
380
%{!maltivec: %{!mpower64: %(asm_default)}}}" },
381
 
382
#else
383
  { "common",   "-mcom" },
384
  { "cell",     "-mcell" },
385
  { "power",    "-mpwr" },
386
  { "power2",   "-mpwrx" },
387
  { "power3",   "-mppc64" },
388
  { "power4",   "-mpower4" },
389
  { "power5",   "%(asm_cpu_power5)" },
390
  { "power5+",  "%(asm_cpu_power5)" },
391
  { "power6",   "%(asm_cpu_power6) -maltivec" },
392
  { "power6x",  "%(asm_cpu_power6) -maltivec" },
393
  { "power7",   "%(asm_cpu_power7)" },
394
  { "powerpc",  "-mppc" },
395
  { "rios",     "-mpwr" },
396
  { "rios1",    "-mpwr" },
397
  { "rios2",    "-mpwrx" },
398
  { "rsc",      "-mpwr" },
399
  { "rsc1",     "-mpwr" },
400
  { "rs64a",    "-mppc64" },
401
  { "401",      "-mppc" },
402
  { "403",      "-m403" },
403
  { "405",      "-m405" },
404
  { "405fp",    "-m405" },
405
  { "440",      "-m440" },
406
  { "440fp",    "-m440" },
407
  { "464",      "-m440" },
408
  { "464fp",    "-m440" },
409
  { "505",      "-mppc" },
410
  { "601",      "-m601" },
411
  { "602",      "-mppc" },
412
  { "603",      "-mppc" },
413
  { "603e",     "-mppc" },
414
  { "ec603e",   "-mppc" },
415
  { "604",      "-mppc" },
416
  { "604e",     "-mppc" },
417
  { "620",      "-mppc64" },
418
  { "630",      "-mppc64" },
419
  { "740",      "-mppc" },
420
  { "750",      "-mppc" },
421
  { "G3",       "-mppc" },
422
  { "7400",     "-mppc -maltivec" },
423
  { "7450",     "-mppc -maltivec" },
424
  { "G4",       "-mppc -maltivec" },
425
  { "801",      "-mppc" },
426
  { "821",      "-mppc" },
427
  { "823",      "-mppc" },
428
  { "860",      "-mppc" },
429
  { "970",      "-mpower4 -maltivec" },
430
  { "G5",       "-mpower4 -maltivec" },
431
  { "8540",     "-me500" },
432
  { "8548",     "-me500" },
433
  { "e300c2",   "-me300" },
434
  { "e300c3",   "-me300" },
435
  { "e500mc",   "-me500mc" },
436
  { NULL,       "\
437
%{mpower: %{!mpower2: -mpwr}} \
438
%{mpower2: -mpwrx} \
439
%{mpowerpc64*: -mppc64} \
440
%{!mpowerpc64*: %{mpowerpc*: -mppc}} \
441
%{mno-power: %{!mpowerpc*: -mcom}} \
442
%{!mno-power: %{!mpower*: %(asm_default)}}" },
443
#endif
444
};
445
 
446
/* This will be called by the spec parser in gcc.c when it sees
447
   a %:local_cpu_detect(args) construct.  Currently it will be called
448
   with either "arch" or "tune" as argument depending on if -march=native
449
   or -mtune=native is to be substituted.
450
 
451
   Additionally it will be called with "asm" to select the appropriate flags
452
   for the assembler.
453
 
454
   It returns a string containing new command line parameters to be
455
   put at the place of the above two options, depending on what CPU
456
   this is executed.
457
 
458
   ARGC and ARGV are set depending on the actual arguments given
459
   in the spec.  */
460
const char *
461
host_detect_local_cpu (int argc, const char **argv)
462
{
463
  const char *cpu = NULL;
464
  const char *cache = "";
465
  const char *options = "";
466
  bool arch;
467
  bool assembler;
468
  size_t i;
469
 
470
  if (argc < 1)
471
    return NULL;
472
 
473
  arch = strcmp (argv[0], "cpu") == 0;
474
  assembler = (!arch && strcmp (argv[0], "asm") == 0);
475
  if (!arch && !assembler && strcmp (argv[0], "tune"))
476
    return NULL;
477
 
478
  if (! assembler)
479
    {
480
#if defined (_AIX)
481
      cache = detect_caches_aix ();
482
#elif defined (__APPLE__)
483
      cache = detect_caches_darwin ();
484
#elif defined (__FreeBSD__)
485
      cache = detect_caches_freebsd ();
486
      /* FreeBSD PPC does not provide any cache information yet.  */
487
      cache = "";
488
#elif defined (__linux__)
489
      cache = detect_caches_linux ();
490
      /* PPC Linux does not provide any cache information yet.  */
491
      cache = "";
492
#else
493
      cache = "";
494
#endif
495
    }
496
 
497
#if defined (_AIX)
498
  cpu = detect_processor_aix ();
499
#elif defined (__APPLE__)
500
  cpu = detect_processor_darwin ();
501
#elif defined (__FreeBSD__)
502
  cpu = detect_processor_freebsd ();
503
#elif defined (__linux__)
504
  cpu = detect_processor_linux ();
505
#else
506
  cpu = "powerpc";
507
#endif
508
 
509
  if (assembler)
510
    {
511
      for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++)
512
        {
513
          if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu))
514
            return asm_names[i].asm_sw;
515
        }
516
 
517
      return NULL;
518
    }
519
 
520
  return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
521
}
522
 
523
#else /* GCC_VERSION */
524
 
525
/* If we aren't compiling with GCC we just provide a minimal
526
   default value.  */
527
const char *
528
host_detect_local_cpu (int argc, const char **argv)
529
{
530
  const char *cpu;
531
  bool arch;
532
 
533
  if (argc < 1)
534
    return NULL;
535
 
536
  arch = strcmp (argv[0], "cpu") == 0;
537
  if (!arch && strcmp (argv[0], "tune"))
538
    return NULL;
539
 
540
  if (arch)
541
    cpu = "powerpc";
542
 
543
  return concat ("-m", argv[0], "=", cpu, NULL);
544
}
545
 
546
#endif /* GCC_VERSION */
547
 

powered by: WebSVN 2.1.0

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