1/* Subroutines for the gcc driver.
2   Copyright (C) 2008-2015 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along 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
25/* This will be called by the spec parser in gcc.c when it sees
26   a %:local_cpu_detect(args) construct.  Currently it will be called
27   with either "arch" or "tune" as argument depending on if -march=native
28   or -mtune=native is to be substituted.
29
30   It returns a string containing new command line parameters to be
31   put at the place of the above two options, depending on what CPU
32   this is executed.  E.g. "-march=loongson2f" on a Loongson 2F for
33   -march=native.  If the routine can't detect a known processor,
34   the -march or -mtune option is discarded.
35
36   ARGC and ARGV are set depending on the actual arguments given
37   in the spec.  */
38const char *
39host_detect_local_cpu (int argc, const char **argv)
40{
41  const char *cpu = NULL;
42  char buf[128];
43  FILE *f;
44  bool arch;
45
46  if (argc < 1)
47    return NULL;
48
49  arch = strcmp (argv[0], "arch") == 0;
50  if (!arch && strcmp (argv[0], "tune"))
51    return NULL;
52
53  f = fopen ("/proc/cpuinfo", "r");
54  if (f == NULL)
55    return NULL;
56
57  while (fgets (buf, sizeof (buf), f) != NULL)
58    if (strncmp (buf, "cpu model", sizeof ("cpu model") - 1) == 0)
59      {
60	if (strstr (buf, "Godson2 V0.2") != NULL
61	    || strstr (buf, "Loongson-2 V0.2") != NULL
62	    || strstr (buf, "Loongson-2E") != NULL)
63	  cpu = "loongson2e";
64	else if (strstr (buf, "Godson2 V0.3") != NULL
65		 || strstr (buf, "Loongson-2 V0.3") != NULL
66		 || strstr (buf, "Loongson-2F") != NULL)
67	  cpu = "loongson2f";
68	else if (strstr (buf, "Godson3 V0.5") != NULL
69		 || strstr (buf, "Loongson-3 V0.5") != NULL
70		 || strstr (buf, "Loongson-3A") != NULL)
71	  cpu = "loongson3a";
72	else if (strstr (buf, "SiByte SB1") != NULL)
73	  cpu = "sb1";
74	else if (strstr (buf, "R5000") != NULL)
75	  cpu = "r5000";
76	else if (strstr (buf, "Octeon II") != NULL)
77	  cpu = "octeon2";
78	else if (strstr (buf, "Octeon") != NULL)
79	  cpu = "octeon";
80	break;
81      }
82
83  fclose (f);
84
85  if (cpu == NULL)
86    return NULL;
87
88  return concat ("-m", argv[0], "=", cpu, NULL);
89}
90