@@ -4,15 +4,42 @@
# SPDX-License-Identifier: GPL-2.0-only
#
-# RISC-V profile name -> equivalent ISA string. These are determined from compiler output, like:
-# tgamblin@alchemist ~ $ riscv64-linux-gnu-gcc -march=rva20u64 -mabi=lp64d -Q --help=target | grep rv64
-# -march=rv64imafdc_ziccamoa_ziccif_zicclsm_ziccrse_zicntr_zicsr_zmmul_za128rs_zaamo_zalrsc_zca_zcd
+# RISC-V profile name -> equivalent ISA string, i.e. the mandatory extensions of
+# each profile as ratified in the RISC-V Profiles specification
+# (https://github.com/riscv/riscv-profiles):
+# RVA20U64, RVA22U64: RVA20/RVA22 Profiles, version 1.0
+# RVA23U64: RVA23 Profiles, version 1.0
+# plus the extensions those imply (e.g. zmmul, zaamo, zca, zve*).
+#
+# The profile names are used as package architectures, so each entry here is an
+# ABI claim: packages built for "rva22u64" must keep meaning exactly this
+# extension set. Do not regenerate these from compiler output (e.g. gcc's
+# -march expansion); a newer compiler, or clang, may expand a profile
+# differently. Changing an entry changes what existing package feeds mean.
RISCV_PROFILES = {
'rva20u64': 'rv64imafdc_ziccamoa_ziccif_zicclsm_ziccrse_zicntr_zicsr_zmmul_za128rs_zaamo_zalrsc_zca_zcd',
'rva22u64': 'rv64imafdcb_zic64b_zicbom_zicbop_zicboz_ziccamoa_ziccif_zicclsm_ziccrse_zicntr_zicsr_zihintpause_zmmul_za64rs_zaamo_zalrsc_zfhmin_zca_zcd_zba_zbb_zbs_zkt',
'rva23u64': 'rv64imafdcbv_zic64b_zicbom_zicbop_zicboz_ziccamoa_ziccif_zicclsm_ziccrse_zicntr_zicond_zicsr_zihintntl_zihintpause_zihpm_zimop_zmmul_za64rs_zaamo_zalrsc_zawrs_zfa_zfhmin_zca_zcb_zcd_zcmop_zba_zbb_zbs_zkt_zvbb_zve32f_zve32x_zve64d_zve64f_zve64x_zvfhmin_zvkb_zvkt_zvl128b_zvl32b_zvl64b_supm',
}
+# Extensions implied by another enabled extension (per GCC's
+# riscv_implied_info). zicsr (implied by f) is left out for backwards
+# compatibility, i.e. so the package archs of the existing non-profile tunes
+# (e.g. riscv64imafdc_zicsr_zifencei) stay the same.
+RISCV_IMPLIED = {
+ 'm': ['zmmul'],
+ 'a': ['zaamo', 'zalrsc'],
+ 'c': ['zca'],
+ 'b': ['zba', 'zbb', 'zbs'],
+ 'v': ['zve32f', 'zve32x', 'zve64d', 'zve64f', 'zve64x', 'zvl32b', 'zvl64b', 'zvl128b'],
+ 'zcb': ['zca'],
+ 'zcd': ['zca'],
+ 'zcmop': ['zca'],
+ 'zvbb': ['zvkb'],
+ # a reservation set of at most 64 bytes is also at most 128 bytes
+ 'za64rs': ['za128rs'],
+}
+
# riscv_isa_to_tune(isa)
#
# Automatically translate a RISC-V ISA string to TUNE_FEATURES
@@ -91,6 +118,15 @@ def riscv_isa_to_tune(isa):
feature = list(dict.fromkeys(feature))
return ' '.join(feature)
+# riscv_implied(enabled)
+#
+# Return the set of extensions implied by those in enabled.
+def riscv_implied(enabled):
+ implied = {i for e in enabled for i in RISCV_IMPLIED.get(e, [])}
+ if 'c' in enabled and 'd' in enabled:
+ implied |= {'zcd', 'zca'}
+ return implied
+
# riscv_pkgarch(features, exact_pkgarch)
#
# Prefer a RISCV_PROFILES name (plus any extensions enabled on top of it) as the
@@ -98,12 +134,25 @@ def riscv_isa_to_tune(isa):
# what the sstate class can handle. When several profiles match, the one with
# the most extensions is preferred, as it is the more specific/clearer match.
# If there's no clear profile matching the extension list, then fall back to
-# exact_pkgarch.
+# exact_pkgarch. Either way, extensions implied by others are left out.
def riscv_pkgarch(features, exact_pkgarch):
if not features:
return exact_pkgarch
current = set(features.split())
+ # Match profiles whether or not implied extensions (or the b shorthand)
+ # were listed
+ if {'zba', 'zbb', 'zbs'} <= current:
+ current.add('b')
+ implied = riscv_implied(current)
+ current |= implied
+
+ # Drop implied extensions from the exact form too, keeping its base
+ # (e.g. riscv64imafdc) and canonical ordering. Only drop what the string
+ # itself implies, as b is never written out there.
+ base, *exts = exact_pkgarch.split('_')
+ exact_implied = riscv_implied(set(base[len('riscv64'):]) | set(exts))
+ exact_pkgarch = '_'.join([base] + [e for e in exts if e not in exact_implied])
best_match = None
best_features = None
@@ -117,5 +166,5 @@ def riscv_pkgarch(features, exact_pkgarch):
if best_match is None:
return exact_pkgarch
- extra = sorted(current - best_features)
+ extra = sorted(current - best_features - implied)
return '_'.join([best_match] + extra)
Add a new function, riscv_implied() and corresponding tuning lists to help with shortening PKGARCH-related variables. There's no need to specify every extension when some (e.g. 'm' implying 'zmmul') are automatic. AI-Generated: Uses Claude Opus 5.5 Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> --- meta/lib/oe/tune.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-)