sm_on ? sm_on | flags : 0 };
}
+ /* Return a requirement that is as restrictive as possible while still being
+ no more restrictive than THIS and no more restrictive than OTHER. */
+ inline CONSTEXPR aarch64_required_extensions
+ common_denominator (const aarch64_required_extensions &other)
+ {
+ return { sm_off && other.sm_off
+ ? sm_off & other.sm_off
+ : sm_off | other.sm_off,
+ sm_on && other.sm_on
+ ? sm_on & other.sm_on
+ : sm_on | other.sm_on };
+ }
+
/* Require non-streaming mode and the features in FLAGS. */
static inline CONSTEXPR aarch64_required_extensions
nonstreaming_only (aarch64_feature_flags flags)
DEF_SVE_FUNCTION (svldnf1ub, load_ext, hsd_integer, implicit)
DEF_SVE_FUNCTION (svldnf1uh, load_ext, sd_integer, implicit)
DEF_SVE_FUNCTION (svldnf1uw, load_ext, d_integer, implicit)
-DEF_SVE_FUNCTION (svmmla, mmla, none, none)
DEF_SVE_FUNCTION (svprfb_gather, prefetch_gather_offset, none, implicit)
DEF_SVE_FUNCTION (svprfd_gather, prefetch_gather_index, none, implicit)
DEF_SVE_FUNCTION (svprfh_gather, prefetch_gather_index, none, implicit)
build (function_builder &b, const function_group_info &group) const override
{
b.add_overloaded_functions (group, MODE_none);
- /* svmmla is distributed over several extensions. Allow the common
- denominator to define the overloaded svmmla function without
- defining any specific versions. */
- if (group.types[0][0] != NUM_TYPE_SUFFIXES)
- {
- if (type_suffixes[group.types[0][0]].float_p)
- build_all (b, "v0,v0,v0,v0", group, MODE_none);
- else
- build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
- }
+ if (type_suffixes[group.types[0][0]].float_p)
+ build_all (b, "v0,v0,v0,v0", group, MODE_none);
+ else
+ build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
}
tree
char *name = get_name (instance, true);
tree id = get_identifier (name);
if (registered_function **map_value = name_map->get (id))
- gcc_assert ((*map_value)->instance == instance
- && (required_extensions.sm_off == 0
- || ((*map_value)->required_extensions.sm_off
- & ~required_extensions.sm_off) == 0)
- && (required_extensions.sm_on == 0
- || ((*map_value)->required_extensions.sm_on
- & ~required_extensions.sm_on) == 0));
+ {
+ auto &dst_extensions = (*map_value)->required_extensions;
+ /* Make sure that any streaming and streaming-compatible attributes
+ on the function type are still correct. (It might not matter if
+ they aren't, so this could be relaxed in future if we're sure that
+ it's safe.) */
+ gcc_assert ((*map_value)->instance == instance
+ && (dst_extensions.sm_off || !required_extensions.sm_off)
+ && (dst_extensions.sm_on || !required_extensions.sm_on));
+ dst_extensions = dst_extensions.common_denominator (required_extensions);
+ }
else
{
registered_function &rfn