1 /* Common hooks for AArch64.
2 Copyright (C) 2012-2016 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of GCC.
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.
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.
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/>. */
23 #include "coretypes.h"
26 #include "common/common-target.h"
27 #include "common/common-target-def.h"
30 #include "diagnostic.h"
32 #ifdef TARGET_BIG_ENDIAN_DEFAULT
33 #undef TARGET_DEFAULT_TARGET_FLAGS
34 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END)
37 #undef TARGET_HANDLE_OPTION
38 #define TARGET_HANDLE_OPTION aarch64_handle_option
40 #undef TARGET_OPTION_OPTIMIZATION_TABLE
41 #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table
43 /* Set default optimization options. */
44 static const struct default_options aarch_option_optimization_table
[] =
46 /* Enable section anchors by default at -O1 or higher. */
47 { OPT_LEVELS_1_PLUS
, OPT_fsection_anchors
, NULL
, 1 },
48 /* Enable -fsched-pressure by default when optimizing. */
49 { OPT_LEVELS_1_PLUS
, OPT_fsched_pressure
, NULL
, 1 },
50 /* Enable redundant extension instructions removal at -O2 and higher. */
51 { OPT_LEVELS_2_PLUS
, OPT_free
, NULL
, 1 },
52 { OPT_LEVELS_NONE
, 0, NULL
, 0 }
55 /* Implement TARGET_HANDLE_OPTION.
56 This function handles the target specific options for CPU/target selection.
58 -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
59 If either of -march or -mtune is given, they override their
60 respective component of -mcpu. This logic is implemented
61 in config/aarch64/aarch64.c:aarch64_override_options. */
64 aarch64_handle_option (struct gcc_options
*opts
,
65 struct gcc_options
*opts_set ATTRIBUTE_UNUSED
,
66 const struct cl_decoded_option
*decoded
,
67 location_t loc ATTRIBUTE_UNUSED
)
69 size_t code
= decoded
->opt_index
;
70 const char *arg
= decoded
->arg
;
71 int val
= decoded
->value
;
76 opts
->x_aarch64_arch_string
= arg
;
80 opts
->x_aarch64_cpu_string
= arg
;
84 opts
->x_aarch64_tune_string
= arg
;
87 case OPT_mgeneral_regs_only
:
88 opts
->x_target_flags
|= MASK_GENERAL_REGS_ONLY
;
91 case OPT_mfix_cortex_a53_835769
:
92 opts
->x_aarch64_fix_a53_err835769
= val
;
95 case OPT_mstrict_align
:
96 opts
->x_target_flags
|= MASK_STRICT_ALIGN
;
99 case OPT_momit_leaf_frame_pointer
:
100 opts
->x_flag_omit_frame_pointer
= val
;
108 struct gcc_targetm_common targetm_common
= TARGETM_COMMON_INITIALIZER
;
110 /* An ISA extension in the co-processor and main instruction set space. */
111 struct aarch64_option_extension
113 const char *const name
;
114 const unsigned long flags_on
;
115 const unsigned long flags_off
;
118 /* ISA extensions in AArch64. */
119 static const struct aarch64_option_extension all_extensions
[] =
121 #define AARCH64_OPT_EXTENSION(NAME, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \
122 {NAME, FLAGS_ON, FLAGS_OFF},
123 #include "config/aarch64/aarch64-option-extensions.def"
124 #undef AARCH64_OPT_EXTENSION
128 struct processor_name_to_arch
130 const std::string processor_name
;
131 const enum aarch64_arch arch
;
132 const unsigned long flags
;
135 struct arch_to_arch_name
137 const enum aarch64_arch arch
;
138 const std::string arch_name
;
141 /* Map processor names to the architecture revision they implement and
142 the default set of architectural feature flags they support. */
143 static const struct processor_name_to_arch all_cores
[] =
145 #define AARCH64_CORE(NAME, X, IDENT, ARCH_IDENT, FLAGS, COSTS, IMP, PART) \
146 {NAME, AARCH64_ARCH_##ARCH_IDENT, FLAGS},
147 #include "config/aarch64/aarch64-cores.def"
149 {"generic", AARCH64_ARCH_8A
, AARCH64_FL_FOR_ARCH8
},
150 {"", aarch64_no_arch
, 0}
153 /* Map architecture revisions to their string representation. */
154 static const struct arch_to_arch_name all_architectures
[] =
156 #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH, FLAGS) \
157 {AARCH64_ARCH_##ARCH_IDENT, NAME},
158 #include "config/aarch64/aarch64-arches.def"
160 {aarch64_no_arch
, ""}
163 /* Return a string representation of ISA_FLAGS. */
166 aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags
)
168 const struct aarch64_option_extension
*opt
= NULL
;
169 std::string outstr
= "";
171 for (opt
= all_extensions
; opt
->name
!= NULL
; opt
++)
172 if ((isa_flags
& opt
->flags_on
) == opt
->flags_on
)
180 /* Attempt to rewrite NAME, which has been passed on the command line
181 as a -mcpu option to an equivalent -march value. If we can do so,
182 return the new string, otherwise return an error. */
185 aarch64_rewrite_selected_cpu (const char *name
)
187 std::string
original_string (name
);
188 std::string extensions
;
189 std::string processor
;
190 size_t extension_pos
= original_string
.find_first_of ('+');
192 /* Strip and save the extension string. */
193 if (extension_pos
!= std::string::npos
)
195 processor
= original_string
.substr (0, extension_pos
);
196 extensions
= original_string
.substr (extension_pos
,
202 processor
= original_string
;
205 const struct processor_name_to_arch
* p_to_a
;
206 for (p_to_a
= all_cores
;
207 p_to_a
->arch
!= aarch64_no_arch
;
210 if (p_to_a
->processor_name
== processor
)
214 const struct arch_to_arch_name
* a_to_an
;
215 for (a_to_an
= all_architectures
;
216 a_to_an
->arch
!= aarch64_no_arch
;
219 if (a_to_an
->arch
== p_to_a
->arch
)
223 /* We couldn't find that proceesor name, or the processor name we
224 found does not map to an architecture we understand. */
225 if (p_to_a
->arch
== aarch64_no_arch
226 || a_to_an
->arch
== aarch64_no_arch
)
227 fatal_error (input_location
, "unknown value %qs for -mcpu", name
);
229 std::string outstr
= a_to_an
->arch_name
230 + aarch64_get_extension_string_for_isa_flags (p_to_a
->flags
)
233 /* We are going to memory leak here, nobody elsewhere
234 in the callchain is going to clean up after us. The alternative is
235 to allocate a static buffer, and assert that it is big enough for our
236 modified string, which seems much worse! */
237 return xstrdup (outstr
.c_str ());
240 /* Called by the driver to rewrite a name passed to the -mcpu
241 argument in preparation to be passed to the assembler. The
242 names passed from the commend line will be in ARGV, we want
243 to use the right-most argument, which should be in
244 ARGV[ARGC - 1]. ARGC should always be greater than 0. */
247 aarch64_rewrite_mcpu (int argc
, const char **argv
)
250 return aarch64_rewrite_selected_cpu (argv
[argc
- 1]);
253 #undef AARCH64_CPU_NAME_LENGTH