xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/arm/driver-arm.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* Subroutines for the gcc driver.
2    Copyright (C) 2011-2020 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 #define IN_TARGET_CODE 1
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "configargs.h"
27 
28 struct vendor_cpu
29 {
30   const char *part_no;
31   const char *arch_name;
32   const char *cpu_name;
33 };
34 
35 struct vendor
36 {
37   const char *vendor_no;
38   const struct vendor_cpu *vendor_parts;
39 };
40 
41 #include "arm-native.h"
42 
43 /* This will be called by the spec parser in gcc.c when it sees
44    a %:local_cpu_detect(args) construct.  Currently it will be called
45    with either "arch", "cpu" or "tune" as argument depending on if
46    -march=native, -mcpu=native or -mtune=native is to be substituted.
47 
48    It returns a string containing new command line parameters to be
49    put at the place of the above two options, depending on what CPU
50    this is executed.  E.g. "-march=armv7-a" on a Cortex-A8 for
51    -march=native.  If the routine can't detect a known processor,
52    the -march or -mtune option is discarded.
53 
54    ARGC and ARGV are set depending on the actual arguments given
55    in the spec.  */
56 const char *
host_detect_local_cpu(int argc,const char ** argv)57 host_detect_local_cpu (int argc, const char **argv)
58 {
59   const char *val = NULL;
60   char buf[128];
61   FILE *f = NULL;
62   bool arch;
63   const struct vendor_cpu *cpu_table = NULL;
64   char *fcpu_info = NULL;
65 
66   if (argc < 1)
67     goto not_found;
68 
69   arch = strcmp (argv[0], "arch") == 0;
70   if (!arch && strcmp (argv[0], "cpu") != 0 && strcmp (argv[0], "tune"))
71     goto not_found;
72 
73   fcpu_info = getenv ("GCC_CPUINFO");
74   if (fcpu_info)
75     f = fopen (fcpu_info, "r");
76   else
77     f = fopen ("/proc/cpuinfo", "r");
78 
79   if (f == NULL)
80     goto not_found;
81 
82   while (fgets (buf, sizeof (buf), f) != NULL)
83     {
84       /* Find the vendor table associated with this implementer.  */
85       if (strncmp (buf, "CPU implementer", sizeof ("CPU implementer") - 1) == 0)
86 	{
87 	  int i;
88 	  for (i = 0; vendors_table[i].vendor_no != NULL; i++)
89 	    if (strstr (buf, vendors_table[i].vendor_no) != NULL)
90 	      {
91 		cpu_table = vendors_table[i].vendor_parts;
92 		break;
93 	      }
94 	}
95 
96       /* Detect arch/cpu.  */
97       if (strncmp (buf, "CPU part", sizeof ("CPU part") - 1) == 0)
98 	{
99 	  int i;
100 
101 	  if (cpu_table == NULL)
102 	    goto not_found;
103 
104 	  for (i = 0; cpu_table[i].part_no != NULL; i++)
105 	    if (strstr (buf, cpu_table[i].part_no) != NULL)
106 	      {
107 		val = arch ? cpu_table[i].arch_name : cpu_table[i].cpu_name;
108 		break;
109 	      }
110 	  break;
111 	}
112     }
113 
114   if (val)
115     {
116       fclose (f);
117       return concat ("-m", argv[0], "=", val, NULL);
118      }
119 
120 not_found:
121   {
122     unsigned int i;
123     unsigned int opt;
124     const char *search[] = {NULL, "arch"};
125 
126     if (f)
127       fclose (f);
128 
129     search[0] = argv[0];
130     for (opt = 0; opt < ARRAY_SIZE (search); opt++)
131       for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
132 	if (strcmp (configure_default_options[i].name, search[opt]) == 0)
133 	  return concat ("-m", search[opt], "=",
134 			 configure_default_options[i].value, NULL);
135     return NULL;
136   }
137 }
138