@@ -31,6 +31,7 @@
#include "flags.h"
#include "diagnostic.h"
#include "config/aarch64/aarch64-feature-deps.h"
+#include "config/arm/aarch-common.h"
#ifdef TARGET_BIG_ENDIAN_DEFAULT
#undef TARGET_DEFAULT_TARGET_FLAGS
@@ -191,13 +192,13 @@ static constexpr arch_to_arch_name all_architectures[] =
/* Parse the architecture extension string STR and update ISA_FLAGS
with the architecture features turned on or off. Return a
- aarch64_parse_opt_result describing the result.
+ aarch_parse_opt_result describing the result.
When the STR string contains an invalid extension,
a copy of the string is created and stored to INVALID_EXTENSION. */
-enum aarch64_parse_opt_result
+enum aarch_parse_opt_result
aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
- std::string *invalid_extension)
+ std::string *invalid_extension)
{
/* The extension string is parsed left to right. */
const struct aarch64_option_extension *opt = NULL;
@@ -228,7 +229,7 @@ aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
adding_ext = 1;
if (len == 0)
- return AARCH64_PARSE_MISSING_ARG;
+ return AARCH_PARSE_MISSING_ARG;
/* Scan over the extensions table trying to find an exact match. */
@@ -250,13 +251,13 @@ aarch64_parse_extension (const char *str, aarch64_feature_flags *isa_flags,
/* Extension not found in list. */
if (invalid_extension)
*invalid_extension = std::string (str, len);
- return AARCH64_PARSE_INVALID_FEATURE;
+ return AARCH_PARSE_INVALID_FEATURE;
}
str = ext;
};
- return AARCH64_PARSE_OK;
+ return AARCH_PARSE_OK;
}
/* Append all architecture extension candidates to the CANDIDATES vector. */
@@ -183,14 +183,14 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
"__ARM_FEATURE_BTI_DEFAULT", pfile);
cpp_undef (pfile, "__ARM_FEATURE_PAC_DEFAULT");
- if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE)
+ if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
{
int v = 0;
- if (aarch64_ra_sign_key == AARCH64_KEY_A)
+ if (aarch_ra_sign_key == AARCH_KEY_A)
v |= 1;
- if (aarch64_ra_sign_key == AARCH64_KEY_B)
+ if (aarch_ra_sign_key == AARCH_KEY_B)
v |= 2;
- if (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL)
+ if (aarch_ra_sign_scope == AARCH_FUNCTION_ALL)
v |= 4;
builtin_define_with_int_value ("__ARM_FEATURE_PAC_DEFAULT", v);
}
@@ -75,16 +75,6 @@ enum aarch64_code_model {
AARCH64_CMODEL_LARGE
};
-/* Function types -msign-return-address should sign. */
-enum aarch64_function_type {
- /* Don't sign any function. */
- AARCH64_FUNCTION_NONE,
- /* Non-leaf functions. */
- AARCH64_FUNCTION_NON_LEAF,
- /* All functions. */
- AARCH64_FUNCTION_ALL
-};
-
/* SVE vector register sizes. */
enum aarch64_sve_vector_bits_enum {
SVE_SCALABLE,
@@ -23,6 +23,7 @@
#define GCC_AARCH64_PROTOS_H
#include "input.h"
+#include "config/arm/aarch-common.h"
/* SYMBOL_SMALL_ABSOLUTE: Generate symbol accesses through
high and lo relocs that calculate the base address using a PC
@@ -651,18 +652,6 @@ enum aarch64_extra_tuning_flags
AARCH64_EXTRA_TUNE_ALL = (1u << AARCH64_EXTRA_TUNE_index_END) - 1
};
-/* Enum describing the various ways that the
- aarch64_parse_{arch,tune,cpu,extension} functions can fail.
- This way their callers can choose what kind of error to give. */
-
-enum aarch64_parse_opt_result
-{
- AARCH64_PARSE_OK, /* Parsing was successful. */
- AARCH64_PARSE_MISSING_ARG, /* Missing argument. */
- AARCH64_PARSE_INVALID_FEATURE, /* Invalid feature modifier. */
- AARCH64_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */
-};
-
/* Enum to distinguish which type of check is to be done in
aarch64_simd_valid_immediate. This is used as a bitmask where
AARCH64_CHECK_MOV has both bits set. Thus AARCH64_CHECK_MOV will
@@ -673,6 +662,8 @@ enum simd_immediate_check {
AARCH64_CHECK_MOV = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC
};
+extern enum aarch_key_type aarch_ra_sign_key;
+
extern struct tune_params aarch64_tune_params;
/* The available SVE predicate patterns, known in the ACLE as "svpattern". */
@@ -1038,9 +1029,9 @@ void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags);
bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
const struct cl_decoded_option *, location_t);
const char *aarch64_rewrite_selected_cpu (const char *name);
-enum aarch64_parse_opt_result aarch64_parse_extension (const char *,
- aarch64_feature_flags *,
- std::string *);
+enum aarch_parse_opt_result aarch64_parse_extension (const char *,
+ aarch64_feature_flags *,
+ std::string *);
void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates);
std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags,
aarch64_feature_flags);
@@ -82,6 +82,8 @@
#include "tree-dfa.h"
#include "asan.h"
#include "aarch64-feature-deps.h"
+#include "config/arm/aarch-common.h"
+#include "config/arm/aarch-common-protos.h"
/* This file should be included last. */
#include "target-def.h"
@@ -318,12 +320,8 @@ bool aarch64_pcrelative_literal_loads;
/* Global flag for whether frame pointer is enabled. */
bool aarch64_use_frame_pointer;
-#define BRANCH_PROTECT_STR_MAX 255
char *accepted_branch_protection_string = NULL;
-static enum aarch64_parse_opt_result
-aarch64_parse_branch_protection (const char*, char**);
-
/* Support for command line parsing of boolean flags in the tuning
structures. */
struct aarch64_flag_desc
@@ -2761,6 +2759,8 @@ static const struct processor all_cores[] =
{NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL}
};
+enum aarch_key_type aarch_ra_sign_key = AARCH_KEY_A;
+
/* The current tuning set. */
struct tune_params aarch64_tune_params = generic_tunings;
@@ -2826,100 +2826,6 @@ aarch64_cc;
#define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1))
-struct aarch64_branch_protect_type
-{
- /* The type's name that the user passes to the branch-protection option
- string. */
- const char* name;
- /* Function to handle the protection type and set global variables.
- First argument is the string token corresponding with this type and the
- second argument is the next token in the option string.
- Return values:
- * AARCH64_PARSE_OK: Handling was sucessful.
- * AARCH64_INVALID_ARG: The type is invalid in this context and the caller
- should print an error.
- * AARCH64_INVALID_FEATURE: The type is invalid and the handler prints its
- own error. */
- enum aarch64_parse_opt_result (*handler)(char*, char*);
- /* A list of types that can follow this type in the option string. */
- const aarch64_branch_protect_type* subtypes;
- unsigned int num_subtypes;
-};
-
-static enum aarch64_parse_opt_result
-aarch64_handle_no_branch_protection (char* str, char* rest)
-{
- aarch64_ra_sign_scope = AARCH64_FUNCTION_NONE;
- aarch64_enable_bti = 0;
- if (rest)
- {
- error ("unexpected %<%s%> after %<%s%>", rest, str);
- return AARCH64_PARSE_INVALID_FEATURE;
- }
- return AARCH64_PARSE_OK;
-}
-
-static enum aarch64_parse_opt_result
-aarch64_handle_standard_branch_protection (char* str, char* rest)
-{
- aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
- aarch64_ra_sign_key = AARCH64_KEY_A;
- aarch64_enable_bti = 1;
- if (rest)
- {
- error ("unexpected %<%s%> after %<%s%>", rest, str);
- return AARCH64_PARSE_INVALID_FEATURE;
- }
- return AARCH64_PARSE_OK;
-}
-
-static enum aarch64_parse_opt_result
-aarch64_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
- char* rest ATTRIBUTE_UNUSED)
-{
- aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
- aarch64_ra_sign_key = AARCH64_KEY_A;
- return AARCH64_PARSE_OK;
-}
-
-static enum aarch64_parse_opt_result
-aarch64_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
- char* rest ATTRIBUTE_UNUSED)
-{
- aarch64_ra_sign_scope = AARCH64_FUNCTION_ALL;
- return AARCH64_PARSE_OK;
-}
-
-static enum aarch64_parse_opt_result
-aarch64_handle_pac_ret_b_key (char* str ATTRIBUTE_UNUSED,
- char* rest ATTRIBUTE_UNUSED)
-{
- aarch64_ra_sign_key = AARCH64_KEY_B;
- return AARCH64_PARSE_OK;
-}
-
-static enum aarch64_parse_opt_result
-aarch64_handle_bti_protection (char* str ATTRIBUTE_UNUSED,
- char* rest ATTRIBUTE_UNUSED)
-{
- aarch64_enable_bti = 1;
- return AARCH64_PARSE_OK;
-}
-
-static const struct aarch64_branch_protect_type aarch64_pac_ret_subtypes[] = {
- { "leaf", aarch64_handle_pac_ret_leaf, NULL, 0 },
- { "b-key", aarch64_handle_pac_ret_b_key, NULL, 0 },
- { NULL, NULL, NULL, 0 }
-};
-
-static const struct aarch64_branch_protect_type aarch64_branch_protect_types[] = {
- { "none", aarch64_handle_no_branch_protection, NULL, 0 },
- { "standard", aarch64_handle_standard_branch_protection, NULL, 0 },
- { "pac-ret", aarch64_handle_pac_ret_protection, aarch64_pac_ret_subtypes,
- ARRAY_SIZE (aarch64_pac_ret_subtypes) },
- { "bti", aarch64_handle_bti_protection, NULL, 0 },
- { NULL, NULL, NULL, 0 }
-};
/* The condition codes of the processor, and the inverse function. */
static const char * const aarch64_condition_codes[] =
@@ -8893,10 +8799,10 @@ aarch64_return_address_signing_enabled (void)
if (crtl->calls_eh_return)
return false;
- /* If signing scope is AARCH64_FUNCTION_NON_LEAF, we only sign a leaf function
+ /* If signing scope is AARCH_FUNCTION_NON_LEAF, we only sign a leaf function
if its LR is pushed onto stack. */
- return (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL
- || (aarch64_ra_sign_scope == AARCH64_FUNCTION_NON_LEAF
+ return (aarch_ra_sign_scope == AARCH_FUNCTION_ALL
+ || (aarch_ra_sign_scope == AARCH_FUNCTION_NON_LEAF
&& known_ge (cfun->machine->frame.reg_offset[LR_REGNUM], 0)));
}
@@ -8904,7 +8810,7 @@ aarch64_return_address_signing_enabled (void)
bool
aarch64_bti_enabled (void)
{
- return (aarch64_enable_bti == 1);
+ return (aarch_enable_bti == 1);
}
/* The caller is going to use ST1D or LD1D to save or restore an SVE
@@ -9896,12 +9802,12 @@ aarch64_expand_prologue (void)
/* Sign return address for functions. */
if (aarch64_return_address_signing_enabled ())
{
- switch (aarch64_ra_sign_key)
+ switch (aarch_ra_sign_key)
{
- case AARCH64_KEY_A:
+ case AARCH_KEY_A:
insn = emit_insn (gen_paciasp ());
break;
- case AARCH64_KEY_B:
+ case AARCH_KEY_B:
insn = emit_insn (gen_pacibsp ());
break;
default:
@@ -10202,12 +10108,12 @@ aarch64_expand_epilogue (bool for_sibcall)
if (aarch64_return_address_signing_enabled ()
&& (for_sibcall || !TARGET_ARMV8_3))
{
- switch (aarch64_ra_sign_key)
+ switch (aarch_ra_sign_key)
{
- case AARCH64_KEY_A:
+ case AARCH_KEY_A:
insn = emit_insn (gen_autiasp ());
break;
- case AARCH64_KEY_B:
+ case AARCH_KEY_B:
insn = emit_insn (gen_autibsp ());
break;
default:
@@ -17222,12 +17128,12 @@ static void initialize_aarch64_code_model (struct gcc_options *);
/* Parse the TO_PARSE string and put the architecture struct that it
selects into RES and the architectural features into ISA_FLAGS.
- Return an aarch64_parse_opt_result describing the parse result.
+ Return an aarch_parse_opt_result describing the parse result.
If there is an error parsing, RES and ISA_FLAGS are left unchanged.
When the TO_PARSE string contains an invalid extension,
a copy of the string is created and stored to INVALID_EXTENSION. */
-static enum aarch64_parse_opt_result
+static enum aarch_parse_opt_result
aarch64_parse_arch (const char *to_parse, const struct processor **res,
aarch64_feature_flags *isa_flags,
std::string *invalid_extension)
@@ -17244,7 +17150,7 @@ aarch64_parse_arch (const char *to_parse, const struct processor **res,
len = strlen (to_parse);
if (len == 0)
- return AARCH64_PARSE_MISSING_ARG;
+ return AARCH_PARSE_MISSING_ARG;
/* Loop through the list of supported ARCHes to find a match. */
@@ -17258,32 +17164,32 @@ aarch64_parse_arch (const char *to_parse, const struct processor **res,
if (ext != NULL)
{
/* TO_PARSE string contains at least one extension. */
- enum aarch64_parse_opt_result ext_res
+ enum aarch_parse_opt_result ext_res
= aarch64_parse_extension (ext, &isa_temp, invalid_extension);
- if (ext_res != AARCH64_PARSE_OK)
+ if (ext_res != AARCH_PARSE_OK)
return ext_res;
}
/* Extension parsing was successful. Confirm the result
arch and ISA flags. */
*res = arch;
*isa_flags = isa_temp;
- return AARCH64_PARSE_OK;
+ return AARCH_PARSE_OK;
}
}
/* ARCH name not found in list. */
- return AARCH64_PARSE_INVALID_ARG;
+ return AARCH_PARSE_INVALID_ARG;
}
/* Parse the TO_PARSE string and put the result tuning in RES and the
- architecture flags in ISA_FLAGS. Return an aarch64_parse_opt_result
+ architecture flags in ISA_FLAGS. Return an aarch_parse_opt_result
describing the parse result. If there is an error parsing, RES and
ISA_FLAGS are left unchanged.
When the TO_PARSE string contains an invalid extension,
a copy of the string is created and stored to INVALID_EXTENSION. */
-static enum aarch64_parse_opt_result
+static enum aarch_parse_opt_result
aarch64_parse_cpu (const char *to_parse, const struct processor **res,
aarch64_feature_flags *isa_flags,
std::string *invalid_extension)
@@ -17300,7 +17206,7 @@ aarch64_parse_cpu (const char *to_parse, const struct processor **res,
len = strlen (to_parse);
if (len == 0)
- return AARCH64_PARSE_MISSING_ARG;
+ return AARCH_PARSE_MISSING_ARG;
/* Loop through the list of supported CPUs to find a match. */
@@ -17313,29 +17219,29 @@ aarch64_parse_cpu (const char *to_parse, const struct processor **res,
if (ext != NULL)
{
/* TO_PARSE string contains at least one extension. */
- enum aarch64_parse_opt_result ext_res
+ enum aarch_parse_opt_result ext_res
= aarch64_parse_extension (ext, &isa_temp, invalid_extension);
- if (ext_res != AARCH64_PARSE_OK)
+ if (ext_res != AARCH_PARSE_OK)
return ext_res;
}
/* Extension parsing was successfull. Confirm the result
cpu and ISA flags. */
*res = cpu;
*isa_flags = isa_temp;
- return AARCH64_PARSE_OK;
+ return AARCH_PARSE_OK;
}
}
/* CPU name not found in list. */
- return AARCH64_PARSE_INVALID_ARG;
+ return AARCH_PARSE_INVALID_ARG;
}
/* Parse the TO_PARSE string and put the cpu it selects into RES.
- Return an aarch64_parse_opt_result describing the parse result.
+ Return an aarch_parse_opt_result describing the parse result.
If the parsing fails the RES does not change. */
-static enum aarch64_parse_opt_result
+static enum aarch_parse_opt_result
aarch64_parse_tune (const char *to_parse, const struct processor **res)
{
const struct processor *cpu;
@@ -17346,12 +17252,12 @@ aarch64_parse_tune (const char *to_parse, const struct processor **res)
if (strcmp (cpu->name, to_parse) == 0)
{
*res = cpu;
- return AARCH64_PARSE_OK;
+ return AARCH_PARSE_OK;
}
}
/* CPU name not found in list. */
- return AARCH64_PARSE_INVALID_ARG;
+ return AARCH_PARSE_INVALID_ARG;
}
/* Parse TOKEN, which has length LENGTH to see if it is an option
@@ -17942,22 +17848,22 @@ aarch64_validate_mcpu (const char *str, const struct processor **res,
aarch64_feature_flags *isa_flags)
{
std::string invalid_extension;
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_cpu (str, res, isa_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
return true;
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing cpu name in %<-mcpu=%s%>", str);
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("unknown value %qs for %<-mcpu%>", str);
aarch64_print_hint_for_core (str);
break;
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
error ("invalid feature modifier %qs in %<-mcpu=%s%>",
invalid_extension.c_str (), str);
aarch64_print_hint_for_extensions (invalid_extension);
@@ -18042,110 +17948,6 @@ aarch64_validate_sls_mitigation (const char *const_str)
free (str_root);
}
-/* Parses CONST_STR for branch protection features specified in
- aarch64_branch_protect_types, and set any global variables required. Returns
- the parsing result and assigns LAST_STR to the last processed token from
- CONST_STR so that it can be used for error reporting. */
-
-static enum
-aarch64_parse_opt_result aarch64_parse_branch_protection (const char *const_str,
- char** last_str)
-{
- char *str_root = xstrdup (const_str);
- char* token_save = NULL;
- char *str = strtok_r (str_root, "+", &token_save);
- enum aarch64_parse_opt_result res = AARCH64_PARSE_OK;
- if (!str)
- res = AARCH64_PARSE_MISSING_ARG;
- else
- {
- char *next_str = strtok_r (NULL, "+", &token_save);
- /* Reset the branch protection features to their defaults. */
- aarch64_handle_no_branch_protection (NULL, NULL);
-
- while (str && res == AARCH64_PARSE_OK)
- {
- const aarch64_branch_protect_type* type = aarch64_branch_protect_types;
- bool found = false;
- /* Search for this type. */
- while (type && type->name && !found && res == AARCH64_PARSE_OK)
- {
- if (strcmp (str, type->name) == 0)
- {
- found = true;
- res = type->handler (str, next_str);
- str = next_str;
- next_str = strtok_r (NULL, "+", &token_save);
- }
- else
- type++;
- }
- if (found && res == AARCH64_PARSE_OK)
- {
- bool found_subtype = true;
- /* Loop through each token until we find one that isn't a
- subtype. */
- while (found_subtype)
- {
- found_subtype = false;
- const aarch64_branch_protect_type *subtype = type->subtypes;
- /* Search for the subtype. */
- while (str && subtype && subtype->name && !found_subtype
- && res == AARCH64_PARSE_OK)
- {
- if (strcmp (str, subtype->name) == 0)
- {
- found_subtype = true;
- res = subtype->handler (str, next_str);
- str = next_str;
- next_str = strtok_r (NULL, "+", &token_save);
- }
- else
- subtype++;
- }
- }
- }
- else if (!found)
- res = AARCH64_PARSE_INVALID_ARG;
- }
- }
- /* Copy the last processed token into the argument to pass it back.
- Used by option and attribute validation to print the offending token. */
- if (last_str)
- {
- if (str) strcpy (*last_str, str);
- else *last_str = NULL;
- }
- if (res == AARCH64_PARSE_OK)
- {
- /* If needed, alloc the accepted string then copy in const_str.
- Used by override_option_after_change_1. */
- if (!accepted_branch_protection_string)
- accepted_branch_protection_string = (char *) xmalloc (
- BRANCH_PROTECT_STR_MAX
- + 1);
- strncpy (accepted_branch_protection_string, const_str,
- BRANCH_PROTECT_STR_MAX + 1);
- /* Forcibly null-terminate. */
- accepted_branch_protection_string[BRANCH_PROTECT_STR_MAX] = '\0';
- }
- return res;
-}
-
-static bool
-aarch64_validate_mbranch_protection (const char *const_str)
-{
- char *str = (char *) xmalloc (strlen (const_str));
- enum aarch64_parse_opt_result res =
- aarch64_parse_branch_protection (const_str, &str);
- if (res == AARCH64_PARSE_INVALID_ARG)
- error ("invalid argument %<%s%> for %<-mbranch-protection=%>", str);
- else if (res == AARCH64_PARSE_MISSING_ARG)
- error ("missing argument for %<-mbranch-protection=%>");
- free (str);
- return res == AARCH64_PARSE_OK;
-}
-
/* Validate a command-line -march option. Parse the arch and extensions
(if any) specified in STR and throw errors if appropriate. Put the
results, if they are valid, in RES and ISA_FLAGS. Return whether the
@@ -18156,27 +17958,27 @@ aarch64_validate_march (const char *str, const struct processor **res,
aarch64_feature_flags *isa_flags)
{
std::string invalid_extension;
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_arch (str, res, isa_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
return true;
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing arch name in %<-march=%s%>", str);
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("unknown value %qs for %<-march%>", str);
aarch64_print_hint_for_arch (str);
/* A common user error is confusing -march and -mcpu.
If the -march string matches a known CPU suggest -mcpu. */
parse_res = aarch64_parse_cpu (str, res, isa_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
inform (input_location, "did you mean %<-mcpu=%s%>?", str);
break;
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
error ("invalid feature modifier %qs in %<-march=%s%>",
invalid_extension.c_str (), str);
aarch64_print_hint_for_extensions (invalid_extension);
@@ -18196,18 +17998,18 @@ aarch64_validate_march (const char *str, const struct processor **res,
static bool
aarch64_validate_mtune (const char *str, const struct processor **res)
{
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_tune (str, res);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
return true;
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing cpu name in %<-mtune=%s%>", str);
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("unknown value %qs for %<-mtune%>", str);
aarch64_print_hint_for_core (str);
break;
@@ -18269,7 +18071,7 @@ aarch64_override_options (void)
aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
if (aarch64_branch_protection_string)
- aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
+ aarch_validate_mbranch_protection (aarch64_branch_protection_string);
/* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU.
If either of -march or -mtune is given, they override their
@@ -18322,12 +18124,12 @@ aarch64_override_options (void)
selected_tune = tune ? tune->ident : cpu->ident;
- if (aarch64_enable_bti == 2)
+ if (aarch_enable_bti == 2)
{
#ifdef TARGET_ENABLE_BTI
- aarch64_enable_bti = 1;
+ aarch_enable_bti = 1;
#else
- aarch64_enable_bti = 0;
+ aarch_enable_bti = 0;
#endif
}
@@ -18337,9 +18139,9 @@ aarch64_override_options (void)
if (!TARGET_ILP32 && accepted_branch_protection_string == NULL)
{
#ifdef TARGET_ENABLE_PAC_RET
- aarch64_ra_sign_scope = AARCH64_FUNCTION_NON_LEAF;
+ aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
#else
- aarch64_ra_sign_scope = AARCH64_FUNCTION_NONE;
+ aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
#endif
}
@@ -18353,7 +18155,7 @@ aarch64_override_options (void)
/* Convert -msve-vector-bits to a VG count. */
aarch64_sve_vg = aarch64_convert_sve_vector_bits (aarch64_sve_vector_bits);
- if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE && TARGET_ILP32)
+ if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE && TARGET_ILP32)
sorry ("return address signing is only supported for %<-mabi=lp64%>");
/* The pass to insert speculation tracking runs before
@@ -18568,10 +18370,10 @@ aarch64_handle_attr_arch (const char *str)
const struct processor *tmp_arch = NULL;
std::string invalid_extension;
aarch64_feature_flags tmp_flags;
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_arch (str, &tmp_arch, &tmp_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
{
gcc_assert (tmp_arch);
selected_arch = tmp_arch->arch;
@@ -18581,14 +18383,14 @@ aarch64_handle_attr_arch (const char *str)
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing name in %<target(\"arch=\")%> pragma or attribute");
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("invalid name %qs in %<target(\"arch=\")%> pragma or attribute", str);
aarch64_print_hint_for_arch (str);
break;
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
error ("invalid feature modifier %s of value %qs in "
"%<target()%> pragma or attribute", invalid_extension.c_str (), str);
aarch64_print_hint_for_extensions (invalid_extension);
@@ -18608,10 +18410,10 @@ aarch64_handle_attr_cpu (const char *str)
const struct processor *tmp_cpu = NULL;
std::string invalid_extension;
aarch64_feature_flags tmp_flags;
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_cpu (str, &tmp_cpu, &tmp_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
{
gcc_assert (tmp_cpu);
selected_tune = tmp_cpu->ident;
@@ -18622,14 +18424,14 @@ aarch64_handle_attr_cpu (const char *str)
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing name in %<target(\"cpu=\")%> pragma or attribute");
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("invalid name %qs in %<target(\"cpu=\")%> pragma or attribute", str);
aarch64_print_hint_for_core (str);
break;
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
error ("invalid feature modifier %qs of value %qs in "
"%<target()%> pragma or attribute", invalid_extension.c_str (), str);
aarch64_print_hint_for_extensions (invalid_extension);
@@ -18647,23 +18449,23 @@ aarch64_handle_attr_cpu (const char *str)
aarch64_handle_attr_branch_protection (const char* str)
{
char *err_str = (char *) xmalloc (strlen (str) + 1);
- enum aarch64_parse_opt_result res = aarch64_parse_branch_protection (str,
- &err_str);
+ enum aarch_parse_opt_result res = aarch_parse_branch_protection (str,
+ &err_str);
bool success = false;
switch (res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing argument to %<target(\"branch-protection=\")%> pragma or"
" attribute");
break;
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("invalid protection type %qs in %<target(\"branch-protection"
"=\")%> pragma or attribute", err_str);
break;
- case AARCH64_PARSE_OK:
+ case AARCH_PARSE_OK:
success = true;
/* Fall through. */
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
break;
default:
gcc_unreachable ();
@@ -18678,10 +18480,10 @@ static bool
aarch64_handle_attr_tune (const char *str)
{
const struct processor *tmp_tune = NULL;
- enum aarch64_parse_opt_result parse_res
+ enum aarch_parse_opt_result parse_res
= aarch64_parse_tune (str, &tmp_tune);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
{
gcc_assert (tmp_tune);
selected_tune = tmp_tune->ident;
@@ -18690,7 +18492,7 @@ aarch64_handle_attr_tune (const char *str)
switch (parse_res)
{
- case AARCH64_PARSE_INVALID_ARG:
+ case AARCH_PARSE_INVALID_ARG:
error ("invalid name %qs in %<target(\"tune=\")%> pragma or attribute", str);
aarch64_print_hint_for_core (str);
break;
@@ -18709,7 +18511,7 @@ aarch64_handle_attr_tune (const char *str)
static bool
aarch64_handle_attr_isa_flags (char *str)
{
- enum aarch64_parse_opt_result parse_res;
+ enum aarch_parse_opt_result parse_res;
auto isa_flags = aarch64_asm_isa_flags;
/* We allow "+nothing" in the beginning to clear out all architectural
@@ -18723,7 +18525,7 @@ aarch64_handle_attr_isa_flags (char *str)
std::string invalid_extension;
parse_res = aarch64_parse_extension (str, &isa_flags, &invalid_extension);
- if (parse_res == AARCH64_PARSE_OK)
+ if (parse_res == AARCH_PARSE_OK)
{
aarch64_set_asm_isa_flags (isa_flags);
return true;
@@ -18731,11 +18533,11 @@ aarch64_handle_attr_isa_flags (char *str)
switch (parse_res)
{
- case AARCH64_PARSE_MISSING_ARG:
+ case AARCH_PARSE_MISSING_ARG:
error ("missing value in %<target()%> pragma or attribute");
break;
- case AARCH64_PARSE_INVALID_FEATURE:
+ case AARCH_PARSE_INVALID_FEATURE:
error ("invalid feature modifier %qs of value %qs in "
"%<target()%> pragma or attribute", invalid_extension.c_str (), str);
break;
@@ -18984,10 +18786,10 @@ aarch64_process_target_attr (tree args)
leading '+'. */
aarch64_feature_flags isa_temp = 0;
auto with_plus = std::string ("+") + token;
- enum aarch64_parse_opt_result ext_res
+ enum aarch_parse_opt_result ext_res
= aarch64_parse_extension (with_plus.c_str (), &isa_temp, nullptr);
- if (ext_res == AARCH64_PARSE_OK)
+ if (ext_res == AARCH_PARSE_OK)
error ("arch extension %<%s%> should be prefixed by %<+%>",
token);
else
@@ -22753,7 +22555,7 @@ void
aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
{
if (cfun->machine->frame.laid_out && aarch64_return_address_signing_enabled ()
- && aarch64_ra_sign_key == AARCH64_KEY_B)
+ && aarch_ra_sign_key == AARCH_KEY_B)
asm_fprintf (f, "\t.cfi_b_key_frame\n");
}
@@ -27163,7 +26965,7 @@ aarch64_file_end_indicate_exec_stack ()
if (aarch64_bti_enabled ())
feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
- if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE)
+ if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE)
feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
if (feature_1_and)
@@ -891,7 +891,7 @@ (define_insn "*do_return"
if (aarch64_return_address_signing_enabled ()
&& (TARGET_PAUTH))
{
- if (aarch64_ra_sign_key == AARCH64_KEY_B)
+ if (aarch_ra_sign_key == AARCH_KEY_B)
ret = "retab";
else
ret = "retaa";
@@ -21,6 +21,9 @@
HeaderInclude
config/aarch64/aarch64-opts.h
+HeaderInclude
+config/arm/aarch-common.h
+
TargetVariable
enum aarch64_processor selected_tune = aarch64_none
@@ -34,7 +37,7 @@ TargetVariable
aarch64_feature_flags aarch64_isa_flags = 0
TargetVariable
-unsigned aarch64_enable_bti = 2
+unsigned aarch_enable_bti = 2
TargetVariable
enum aarch64_key_type aarch64_ra_sign_key = AARCH64_KEY_A
@@ -164,21 +167,21 @@ Target RejectNegative Joined Var(aarch64_branch_protection_string) Save
Use branch-protection features.
msign-return-address=
-Target WarnRemoved RejectNegative Joined Enum(aarch64_ra_sign_scope_t) Var(aarch64_ra_sign_scope) Init(AARCH64_FUNCTION_NONE) Save
+Target WarnRemoved RejectNegative Joined Enum(aarch_ra_sign_scope_t) Var(aarch_ra_sign_scope) Init(AARCH_FUNCTION_NONE) Save
Select return address signing scope.
Enum
-Name(aarch64_ra_sign_scope_t) Type(enum aarch64_function_type)
+Name(aarch_ra_sign_scope_t) Type(enum aarch_function_type)
Supported AArch64 return address signing scope (for use with -msign-return-address= option):
EnumValue
-Enum(aarch64_ra_sign_scope_t) String(none) Value(AARCH64_FUNCTION_NONE)
+Enum(aarch_ra_sign_scope_t) String(none) Value(AARCH_FUNCTION_NONE)
EnumValue
-Enum(aarch64_ra_sign_scope_t) String(non-leaf) Value(AARCH64_FUNCTION_NON_LEAF)
+Enum(aarch_ra_sign_scope_t) String(non-leaf) Value(AARCH_FUNCTION_NON_LEAF)
EnumValue
-Enum(aarch64_ra_sign_scope_t) String(all) Value(AARCH64_FUNCTION_ALL)
+Enum(aarch_ra_sign_scope_t) String(all) Value(AARCH_FUNCTION_ALL)
mlow-precision-recip-sqrt
Target Var(flag_mrecip_low_precision_sqrt) Optimization
@@ -153,4 +153,10 @@ rtx_insn *arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
location_t loc);
+/* Parsing routine for branch-protection common to AArch64 and Arm. */
+enum aarch_parse_opt_result aarch_parse_branch_protection (const char*, char**);
+
+/* Validation routine for branch-protection common to AArch64 and Arm. */
+bool aarch_validate_mbranch_protection (const char *);
+
#endif /* GCC_AARCH_COMMON_PROTOS_H */
@@ -36,6 +36,7 @@
#include "expr.h"
#include "function.h"
#include "emit-rtl.h"
+#include "aarch-common.h"
/* Return TRUE if X is either an arithmetic shift left, or
is a multiplication by a power of two. */
@@ -657,3 +658,187 @@ arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
return saw_asm_flag ? seq : NULL;
}
+
+#define BRANCH_PROTECT_STR_MAX 255
+extern char *accepted_branch_protection_string;
+extern enum aarch_key_type aarch_ra_sign_key;
+
+static enum aarch_parse_opt_result
+aarch_handle_no_branch_protection (char* str, char* rest)
+{
+ aarch_ra_sign_scope = AARCH_FUNCTION_NONE;
+ aarch_enable_bti = 0;
+ if (rest)
+ {
+ error ("unexpected %<%s%> after %<%s%>", rest, str);
+ return AARCH_PARSE_INVALID_FEATURE;
+ }
+ return AARCH_PARSE_OK;
+}
+
+static enum aarch_parse_opt_result
+aarch_handle_standard_branch_protection (char* str, char* rest)
+{
+ aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+ aarch_ra_sign_key = AARCH_KEY_A;
+ aarch_enable_bti = 1;
+ if (rest)
+ {
+ error ("unexpected %<%s%> after %<%s%>", rest, str);
+ return AARCH_PARSE_INVALID_FEATURE;
+ }
+ return AARCH_PARSE_OK;
+}
+
+static enum aarch_parse_opt_result
+aarch_handle_pac_ret_protection (char* str ATTRIBUTE_UNUSED,
+ char* rest ATTRIBUTE_UNUSED)
+{
+ aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF;
+ aarch_ra_sign_key = AARCH_KEY_A;
+ return AARCH_PARSE_OK;
+}
+
+static enum aarch_parse_opt_result
+aarch_handle_pac_ret_leaf (char* str ATTRIBUTE_UNUSED,
+ char* rest ATTRIBUTE_UNUSED)
+{
+ aarch_ra_sign_scope = AARCH_FUNCTION_ALL;
+ return AARCH_PARSE_OK;
+}
+
+static enum aarch_parse_opt_result
+aarch_handle_pac_ret_b_key (char* str ATTRIBUTE_UNUSED,
+ char* rest ATTRIBUTE_UNUSED)
+{
+ aarch_ra_sign_key = AARCH_KEY_B;
+ return AARCH_PARSE_OK;
+}
+
+static enum aarch_parse_opt_result
+aarch_handle_bti_protection (char* str ATTRIBUTE_UNUSED,
+ char* rest ATTRIBUTE_UNUSED)
+{
+ aarch_enable_bti = 1;
+ return AARCH_PARSE_OK;
+}
+
+static const struct aarch_branch_protect_type aarch_pac_ret_subtypes[] = {
+ { "leaf", aarch_handle_pac_ret_leaf, NULL, 0 },
+ { "b-key", aarch_handle_pac_ret_b_key, NULL, 0 },
+ { NULL, NULL, NULL, 0 }
+};
+
+static const struct aarch_branch_protect_type aarch_branch_protect_types[] = {
+ { "none", aarch_handle_no_branch_protection, NULL, 0 },
+ { "standard", aarch_handle_standard_branch_protection, NULL, 0 },
+ { "pac-ret", aarch_handle_pac_ret_protection, aarch_pac_ret_subtypes,
+ ARRAY_SIZE (aarch_pac_ret_subtypes) },
+ { "bti", aarch_handle_bti_protection, NULL, 0 },
+ { NULL, NULL, NULL, 0 }
+};
+
+/* Parses CONST_STR for branch protection features specified in
+ aarch64_branch_protect_types, and set any global variables required. Returns
+ the parsing result and assigns LAST_STR to the last processed token from
+ CONST_STR so that it can be used for error reporting. */
+
+enum aarch_parse_opt_result
+aarch_parse_branch_protection (const char *const_str, char** last_str)
+{
+ char *str_root = xstrdup (const_str);
+ char* token_save = NULL;
+ char *str = strtok_r (str_root, "+", &token_save);
+ enum aarch_parse_opt_result res = AARCH_PARSE_OK;
+ if (!str)
+ res = AARCH_PARSE_MISSING_ARG;
+ else
+ {
+ char *next_str = strtok_r (NULL, "+", &token_save);
+ /* Reset the branch protection features to their defaults. */
+ aarch_handle_no_branch_protection (NULL, NULL);
+
+ while (str && res == AARCH_PARSE_OK)
+ {
+ const aarch_branch_protect_type* type = aarch_branch_protect_types;
+ bool found = false;
+ /* Search for this type. */
+ while (type && type->name && !found && res == AARCH_PARSE_OK)
+ {
+ if (strcmp (str, type->name) == 0)
+ {
+ found = true;
+ res = type->handler (str, next_str);
+ str = next_str;
+ next_str = strtok_r (NULL, "+", &token_save);
+ }
+ else
+ type++;
+ }
+ if (found && res == AARCH_PARSE_OK)
+ {
+ bool found_subtype = true;
+ /* Loop through each token until we find one that isn't a
+ subtype. */
+ while (found_subtype)
+ {
+ found_subtype = false;
+ const aarch_branch_protect_type *subtype = type->subtypes;
+ /* Search for the subtype. */
+ while (str && subtype && subtype->name && !found_subtype
+ && res == AARCH_PARSE_OK)
+ {
+ if (strcmp (str, subtype->name) == 0)
+ {
+ found_subtype = true;
+ res = subtype->handler (str, next_str);
+ str = next_str;
+ next_str = strtok_r (NULL, "+", &token_save);
+ }
+ else
+ subtype++;
+ }
+ }
+ }
+ else if (!found)
+ res = AARCH_PARSE_INVALID_ARG;
+ }
+ }
+ /* Copy the last processed token into the argument to pass it back.
+ Used by option and attribute validation to print the offending token. */
+ if (last_str)
+ {
+ if (str)
+ strcpy (*last_str, str);
+ else
+ *last_str = NULL;
+ }
+
+ if (res == AARCH_PARSE_OK)
+ {
+ /* If needed, alloc the accepted string then copy in const_str.
+ Used by override_option_after_change_1. */
+ if (!accepted_branch_protection_string)
+ accepted_branch_protection_string
+ = (char *) xmalloc (BRANCH_PROTECT_STR_MAX + 1);
+ strncpy (accepted_branch_protection_string, const_str,
+ BRANCH_PROTECT_STR_MAX + 1);
+ /* Forcibly null-terminate. */
+ accepted_branch_protection_string[BRANCH_PROTECT_STR_MAX] = '\0';
+ }
+ return res;
+}
+
+bool
+aarch_validate_mbranch_protection (const char *const_str)
+{
+ char *str = (char *) xmalloc (strlen (const_str));
+ enum aarch_parse_opt_result res =
+ aarch_parse_branch_protection (const_str, &str);
+ if (res == AARCH_PARSE_INVALID_ARG)
+ error ("invalid argument %<%s%> for %<-mbranch-protection=%>", str);
+ else if (res == AARCH_PARSE_MISSING_ARG)
+ error ("missing argument for %<-mbranch-protection=%>");
+ free (str);
+ return res == AARCH_PARSE_OK;
+}
new file mode 100644
@@ -0,0 +1,73 @@
+/* Types shared between arm and aarch64.
+
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
+ Contributed by Arm Ltd.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_AARCH_COMMON_H
+#define GCC_AARCH_COMMON_H
+
+/* Enum describing the various ways that the
+ aarch*_parse_{arch,tune,cpu,extension} functions can fail.
+ This way their callers can choose what kind of error to give. */
+
+enum aarch_parse_opt_result
+{
+ AARCH_PARSE_OK, /* Parsing was successful. */
+ AARCH_PARSE_MISSING_ARG, /* Missing argument. */
+ AARCH_PARSE_INVALID_FEATURE, /* Invalid feature modifier. */
+ AARCH_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */
+};
+
+/* Function types -msign-return-address should sign. */
+enum aarch_function_type {
+ /* Don't sign any function. */
+ AARCH_FUNCTION_NONE,
+ /* Non-leaf functions. */
+ AARCH_FUNCTION_NON_LEAF,
+ /* All functions. */
+ AARCH_FUNCTION_ALL
+};
+
+/* The key type that -msign-return-address should use. */
+enum aarch_key_type {
+ AARCH_KEY_A,
+ AARCH_KEY_B
+};
+
+struct aarch_branch_protect_type
+{
+ /* The type's name that the user passes to the branch-protection option
+ string. */
+ const char* name;
+ /* Function to handle the protection type and set global variables.
+ First argument is the string token corresponding with this type and the
+ second argument is the next token in the option string.
+ Return values:
+ * AARCH_PARSE_OK: Handling was sucessful.
+ * AARCH_INVALID_ARG: The type is invalid in this context and the caller
+ should print an error.
+ * AARCH_INVALID_FEATURE: The type is invalid and the handler prints its
+ own error. */
+ enum aarch_parse_opt_result (*handler)(char*, char*);
+ /* A list of types that can follow this type in the option string. */
+ const struct aarch_branch_protect_type* subtypes;
+ unsigned int num_subtypes;
+};
+
+#endif /* GCC_AARCH_COMMON_H */
@@ -581,6 +581,8 @@ struct cpu_option
extern const arch_option all_architectures[];
extern const cpu_option all_cores[];
+extern enum aarch_key_type aarch_ra_sign_key;
+
const cpu_option *arm_parse_cpu_option_name (const cpu_option *, const char *,
const char *, bool = true);
const arch_option *arm_parse_arch_option_name (const arch_option *,
@@ -72,6 +72,8 @@
#include "selftest.h"
#include "tree-vectorizer.h"
#include "opts.h"
+#include "aarch-common.h"
+#include "aarch-common-protos.h"
/* This file should be included last. */
#include "target-def.h"
@@ -2413,6 +2415,11 @@ const struct tune_params arm_fa726te_tune =
tune_params::SCHED_AUTOPREF_OFF
};
+/* Key type for Pointer Authentication extension. */
+enum aarch_key_type aarch_ra_sign_key = AARCH_KEY_A;
+
+char *accepted_branch_protection_string = NULL;
+
/* Auto-generated CPU, FPU and architecture tables. */
#include "arm-cpu-data.h"
@@ -21,6 +21,15 @@
HeaderInclude
config/arm/arm-opts.h
+HeaderInclude
+config/arm/aarch-common.h
+
+TargetVariable
+enum aarch_function_type aarch_ra_sign_scope = AARCH_FUNCTION_NONE
+
+TargetVariable
+unsigned aarch_enable_bti = 0
+
Enum
Name(tls_type) Type(enum arm_tls_type)
TLS dialect to use: