]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/common/config/aarch64/aarch64-common.c
[AArch64] Fix thinko in handling of -momit-leaf-frame-pointer option
[thirdparty/gcc.git] / gcc / common / config / aarch64 / aarch64-common.c
1 /* Common hooks for AArch64.
2 Copyright (C) 2012-2016 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #define INCLUDE_STRING
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tm_p.h"
27 #include "common/common-target.h"
28 #include "common/common-target-def.h"
29 #include "opts.h"
30 #include "flags.h"
31 #include "diagnostic.h"
32
33 #ifdef TARGET_BIG_ENDIAN_DEFAULT
34 #undef TARGET_DEFAULT_TARGET_FLAGS
35 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END)
36 #endif
37
38 #undef TARGET_HANDLE_OPTION
39 #define TARGET_HANDLE_OPTION aarch64_handle_option
40
41 #undef TARGET_OPTION_OPTIMIZATION_TABLE
42 #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table
43
44 /* Set default optimization options. */
45 static const struct default_options aarch_option_optimization_table[] =
46 {
47 /* Enable section anchors by default at -O1 or higher. */
48 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
49 /* Enable -fsched-pressure by default when optimizing. */
50 { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
51 /* Enable redundant extension instructions removal at -O2 and higher. */
52 { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 },
53 { OPT_LEVELS_NONE, 0, NULL, 0 }
54 };
55
56 /* Implement TARGET_HANDLE_OPTION.
57 This function handles the target specific options for CPU/target selection.
58
59 -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
60 If either of -march or -mtune is given, they override their
61 respective component of -mcpu. This logic is implemented
62 in config/aarch64/aarch64.c:aarch64_override_options. */
63
64 bool
65 aarch64_handle_option (struct gcc_options *opts,
66 struct gcc_options *opts_set ATTRIBUTE_UNUSED,
67 const struct cl_decoded_option *decoded,
68 location_t loc ATTRIBUTE_UNUSED)
69 {
70 size_t code = decoded->opt_index;
71 const char *arg = decoded->arg;
72 int val = decoded->value;
73
74 switch (code)
75 {
76 case OPT_march_:
77 opts->x_aarch64_arch_string = arg;
78 return true;
79
80 case OPT_mcpu_:
81 opts->x_aarch64_cpu_string = arg;
82 return true;
83
84 case OPT_mtune_:
85 opts->x_aarch64_tune_string = arg;
86 return true;
87
88 case OPT_mgeneral_regs_only:
89 opts->x_target_flags |= MASK_GENERAL_REGS_ONLY;
90 return true;
91
92 case OPT_mfix_cortex_a53_835769:
93 opts->x_aarch64_fix_a53_err835769 = val;
94 return true;
95
96 case OPT_mstrict_align:
97 opts->x_target_flags |= MASK_STRICT_ALIGN;
98 return true;
99
100 case OPT_momit_leaf_frame_pointer:
101 opts->x_flag_omit_leaf_frame_pointer = val;
102 return true;
103
104 default:
105 return true;
106 }
107 }
108
109 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
110
111 /* An ISA extension in the co-processor and main instruction set space. */
112 struct aarch64_option_extension
113 {
114 const char *const name;
115 const unsigned long flags_on;
116 const unsigned long flags_off;
117 };
118
119 /* ISA extensions in AArch64. */
120 static const struct aarch64_option_extension all_extensions[] =
121 {
122 #define AARCH64_OPT_EXTENSION(NAME, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \
123 {NAME, FLAGS_ON, FLAGS_OFF},
124 #include "config/aarch64/aarch64-option-extensions.def"
125 #undef AARCH64_OPT_EXTENSION
126 {NULL, 0, 0}
127 };
128
129 struct processor_name_to_arch
130 {
131 const std::string processor_name;
132 const enum aarch64_arch arch;
133 const unsigned long flags;
134 };
135
136 struct arch_to_arch_name
137 {
138 const enum aarch64_arch arch;
139 const std::string arch_name;
140 };
141
142 /* Map processor names to the architecture revision they implement and
143 the default set of architectural feature flags they support. */
144 static const struct processor_name_to_arch all_cores[] =
145 {
146 #define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART) \
147 {NAME, AARCH64_ARCH_##ARCH_IDENT, FLAGS},
148 #include "config/aarch64/aarch64-cores.def"
149 #undef AARCH64_CORE
150 {"generic", AARCH64_ARCH_8A, AARCH64_FL_FOR_ARCH8},
151 {"", aarch64_no_arch, 0}
152 };
153
154 /* Map architecture revisions to their string representation. */
155 static const struct arch_to_arch_name all_architectures[] =
156 {
157 #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \
158 {AARCH64_ARCH_##ARCH_IDENT, NAME},
159 #include "config/aarch64/aarch64-arches.def"
160 #undef AARCH64_ARCH
161 {aarch64_no_arch, ""}
162 };
163
164 /* Return a string representation of ISA_FLAGS. */
165
166 std::string
167 aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags)
168 {
169 const struct aarch64_option_extension *opt = NULL;
170 std::string outstr = "";
171
172 for (opt = all_extensions; opt->name != NULL; opt++)
173 if ((isa_flags & opt->flags_on) == opt->flags_on)
174 {
175 outstr += "+";
176 outstr += opt->name;
177 }
178 return outstr;
179 }
180
181 /* Attempt to rewrite NAME, which has been passed on the command line
182 as a -mcpu option to an equivalent -march value. If we can do so,
183 return the new string, otherwise return an error. */
184
185 const char *
186 aarch64_rewrite_selected_cpu (const char *name)
187 {
188 std::string original_string (name);
189 std::string extensions;
190 std::string processor;
191 size_t extension_pos = original_string.find_first_of ('+');
192
193 /* Strip and save the extension string. */
194 if (extension_pos != std::string::npos)
195 {
196 processor = original_string.substr (0, extension_pos);
197 extensions = original_string.substr (extension_pos,
198 std::string::npos);
199 }
200 else
201 {
202 /* No extensions. */
203 processor = original_string;
204 }
205
206 const struct processor_name_to_arch* p_to_a;
207 for (p_to_a = all_cores;
208 p_to_a->arch != aarch64_no_arch;
209 p_to_a++)
210 {
211 if (p_to_a->processor_name == processor)
212 break;
213 }
214
215 const struct arch_to_arch_name* a_to_an;
216 for (a_to_an = all_architectures;
217 a_to_an->arch != aarch64_no_arch;
218 a_to_an++)
219 {
220 if (a_to_an->arch == p_to_a->arch)
221 break;
222 }
223
224 /* We couldn't find that proceesor name, or the processor name we
225 found does not map to an architecture we understand. */
226 if (p_to_a->arch == aarch64_no_arch
227 || a_to_an->arch == aarch64_no_arch)
228 fatal_error (input_location, "unknown value %qs for -mcpu", name);
229
230 std::string outstr = a_to_an->arch_name
231 + aarch64_get_extension_string_for_isa_flags (p_to_a->flags)
232 + extensions;
233
234 /* We are going to memory leak here, nobody elsewhere
235 in the callchain is going to clean up after us. The alternative is
236 to allocate a static buffer, and assert that it is big enough for our
237 modified string, which seems much worse! */
238 return xstrdup (outstr.c_str ());
239 }
240
241 /* Called by the driver to rewrite a name passed to the -mcpu
242 argument in preparation to be passed to the assembler. The
243 names passed from the commend line will be in ARGV, we want
244 to use the right-most argument, which should be in
245 ARGV[ARGC - 1]. ARGC should always be greater than 0. */
246
247 const char *
248 aarch64_rewrite_mcpu (int argc, const char **argv)
249 {
250 gcc_assert (argc);
251 return aarch64_rewrite_selected_cpu (argv[argc - 1]);
252 }
253
254 #undef AARCH64_CPU_NAME_LENGTH
255