aarch64_feature_flags flags_on;
/* If this feature is turned off, these bits also need to be turned off. */
aarch64_feature_flags flags_off;
+ /* If this feature remains enabled, these bits must also remain enabled. */
+ aarch64_feature_flags flags_required;
};
/* ISA extensions in AArch64. */
{
#define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, FEATURE_STRING) \
{NAME, AARCH64_FL_##IDENT, feature_deps::IDENT ().explicit_on, \
- feature_deps::get_flags_off (feature_deps::root_off_##IDENT)},
+ feature_deps::get_flags_off (feature_deps::root_off_##IDENT), \
+ feature_deps::IDENT ().enable},
#include "config/aarch64/aarch64-option-extensions.def"
- {NULL, 0, 0, 0}
+ {NULL, 0, 0, 0, 0}
};
struct aarch64_arch_info
{NULL, aarch64_no_cpu, aarch64_no_arch, 0}
};
+/* Return the set of feature flags that are required to be enabled when the
+ features in FLAGS are enabled. */
+
+aarch64_feature_flags
+aarch64_get_required_features (aarch64_feature_flags flags)
+{
+ const struct aarch64_extension_info *opt;
+ for (opt = all_extensions; opt->name != NULL; opt++)
+ if (flags & opt->flag_canonical)
+ flags |= opt->flags_required;
+ return flags;
+}
/* Print a list of CANDIDATES for an argument, and try to suggest a specific
close match. */
#include "langhooks.h"
#include "gimple-iterator.h"
#include "case-cfn-macros.h"
+#include "regs.h"
#include "emit-rtl.h"
#include "stringpool.h"
#include "attribs.h"
return (t == Poly8_t || t == Poly16_t || t == Poly64_t || t == Poly128_t);
}
-/* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD
- set. */
-aarch64_simd_switcher::aarch64_simd_switcher (aarch64_feature_flags extra_flags)
+/* Temporarily set FLAGS as the enabled target features. */
+aarch64_target_switcher::aarch64_target_switcher (aarch64_feature_flags flags)
: m_old_asm_isa_flags (aarch64_asm_isa_flags),
- m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY)
+ m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY),
+ m_old_target_pragma (current_target_pragma)
{
- /* Changing the ISA flags should be enough here. We shouldn't need to
- pay the compile-time cost of a full target switch. */
- global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY;
- aarch64_set_asm_isa_flags (AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags);
+ /* Include all dependencies. */
+ flags = aarch64_get_required_features (flags);
+
+ /* Changing the ISA flags and have_regs_of_mode should be enough here. We
+ shouldn't need to pay the compile-time cost of a full target switch. */
+ if (flags & AARCH64_FL_FP)
+ global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY;
+ aarch64_set_asm_isa_flags (flags);
+
+ /* Target pragmas are irrelevant when defining intrinsics artificially. */
+ current_target_pragma = NULL_TREE;
+
+ /* Ensure SVE regs are available if SVE or SME is enabled. */
+ memcpy (m_old_have_regs_of_mode, have_regs_of_mode, sizeof
+ (have_regs_of_mode));
+ if (flags & (AARCH64_FL_SVE | AARCH64_FL_SME))
+ for (int i = 0; i < NUM_MACHINE_MODES; ++i)
+ if (aarch64_sve_mode_p ((machine_mode) i))
+ have_regs_of_mode[i] = true;
}
-aarch64_simd_switcher::~aarch64_simd_switcher ()
+aarch64_target_switcher::~aarch64_target_switcher ()
{
if (m_old_general_regs_only)
global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY;
aarch64_set_asm_isa_flags (m_old_asm_isa_flags);
+ current_target_pragma = m_old_target_pragma;
+
+ memcpy (have_regs_of_mode, m_old_have_regs_of_mode,
+ sizeof (have_regs_of_mode));
}
/* Implement #pragma GCC aarch64 "arm_neon.h".
void
handle_arm_neon_h (void)
{
- aarch64_simd_switcher simd;
+ aarch64_target_switcher switcher (AARCH64_FL_SIMD);
/* Register the AdvSIMD vector tuple types. */
for (unsigned int i = 0; i < ARM_NEON_H_TYPES_LAST; i++)
void
handle_arm_acle_h (void)
{
+ aarch64_target_switcher switcher;
+
aarch64_init_ls64_builtins ();
aarch64_init_tme_builtins ();
aarch64_init_memtag_builtins ();
aarch64_init_bf16_types ();
{
- aarch64_simd_switcher simd;
+ aarch64_target_switcher switcher (AARCH64_FL_SIMD);
aarch64_init_simd_builtins ();
}
/* RAII class for enabling enough features to define built-in types
and implement the arm_neon.h pragma. */
-class aarch64_simd_switcher
+class aarch64_target_switcher
{
public:
- aarch64_simd_switcher (aarch64_feature_flags extra_flags = 0);
- ~aarch64_simd_switcher ();
+ aarch64_target_switcher (aarch64_feature_flags flags = 0);
+ ~aarch64_target_switcher ();
private:
aarch64_feature_flags m_old_asm_isa_flags;
bool m_old_general_regs_only;
+ tree m_old_target_pragma;
+ bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
};
/* Represents the ISA requirements of an intrinsic function, or of some
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);
+aarch64_feature_flags aarch64_get_required_features (aarch64_feature_flags);
void aarch64_print_hint_for_extensions (const char *);
void aarch64_print_hint_for_arch (const char *);
void aarch64_print_hint_for_core (const char *);
#include "emit-rtl.h"
#include "tree-vector-builder.h"
#include "stor-layout.h"
-#include "regs.h"
#include "alias.h"
#include "gimple-fold.h"
#include "langhooks.h"
return value->instance == key;
}
-sve_switcher::sve_switcher (aarch64_feature_flags flags)
- : aarch64_simd_switcher (AARCH64_FL_F16 | AARCH64_FL_SVE | flags)
+sve_alignment_switcher::sve_alignment_switcher ()
{
- /* Changing the ISA flags and have_regs_of_mode should be enough here.
- We shouldn't need to pay the compile-time cost of a full target
- switch. */
m_old_maximum_field_alignment = maximum_field_alignment;
maximum_field_alignment = 0;
-
- memcpy (m_old_have_regs_of_mode, have_regs_of_mode,
- sizeof (have_regs_of_mode));
- for (int i = 0; i < NUM_MACHINE_MODES; ++i)
- if (aarch64_sve_mode_p ((machine_mode) i))
- have_regs_of_mode[i] = true;
}
-sve_switcher::~sve_switcher ()
+sve_alignment_switcher::~sve_alignment_switcher ()
{
- memcpy (have_regs_of_mode, m_old_have_regs_of_mode,
- sizeof (have_regs_of_mode));
maximum_field_alignment = m_old_maximum_field_alignment;
}
static void
register_builtin_types ()
{
+ sve_alignment_switcher switcher;
+
#define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
#include "aarch64-sve-builtins.def"
void
init_builtins ()
{
- sve_switcher sve;
+ aarch64_target_switcher switcher (AARCH64_FL_SVE);
register_builtin_types ();
if (in_lto_p)
{
return;
}
- sve_switcher sve;
+ aarch64_target_switcher switcher (AARCH64_FL_SVE);
+ sve_alignment_switcher alignment_switcher;
/* Define the vector and tuple types. */
for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
if (initial_indexes[arm_sme_handle] == 0)
handle_arm_sme_h (true);
+ aarch64_target_switcher switcher;
+
/* Define the functions. */
function_builder builder (arm_neon_sve_handle, function_nulls_p);
for (unsigned int i = 0; i < ARRAY_SIZE (neon_sve_function_groups); ++i)
return;
}
- sme_switcher sme;
+ aarch64_target_switcher switcher (AARCH64_FL_SME);
function_builder builder (arm_sme_handle, function_nulls_p);
for (unsigned int i = 0; i < ARRAY_SIZE (sme_function_groups); ++i)
virtual bool check (function_checker &) const { return true; }
};
-/* RAII class for enabling enough SVE features to define the built-in
- types and implement the arm_sve.h pragma. */
-class sve_switcher : public aarch64_simd_switcher
+/* RAII class for temporarily disabling the effect of any -fpack-struct option.
+ This is used to ensure that sve vector tuple types are defined with the
+ correct alignment. */
+class sve_alignment_switcher
{
public:
- sve_switcher (aarch64_feature_flags = 0);
- ~sve_switcher ();
+ sve_alignment_switcher ();
+ ~sve_alignment_switcher ();
private:
unsigned int m_old_maximum_field_alignment;
- bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
-};
-
-/* Extends sve_switch enough for defining arm_sme.h. */
-class sme_switcher : public sve_switcher
-{
-public:
- sme_switcher () : sve_switcher (AARCH64_FL_SME) {}
};
extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
s-mddeps: s-aarch64-tune-md
aarch64-builtins.o: $(srcdir)/config/aarch64/aarch64-builtins.cc $(CONFIG_H) \
- $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(REGS_H) \
$(RTL_H) $(TREE_H) expr.h $(TM_P_H) $(RECOG_H) langhooks.h \
$(DIAGNOSTIC_CORE_H) $(OPTABS_H) \
$(srcdir)/config/aarch64/aarch64-simd-builtins.def \
$(TM_P_H) memmodel.h insn-codes.h $(OPTABS_H) $(RECOG_H) $(DIAGNOSTIC_H) \
$(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) fold-const.h $(GIMPLE_H) \
gimple-iterator.h gimplify.h explow.h $(EMIT_RTL_H) tree-vector-builder.h \
- stor-layout.h $(REG_H) alias.h gimple-fold.h langhooks.h \
+ stor-layout.h alias.h gimple-fold.h langhooks.h \
stringpool.h \
$(srcdir)/config/aarch64/aarch64-sve-builtins.h \
$(srcdir)/config/aarch64/aarch64-sve-builtins-shapes.h \