Mercurial > hg > CbC > CbC_gcc
comparison gcc/common/config/arm/arm-common.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Common hooks for ARM. | 1 /* Common hooks for ARM. |
2 Copyright (C) 1991-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1991-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published | 7 under the terms of the GNU General Public License as published |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with GCC; see the file COPYING3. If not see | 17 along with GCC; see the file COPYING3. If not see |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #define INCLUDE_LIST | 20 #define INCLUDE_LIST |
21 #define INCLUDE_VECTOR | |
21 #include "config.h" | 22 #include "config.h" |
22 #include "system.h" | 23 #include "system.h" |
23 #include "coretypes.h" | 24 #include "coretypes.h" |
24 #include "tm.h" | 25 #include "tm.h" |
25 #include "memmodel.h" | 26 #include "memmodel.h" |
28 #include "common/common-target-def.h" | 29 #include "common/common-target-def.h" |
29 #include "opts.h" | 30 #include "opts.h" |
30 #include "flags.h" | 31 #include "flags.h" |
31 #include "sbitmap.h" | 32 #include "sbitmap.h" |
32 #include "diagnostic.h" | 33 #include "diagnostic.h" |
34 #include <algorithm> | |
33 | 35 |
34 /* Set default optimization options. */ | 36 /* Set default optimization options. */ |
35 static const struct default_options arm_option_optimization_table[] = | 37 static const struct default_options arm_option_optimization_table[] = |
36 { | 38 { |
37 /* Enable section anchors by default at -O1 or higher. */ | 39 /* Enable section anchors by default at -O1 or higher. */ |
38 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, | 40 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, |
39 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, | |
40 { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, | 41 { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, |
41 { OPT_LEVELS_NONE, 0, NULL, 0 } | 42 { OPT_LEVELS_NONE, 0, NULL, 0 } |
42 }; | 43 }; |
43 | 44 |
44 /* Implement TARGET_EXCEPT_UNWIND_INFO. */ | 45 /* Implement TARGET_EXCEPT_UNWIND_INFO. */ |
113 { | 114 { |
114 gcc_assert (argc); | 115 gcc_assert (argc); |
115 return arm_rewrite_selected_cpu (argv[argc - 1]); | 116 return arm_rewrite_selected_cpu (argv[argc - 1]); |
116 } | 117 } |
117 | 118 |
118 /* Truncate NAME at the first '+' character seen, or return | 119 /* Comparator for arm_rewrite_selected_arch. Compare the two arch extension |
119 NAME unmodified. Similar to arm_rewrite_selected_cpu, but we must | 120 strings FIRST and SECOND and return TRUE if FIRST is less than SECOND |
120 preserve '.' as that is part of some architecture names. */ | 121 alphabetically. */ |
121 | 122 |
123 static bool | |
124 compare_opt_names (const char *first, const char *second) | |
125 { | |
126 return strcmp (first, second) <= 0; | |
127 } | |
128 | |
129 /* Rewrite the architecture string for passing to the assembler. | |
130 Although the syntax is similar we cannot assume that it supports | |
131 the newer FP related options. So strip any option that only | |
132 defines features in the standard -mfpu options out. We'll generate | |
133 a suitable -mfpu option elsewhere to carry that information. NAME | |
134 should already have been canonicalized, so we do not expect to | |
135 encounter +no.. options that remove features. A final problem is | |
136 that the assembler expects the feature extensions to be listed | |
137 alphabetically, so we build a list of required options and then | |
138 sort them into canonical order in the resulting string. */ | |
122 const char * | 139 const char * |
123 arm_rewrite_selected_arch (const char *name) | 140 arm_rewrite_selected_arch (const char *name) |
124 { | 141 { |
125 static char output_buf[ARM_CPU_NAME_LENGTH + 1] = {0}; | 142 /* The result we return needs to be semi persistent, so handle being |
126 char *arg_pos; | 143 re-invoked. */ |
127 | 144 static char *asm_arch = NULL; |
128 strncpy (output_buf, name, ARM_CPU_NAME_LENGTH); | 145 |
129 output_buf[ARM_CPU_NAME_LENGTH] = 0; | 146 if (asm_arch) |
130 | 147 { |
131 arg_pos = strchr (output_buf, '+'); | 148 free (asm_arch); |
132 | 149 asm_arch = NULL; |
133 /* If we found a '+' truncate the entry at that point. */ | 150 } |
134 if (arg_pos) | 151 |
135 *arg_pos = '\0'; | 152 const char *arg_pos = strchr (name, '+'); |
136 | 153 |
137 return output_buf; | 154 /* No extension options? just return the original string. */ |
155 if (arg_pos == NULL) | |
156 return name; | |
157 | |
158 const arch_option *arch_opt | |
159 = arm_parse_arch_option_name (all_architectures, "-march", name); | |
160 | |
161 auto_sbitmap fpu_bits (isa_num_bits); | |
162 static const enum isa_feature fpu_bitlist[] | |
163 = { ISA_ALL_FPU_INTERNAL, isa_nobit }; | |
164 | |
165 arm_initialize_isa (fpu_bits, fpu_bitlist); | |
166 | |
167 auto_sbitmap opt_bits (isa_num_bits); | |
168 | |
169 /* Ensure that the resulting string is large enough for the result. We | |
170 never add options, so using strdup here will ensure that. */ | |
171 asm_arch = xstrdup (name); | |
172 asm_arch[arg_pos - name] = '\0'; | |
173 | |
174 std::vector<const char *>optlist; | |
175 | |
176 while (arg_pos) | |
177 { | |
178 const char *end = strchr (arg_pos + 1, '+'); | |
179 size_t len = end ? end - arg_pos : strlen (arg_pos); | |
180 | |
181 for (const cpu_arch_extension *entry = arch_opt->common.extensions; | |
182 entry->name != NULL; | |
183 entry++) | |
184 { | |
185 if (strncmp (entry->name, arg_pos + 1, len - 1) == 0 | |
186 && entry->name[len - 1] == '\0') | |
187 { | |
188 /* Don't expect removal options. */ | |
189 gcc_assert (!entry->remove); | |
190 arm_initialize_isa (opt_bits, entry->isa_bits); | |
191 if (!bitmap_subset_p (opt_bits, fpu_bits)) | |
192 optlist.push_back (entry->name); | |
193 bitmap_clear (opt_bits); | |
194 break; | |
195 } | |
196 } | |
197 | |
198 arg_pos = end; | |
199 } | |
200 | |
201 std::sort (optlist.begin (), optlist.end (), compare_opt_names); | |
202 | |
203 for (std::vector<const char *>::iterator opt_iter = optlist.begin (); | |
204 opt_iter != optlist.end (); | |
205 ++opt_iter) | |
206 { | |
207 strcat (asm_arch, "+"); | |
208 strcat (asm_arch, (*opt_iter)); | |
209 } | |
210 | |
211 return asm_arch; | |
138 } | 212 } |
139 | 213 |
140 /* Called by the driver to rewrite a name passed to the -march | 214 /* Called by the driver to rewrite a name passed to the -march |
141 argument in preparation to be passed to the assembler. The | 215 argument in preparation to be passed to the assembler. The |
142 names passed from the command line will be in ARGV, we want | 216 names passed from the command line will be in ARGV, we want |
203 | 277 |
204 /* If the architecture is specified, that overrides any CPU setting. */ | 278 /* If the architecture is specified, that overrides any CPU setting. */ |
205 if (arch) | 279 if (arch) |
206 { | 280 { |
207 const arch_option *arch_opt | 281 const arch_option *arch_opt |
208 = arm_parse_arch_option_name (all_architectures, "-march", arch); | 282 = arm_parse_arch_option_name (all_architectures, "-march", arch, |
283 false); | |
209 | 284 |
210 if (arch_opt && !check_isa_bits_for (arch_opt->common.isa_bits, | 285 if (arch_opt && !check_isa_bits_for (arch_opt->common.isa_bits, |
211 isa_bit_notm)) | 286 isa_bit_notm)) |
212 return "-mthumb"; | 287 return "-mthumb"; |
213 } | 288 } |
214 else if (cpu) | 289 else if (cpu) |
215 { | 290 { |
216 const cpu_option *cpu_opt | 291 const cpu_option *cpu_opt |
217 = arm_parse_cpu_option_name (all_cores, "-mcpu", cpu); | 292 = arm_parse_cpu_option_name (all_cores, "-mcpu", cpu, false); |
218 | 293 |
219 if (cpu_opt && !check_isa_bits_for (cpu_opt->common.isa_bits, | 294 if (cpu_opt && !check_isa_bits_for (cpu_opt->common.isa_bits, |
220 isa_bit_notm)) | 295 isa_bit_notm)) |
221 return "-mthumb"; | 296 return "-mthumb"; |
222 } | 297 } |
233 const cpu_option *list) | 308 const cpu_option *list) |
234 { | 309 { |
235 auto_vec<const char*> candidates; | 310 auto_vec<const char*> candidates; |
236 for (; list->common.name != NULL; list++) | 311 for (; list->common.name != NULL; list++) |
237 candidates.safe_push (list->common.name); | 312 candidates.safe_push (list->common.name); |
313 | |
314 #ifdef HAVE_LOCAL_CPU_DETECT | |
315 /* Add also "native" as possible value. */ | |
316 candidates.safe_push ("native"); | |
317 #endif | |
318 | |
238 char *s; | 319 char *s; |
239 const char *hint = candidates_list_and_hint (target, s, candidates); | 320 const char *hint = candidates_list_and_hint (target, s, candidates); |
240 if (hint) | 321 if (hint) |
241 inform (input_location, "valid arguments are: %s; did you mean %qs?", | 322 inform (input_location, "valid arguments are: %s; did you mean %qs?", |
242 s, hint); | 323 s, hint); |
247 } | 328 } |
248 | 329 |
249 /* Parse the base component of a CPU selection in LIST. Return a | 330 /* Parse the base component of a CPU selection in LIST. Return a |
250 pointer to the entry in the architecture table. OPTNAME is the | 331 pointer to the entry in the architecture table. OPTNAME is the |
251 name of the option we are parsing and can be used if a diagnostic | 332 name of the option we are parsing and can be used if a diagnostic |
252 is needed. */ | 333 is needed. If COMPLAIN is true (the default) emit error |
334 messages and hints on invalid input. */ | |
253 const cpu_option * | 335 const cpu_option * |
254 arm_parse_cpu_option_name (const cpu_option *list, const char *optname, | 336 arm_parse_cpu_option_name (const cpu_option *list, const char *optname, |
255 const char *target) | 337 const char *target, bool complain) |
256 { | 338 { |
257 const cpu_option *entry; | 339 const cpu_option *entry; |
258 const char *end = strchr (target, '+'); | 340 const char *end = strchr (target, '+'); |
259 size_t len = end ? end - target : strlen (target); | 341 size_t len = end ? end - target : strlen (target); |
260 | 342 |
263 if (strncmp (entry->common.name, target, len) == 0 | 345 if (strncmp (entry->common.name, target, len) == 0 |
264 && entry->common.name[len] == '\0') | 346 && entry->common.name[len] == '\0') |
265 return entry; | 347 return entry; |
266 } | 348 } |
267 | 349 |
268 error_at (input_location, "unrecognized %s target: %s", optname, target); | 350 if (complain) |
269 arm_print_hint_for_cpu_option (target, list); | 351 { |
352 error_at (input_location, "unrecognized %s target: %s", optname, target); | |
353 arm_print_hint_for_cpu_option (target, list); | |
354 } | |
270 return NULL; | 355 return NULL; |
271 } | 356 } |
272 | 357 |
273 /* List the permitted architecture option names. If TARGET is a near | 358 /* List the permitted architecture option names. If TARGET is a near |
274 miss for an entry, print out the suggested alternative. */ | 359 miss for an entry, print out the suggested alternative. */ |
277 const arch_option *list) | 362 const arch_option *list) |
278 { | 363 { |
279 auto_vec<const char*> candidates; | 364 auto_vec<const char*> candidates; |
280 for (; list->common.name != NULL; list++) | 365 for (; list->common.name != NULL; list++) |
281 candidates.safe_push (list->common.name); | 366 candidates.safe_push (list->common.name); |
367 | |
368 #ifdef HAVE_LOCAL_CPU_DETECT | |
369 /* Add also "native" as possible value. */ | |
370 candidates.safe_push ("native"); | |
371 #endif | |
372 | |
282 char *s; | 373 char *s; |
283 const char *hint = candidates_list_and_hint (target, s, candidates); | 374 const char *hint = candidates_list_and_hint (target, s, candidates); |
284 if (hint) | 375 if (hint) |
285 inform (input_location, "valid arguments are: %s; did you mean %qs?", | 376 inform (input_location, "valid arguments are: %s; did you mean %qs?", |
286 s, hint); | 377 s, hint); |
291 } | 382 } |
292 | 383 |
293 /* Parse the base component of a CPU or architecture selection in | 384 /* Parse the base component of a CPU or architecture selection in |
294 LIST. Return a pointer to the entry in the architecture table. | 385 LIST. Return a pointer to the entry in the architecture table. |
295 OPTNAME is the name of the option we are parsing and can be used if | 386 OPTNAME is the name of the option we are parsing and can be used if |
296 a diagnostic is needed. */ | 387 a diagnostic is needed. If COMPLAIN is true (the default) emit error |
388 messages and hints on invalid input. */ | |
297 const arch_option * | 389 const arch_option * |
298 arm_parse_arch_option_name (const arch_option *list, const char *optname, | 390 arm_parse_arch_option_name (const arch_option *list, const char *optname, |
299 const char *target) | 391 const char *target, bool complain) |
300 { | 392 { |
301 const arch_option *entry; | 393 const arch_option *entry; |
302 const char *end = strchr (target, '+'); | 394 const char *end = strchr (target, '+'); |
303 size_t len = end ? end - target : strlen (target); | 395 size_t len = end ? end - target : strlen (target); |
304 | 396 |
307 if (strncmp (entry->common.name, target, len) == 0 | 399 if (strncmp (entry->common.name, target, len) == 0 |
308 && entry->common.name[len] == '\0') | 400 && entry->common.name[len] == '\0') |
309 return entry; | 401 return entry; |
310 } | 402 } |
311 | 403 |
312 error_at (input_location, "unrecognized %s target: %s", optname, target); | 404 if (complain) |
313 arm_print_hint_for_arch_option (target, list); | 405 { |
406 error_at (input_location, "unrecognized %s target: %s", optname, target); | |
407 arm_print_hint_for_arch_option (target, list); | |
408 } | |
314 return NULL; | 409 return NULL; |
315 } | 410 } |
316 | 411 |
317 /* List the permitted architecture option names. If TARGET is a near | 412 /* List the permitted architecture option names. If TARGET is a near |
318 miss for an entry, print out the suggested alternative. */ | 413 miss for an entry, print out the suggested alternative. */ |
822 return "--be8"; | 917 return "--be8"; |
823 | 918 |
824 return ""; | 919 return ""; |
825 } | 920 } |
826 | 921 |
922 /* Generate a -mfpu= option for passing to the assembler. This is | |
923 only called when -mfpu was set (possibly defaulted) to auto and is | |
924 needed to ensure that the assembler knows the correct FPU to use. | |
925 It wouldn't really be needed except that the compiler can be used | |
926 to invoke the assembler directly on hand-written files that lack | |
927 the necessary internal .fpu directives. We assume that the architecture | |
928 canonicalization calls have already been made so that we have a final | |
929 -march= option to derive the fpu from. */ | |
930 const char* | |
931 arm_asm_auto_mfpu (int argc, const char **argv) | |
932 { | |
933 static char *auto_fpu = NULL; | |
934 const char *arch = NULL; | |
935 static const enum isa_feature fpu_bitlist[] | |
936 = { ISA_ALL_FPU_INTERNAL, isa_nobit }; | |
937 const arch_option *selected_arch; | |
938 static const char* fpuname = "softvfp"; | |
939 | |
940 /* Handle multiple calls to this routine. */ | |
941 if (auto_fpu) | |
942 { | |
943 free (auto_fpu); | |
944 auto_fpu = NULL; | |
945 } | |
946 | |
947 while (argc) | |
948 { | |
949 if (strcmp (argv[0], "arch") == 0) | |
950 arch = argv[1]; | |
951 else | |
952 fatal_error (input_location, | |
953 "unrecognized operand to %%:asm_auto_mfpu"); | |
954 argc -= 2; | |
955 argv += 2; | |
956 } | |
957 | |
958 auto_sbitmap target_isa (isa_num_bits); | |
959 auto_sbitmap fpubits (isa_num_bits); | |
960 | |
961 gcc_assert (arch != NULL); | |
962 selected_arch = arm_parse_arch_option_name (all_architectures, | |
963 "-march", arch); | |
964 if (selected_arch == NULL) | |
965 return ""; | |
966 | |
967 arm_initialize_isa (target_isa, selected_arch->common.isa_bits); | |
968 arm_parse_option_features (target_isa, &selected_arch->common, | |
969 strchr (arch, '+')); | |
970 arm_initialize_isa (fpubits, fpu_bitlist); | |
971 | |
972 bitmap_and (fpubits, fpubits, target_isa); | |
973 | |
974 /* The logic below is essentially identical to that in | |
975 arm.c:arm_identify_fpu_from_isa(), but that only works in the main | |
976 part of the compiler. */ | |
977 | |
978 /* If there are no FPU capability bits, we just pass -mfpu=softvfp. */ | |
979 if (!bitmap_empty_p (fpubits)) | |
980 { | |
981 unsigned int i; | |
982 auto_sbitmap cand_fpubits (isa_num_bits); | |
983 for (i = 0; i < TARGET_FPU_auto; i++) | |
984 { | |
985 arm_initialize_isa (cand_fpubits, all_fpus[i].isa_bits); | |
986 if (bitmap_equal_p (fpubits, cand_fpubits)) | |
987 { | |
988 fpuname = all_fpus[i].name; | |
989 break; | |
990 } | |
991 } | |
992 | |
993 gcc_assert (i != TARGET_FPU_auto); | |
994 } | |
995 | |
996 auto_fpu = (char *) xmalloc (strlen (fpuname) + sizeof ("-mfpu=")); | |
997 strcpy (auto_fpu, "-mfpu="); | |
998 strcat (auto_fpu, fpuname); | |
999 return auto_fpu; | |
1000 } | |
1001 | |
827 #undef ARM_CPU_NAME_LENGTH | 1002 #undef ARM_CPU_NAME_LENGTH |
828 | 1003 |
829 | 1004 |
830 #undef TARGET_DEFAULT_TARGET_FLAGS | 1005 #undef TARGET_DEFAULT_TARGET_FLAGS |
831 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG) | 1006 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG) |