annotate gcc/common/config/aarch64/aarch64-common.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Common hooks for AArch64.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by ARM Ltd.
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
kono
parents:
diff changeset
8 under the terms of the GNU General Public License as published
kono
parents:
diff changeset
9 by the Free Software Foundation; either version 3, or (at your
kono
parents:
diff changeset
10 option) any later version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT
kono
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
kono
parents:
diff changeset
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
kono
parents:
diff changeset
15 License for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 #include "config.h"
kono
parents:
diff changeset
22 #define INCLUDE_STRING
kono
parents:
diff changeset
23 #include "system.h"
kono
parents:
diff changeset
24 #include "coretypes.h"
kono
parents:
diff changeset
25 #include "tm.h"
kono
parents:
diff changeset
26 #include "memmodel.h"
kono
parents:
diff changeset
27 #include "tm_p.h"
kono
parents:
diff changeset
28 #include "common/common-target.h"
kono
parents:
diff changeset
29 #include "common/common-target-def.h"
kono
parents:
diff changeset
30 #include "opts.h"
kono
parents:
diff changeset
31 #include "flags.h"
kono
parents:
diff changeset
32 #include "diagnostic.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
33 #include "params.h"
111
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 #ifdef TARGET_BIG_ENDIAN_DEFAULT
kono
parents:
diff changeset
36 #undef TARGET_DEFAULT_TARGET_FLAGS
kono
parents:
diff changeset
37 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END)
kono
parents:
diff changeset
38 #endif
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 #undef TARGET_HANDLE_OPTION
kono
parents:
diff changeset
41 #define TARGET_HANDLE_OPTION aarch64_handle_option
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 #undef TARGET_OPTION_OPTIMIZATION_TABLE
kono
parents:
diff changeset
44 #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
45 #undef TARGET_OPTION_DEFAULT_PARAMS
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
46 #define TARGET_OPTION_DEFAULT_PARAMS aarch64_option_default_params
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 #undef TARGET_OPTION_VALIDATE_PARAM
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
48 #define TARGET_OPTION_VALIDATE_PARAM aarch64_option_validate_param
111
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 /* Set default optimization options. */
kono
parents:
diff changeset
51 static const struct default_options aarch_option_optimization_table[] =
kono
parents:
diff changeset
52 {
kono
parents:
diff changeset
53 /* Enable section anchors by default at -O1 or higher. */
kono
parents:
diff changeset
54 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 /* Disable fomit-frame-pointer by default. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 0 },
111
kono
parents:
diff changeset
57 /* Enable -fsched-pressure by default when optimizing. */
kono
parents:
diff changeset
58 { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
kono
parents:
diff changeset
59 /* Enable redundant extension instructions removal at -O2 and higher. */
kono
parents:
diff changeset
60 { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
61 #if (TARGET_DEFAULT_ASYNC_UNWIND_TABLES == 1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
62 { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 },
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
63 { OPT_LEVELS_ALL, OPT_funwind_tables, NULL, 1},
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
64 #endif
111
kono
parents:
diff changeset
65 { OPT_LEVELS_NONE, 0, NULL, 0 }
kono
parents:
diff changeset
66 };
kono
parents:
diff changeset
67
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
68 /* Implement target validation TARGET_OPTION_DEFAULT_PARAM. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
69
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
70 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
71 aarch64_option_validate_param (const int value, const int param)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
72 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
73 /* Check that both parameters are the same. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 if (param == (int) PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
76 if (value != 12 && value != 16)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 error ("only values 12 (4 KB) and 16 (64 KB) are supported for guard "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 "size. Given value %d (%llu KB) is out of range",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
80 value, (1ULL << value) / 1024ULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
85 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 static void
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 aarch64_option_default_params (void)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 /* We assume the guard page is 64k. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 int index = (int) PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95 set_default_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 DEFAULT_STK_CLASH_GUARD_SIZE == 0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 ? 16 : DEFAULT_STK_CLASH_GUARD_SIZE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 int guard_size
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 = default_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 /* Set the interval parameter to be the same as the guard size. This way the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 mid-end code does the right thing for us. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 set_default_param_value (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105 guard_size);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 /* Validate the options. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 aarch64_option_validate_param (guard_size, index);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110
111
kono
parents:
diff changeset
111 /* Implement TARGET_HANDLE_OPTION.
kono
parents:
diff changeset
112 This function handles the target specific options for CPU/target selection.
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
kono
parents:
diff changeset
115 If either of -march or -mtune is given, they override their
kono
parents:
diff changeset
116 respective component of -mcpu. This logic is implemented
kono
parents:
diff changeset
117 in config/aarch64/aarch64.c:aarch64_override_options. */
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 bool
kono
parents:
diff changeset
120 aarch64_handle_option (struct gcc_options *opts,
kono
parents:
diff changeset
121 struct gcc_options *opts_set ATTRIBUTE_UNUSED,
kono
parents:
diff changeset
122 const struct cl_decoded_option *decoded,
kono
parents:
diff changeset
123 location_t loc ATTRIBUTE_UNUSED)
kono
parents:
diff changeset
124 {
kono
parents:
diff changeset
125 size_t code = decoded->opt_index;
kono
parents:
diff changeset
126 const char *arg = decoded->arg;
kono
parents:
diff changeset
127 int val = decoded->value;
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 switch (code)
kono
parents:
diff changeset
130 {
kono
parents:
diff changeset
131 case OPT_march_:
kono
parents:
diff changeset
132 opts->x_aarch64_arch_string = arg;
kono
parents:
diff changeset
133 return true;
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 case OPT_mcpu_:
kono
parents:
diff changeset
136 opts->x_aarch64_cpu_string = arg;
kono
parents:
diff changeset
137 return true;
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 case OPT_mtune_:
kono
parents:
diff changeset
140 opts->x_aarch64_tune_string = arg;
kono
parents:
diff changeset
141 return true;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 case OPT_mgeneral_regs_only:
kono
parents:
diff changeset
144 opts->x_target_flags |= MASK_GENERAL_REGS_ONLY;
kono
parents:
diff changeset
145 return true;
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 case OPT_mfix_cortex_a53_835769:
kono
parents:
diff changeset
148 opts->x_aarch64_fix_a53_err835769 = val;
kono
parents:
diff changeset
149 return true;
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 case OPT_mstrict_align:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
152 if (val)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 opts->x_target_flags |= MASK_STRICT_ALIGN;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 opts->x_target_flags &= ~MASK_STRICT_ALIGN;
111
kono
parents:
diff changeset
156 return true;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 case OPT_momit_leaf_frame_pointer:
kono
parents:
diff changeset
159 opts->x_flag_omit_leaf_frame_pointer = val;
kono
parents:
diff changeset
160 return true;
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 default:
kono
parents:
diff changeset
163 return true;
kono
parents:
diff changeset
164 }
kono
parents:
diff changeset
165 }
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 /* An ISA extension in the co-processor and main instruction set space. */
kono
parents:
diff changeset
170 struct aarch64_option_extension
kono
parents:
diff changeset
171 {
kono
parents:
diff changeset
172 const char *const name;
kono
parents:
diff changeset
173 const unsigned long flag_canonical;
kono
parents:
diff changeset
174 const unsigned long flags_on;
kono
parents:
diff changeset
175 const unsigned long flags_off;
kono
parents:
diff changeset
176 };
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 /* ISA extensions in AArch64. */
kono
parents:
diff changeset
179 static const struct aarch64_option_extension all_extensions[] =
kono
parents:
diff changeset
180 {
kono
parents:
diff changeset
181 #define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, Z) \
kono
parents:
diff changeset
182 {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF},
kono
parents:
diff changeset
183 #include "config/aarch64/aarch64-option-extensions.def"
kono
parents:
diff changeset
184 {NULL, 0, 0, 0}
kono
parents:
diff changeset
185 };
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 struct processor_name_to_arch
kono
parents:
diff changeset
188 {
kono
parents:
diff changeset
189 const std::string processor_name;
kono
parents:
diff changeset
190 const enum aarch64_arch arch;
kono
parents:
diff changeset
191 const unsigned long flags;
kono
parents:
diff changeset
192 };
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 struct arch_to_arch_name
kono
parents:
diff changeset
195 {
kono
parents:
diff changeset
196 const enum aarch64_arch arch;
kono
parents:
diff changeset
197 const std::string arch_name;
kono
parents:
diff changeset
198 const unsigned long flags;
kono
parents:
diff changeset
199 };
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 /* Map processor names to the architecture revision they implement and
kono
parents:
diff changeset
202 the default set of architectural feature flags they support. */
kono
parents:
diff changeset
203 static const struct processor_name_to_arch all_cores[] =
kono
parents:
diff changeset
204 {
kono
parents:
diff changeset
205 #define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART, VARIANT) \
kono
parents:
diff changeset
206 {NAME, AARCH64_ARCH_##ARCH_IDENT, FLAGS},
kono
parents:
diff changeset
207 #include "config/aarch64/aarch64-cores.def"
kono
parents:
diff changeset
208 {"generic", AARCH64_ARCH_8A, AARCH64_FL_FOR_ARCH8},
kono
parents:
diff changeset
209 {"", aarch64_no_arch, 0}
kono
parents:
diff changeset
210 };
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 /* Map architecture revisions to their string representation. */
kono
parents:
diff changeset
213 static const struct arch_to_arch_name all_architectures[] =
kono
parents:
diff changeset
214 {
kono
parents:
diff changeset
215 #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \
kono
parents:
diff changeset
216 {AARCH64_ARCH_##ARCH_IDENT, NAME, FLAGS},
kono
parents:
diff changeset
217 #include "config/aarch64/aarch64-arches.def"
kono
parents:
diff changeset
218 {aarch64_no_arch, "", 0}
kono
parents:
diff changeset
219 };
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 /* Parse the architecture extension string STR and update ISA_FLAGS
kono
parents:
diff changeset
222 with the architecture features turned on or off. Return a
kono
parents:
diff changeset
223 aarch64_parse_opt_result describing the result. */
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 enum aarch64_parse_opt_result
kono
parents:
diff changeset
226 aarch64_parse_extension (const char *str, unsigned long *isa_flags)
kono
parents:
diff changeset
227 {
kono
parents:
diff changeset
228 /* The extension string is parsed left to right. */
kono
parents:
diff changeset
229 const struct aarch64_option_extension *opt = NULL;
kono
parents:
diff changeset
230
kono
parents:
diff changeset
231 /* Flag to say whether we are adding or removing an extension. */
kono
parents:
diff changeset
232 int adding_ext = -1;
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 while (str != NULL && *str != 0)
kono
parents:
diff changeset
235 {
kono
parents:
diff changeset
236 const char *ext;
kono
parents:
diff changeset
237 size_t len;
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 str++;
kono
parents:
diff changeset
240 ext = strchr (str, '+');
kono
parents:
diff changeset
241
kono
parents:
diff changeset
242 if (ext != NULL)
kono
parents:
diff changeset
243 len = ext - str;
kono
parents:
diff changeset
244 else
kono
parents:
diff changeset
245 len = strlen (str);
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 if (len >= 2 && strncmp (str, "no", 2) == 0)
kono
parents:
diff changeset
248 {
kono
parents:
diff changeset
249 adding_ext = 0;
kono
parents:
diff changeset
250 len -= 2;
kono
parents:
diff changeset
251 str += 2;
kono
parents:
diff changeset
252 }
kono
parents:
diff changeset
253 else if (len > 0)
kono
parents:
diff changeset
254 adding_ext = 1;
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 if (len == 0)
kono
parents:
diff changeset
257 return AARCH64_PARSE_MISSING_ARG;
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 /* Scan over the extensions table trying to find an exact match. */
kono
parents:
diff changeset
261 for (opt = all_extensions; opt->name != NULL; opt++)
kono
parents:
diff changeset
262 {
kono
parents:
diff changeset
263 if (strlen (opt->name) == len && strncmp (opt->name, str, len) == 0)
kono
parents:
diff changeset
264 {
kono
parents:
diff changeset
265 /* Add or remove the extension. */
kono
parents:
diff changeset
266 if (adding_ext)
kono
parents:
diff changeset
267 *isa_flags |= (opt->flags_on | opt->flag_canonical);
kono
parents:
diff changeset
268 else
kono
parents:
diff changeset
269 *isa_flags &= ~(opt->flags_off | opt->flag_canonical);
kono
parents:
diff changeset
270 break;
kono
parents:
diff changeset
271 }
kono
parents:
diff changeset
272 }
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 if (opt->name == NULL)
kono
parents:
diff changeset
275 {
kono
parents:
diff changeset
276 /* Extension not found in list. */
kono
parents:
diff changeset
277 return AARCH64_PARSE_INVALID_FEATURE;
kono
parents:
diff changeset
278 }
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 str = ext;
kono
parents:
diff changeset
281 };
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 return AARCH64_PARSE_OK;
kono
parents:
diff changeset
284 }
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS
kono
parents:
diff changeset
287 gives the default set of flags which are implied by whatever -march
kono
parents:
diff changeset
288 we'd put out. Our job is to figure out the minimal set of "+" and
kono
parents:
diff changeset
289 "+no" feature flags to put out, and to put them out grouped such
kono
parents:
diff changeset
290 that all the "+" flags come before the "+no" flags. */
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 std::string
kono
parents:
diff changeset
293 aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags,
kono
parents:
diff changeset
294 unsigned long default_arch_flags)
kono
parents:
diff changeset
295 {
kono
parents:
diff changeset
296 const struct aarch64_option_extension *opt = NULL;
kono
parents:
diff changeset
297 std::string outstr = "";
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 /* Pass one: Find all the things we need to turn on. As a special case,
kono
parents:
diff changeset
300 we always want to put out +crc if it is enabled. */
kono
parents:
diff changeset
301 for (opt = all_extensions; opt->name != NULL; opt++)
kono
parents:
diff changeset
302 if ((isa_flags & opt->flag_canonical
kono
parents:
diff changeset
303 && !(default_arch_flags & opt->flag_canonical))
kono
parents:
diff changeset
304 || (default_arch_flags & opt->flag_canonical
kono
parents:
diff changeset
305 && opt->flag_canonical == AARCH64_ISA_CRC))
kono
parents:
diff changeset
306 {
kono
parents:
diff changeset
307 outstr += "+";
kono
parents:
diff changeset
308 outstr += opt->name;
kono
parents:
diff changeset
309 }
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 /* Pass two: Find all the things we need to turn off. */
kono
parents:
diff changeset
312 for (opt = all_extensions; opt->name != NULL; opt++)
kono
parents:
diff changeset
313 if ((~isa_flags) & opt->flag_canonical
kono
parents:
diff changeset
314 && !((~default_arch_flags) & opt->flag_canonical))
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 outstr += "+no";
kono
parents:
diff changeset
317 outstr += opt->name;
kono
parents:
diff changeset
318 }
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 return outstr;
kono
parents:
diff changeset
321 }
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 /* Attempt to rewrite NAME, which has been passed on the command line
kono
parents:
diff changeset
324 as a -mcpu option to an equivalent -march value. If we can do so,
kono
parents:
diff changeset
325 return the new string, otherwise return an error. */
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 const char *
kono
parents:
diff changeset
328 aarch64_rewrite_selected_cpu (const char *name)
kono
parents:
diff changeset
329 {
kono
parents:
diff changeset
330 std::string original_string (name);
kono
parents:
diff changeset
331 std::string extension_str;
kono
parents:
diff changeset
332 std::string processor;
kono
parents:
diff changeset
333 size_t extension_pos = original_string.find_first_of ('+');
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 /* Strip and save the extension string. */
kono
parents:
diff changeset
336 if (extension_pos != std::string::npos)
kono
parents:
diff changeset
337 {
kono
parents:
diff changeset
338 processor = original_string.substr (0, extension_pos);
kono
parents:
diff changeset
339 extension_str = original_string.substr (extension_pos,
kono
parents:
diff changeset
340 std::string::npos);
kono
parents:
diff changeset
341 }
kono
parents:
diff changeset
342 else
kono
parents:
diff changeset
343 {
kono
parents:
diff changeset
344 /* No extensions. */
kono
parents:
diff changeset
345 processor = original_string;
kono
parents:
diff changeset
346 }
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 const struct processor_name_to_arch* p_to_a;
kono
parents:
diff changeset
349 for (p_to_a = all_cores;
kono
parents:
diff changeset
350 p_to_a->arch != aarch64_no_arch;
kono
parents:
diff changeset
351 p_to_a++)
kono
parents:
diff changeset
352 {
kono
parents:
diff changeset
353 if (p_to_a->processor_name == processor)
kono
parents:
diff changeset
354 break;
kono
parents:
diff changeset
355 }
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 const struct arch_to_arch_name* a_to_an;
kono
parents:
diff changeset
358 for (a_to_an = all_architectures;
kono
parents:
diff changeset
359 a_to_an->arch != aarch64_no_arch;
kono
parents:
diff changeset
360 a_to_an++)
kono
parents:
diff changeset
361 {
kono
parents:
diff changeset
362 if (a_to_an->arch == p_to_a->arch)
kono
parents:
diff changeset
363 break;
kono
parents:
diff changeset
364 }
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 /* We couldn't find that proceesor name, or the processor name we
kono
parents:
diff changeset
367 found does not map to an architecture we understand. */
kono
parents:
diff changeset
368 if (p_to_a->arch == aarch64_no_arch
kono
parents:
diff changeset
369 || a_to_an->arch == aarch64_no_arch)
kono
parents:
diff changeset
370 fatal_error (input_location, "unknown value %qs for -mcpu", name);
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 unsigned long extensions = p_to_a->flags;
kono
parents:
diff changeset
373 aarch64_parse_extension (extension_str.c_str (), &extensions);
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 std::string outstr = a_to_an->arch_name
kono
parents:
diff changeset
376 + aarch64_get_extension_string_for_isa_flags (extensions,
kono
parents:
diff changeset
377 a_to_an->flags);
kono
parents:
diff changeset
378
kono
parents:
diff changeset
379 /* We are going to memory leak here, nobody elsewhere
kono
parents:
diff changeset
380 in the callchain is going to clean up after us. The alternative is
kono
parents:
diff changeset
381 to allocate a static buffer, and assert that it is big enough for our
kono
parents:
diff changeset
382 modified string, which seems much worse! */
kono
parents:
diff changeset
383 return xstrdup (outstr.c_str ());
kono
parents:
diff changeset
384 }
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 /* Called by the driver to rewrite a name passed to the -mcpu
kono
parents:
diff changeset
387 argument in preparation to be passed to the assembler. The
kono
parents:
diff changeset
388 names passed from the commend line will be in ARGV, we want
kono
parents:
diff changeset
389 to use the right-most argument, which should be in
kono
parents:
diff changeset
390 ARGV[ARGC - 1]. ARGC should always be greater than 0. */
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 const char *
kono
parents:
diff changeset
393 aarch64_rewrite_mcpu (int argc, const char **argv)
kono
parents:
diff changeset
394 {
kono
parents:
diff changeset
395 gcc_assert (argc);
kono
parents:
diff changeset
396 return aarch64_rewrite_selected_cpu (argv[argc - 1]);
kono
parents:
diff changeset
397 }
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399 #undef AARCH64_CPU_NAME_LENGTH
kono
parents:
diff changeset
400