Re: [OE-core] [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features

Mark Hatle
2025-06-18T14:13:37Z

On 6/17/25 11:00 PM, Alistair Francis wrote:
> On Wed, Jun 18, 2025 at 9:39 AM Mark Hatle via lists.openembedded.org
> <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote:
>>
>> From: Mark Hatle <mark.hatle@amd.com>
>>
>> This implements the following base ISAs:
>>
>> * rv32i, rv64i
>> * rv32e, rv64i
>>
>> The following ABIs:
>> * ilp32, ilp32e, ilp32f, ilp32d
>> * lp64, lp64e, lp64f, lp64d
>>
>> The following ISA extension are also implemented:
>> * M - Integer Multiplication and Division Extension
>> * A - Atomic Memory Extension
>> * F - Single-Precision Floating-Point Extension
>> * D - Double-Precision Floating-Point Extension
>> * C - Compressed Extension
>> * B - Bit Manipulation Extension (implies Zba, Zbb, Zbs)
>> * V - Vector Operations Extension
>> * Zicsr - Control and Status Register Access Extension
>> * Zifencei - Instruction-Fetch Fence Extension
>> * Zba - Address bit manipulation extension
>> * Zbb - Basic bit manipulation extension
>> * Zbc - Carry-less multiplication extension
>> * Zbs - Single-bit manipulation extension
>> * Zicbom - Cache-block management extension
>>
>> The existing processors tunes are preserved:
>> * riscv64 (rv64gc)
>> * riscv32 (rv32gc)
>> * riscv64nf (rv64imac_zicsr_zifencei)
>> * riscv32nf (rv32imac_zicsr_zifencei)
>> * riscv64nc (rv64imafd_zicsr_zifencei)
>
> I'm not sure this is the way we want to handle this. You are picking
> and choosing each individual extension, which is difficult for users
> to do. Not to mention it's easy to get wrong as some extensions
> conflict with other extensions.
>
> You also end up using the `rv32` or `rv64` CPUs with QEMU and enabling
> extensions manually. We will probably remove those CPUs from QEMU in
> the future as they cause a lot of user confusion.
>
> I think instead we should be moving towards the RISC-V profiles.
> Individual extensions can still be enabled/disabled on top of a
> profile if required. That's what we are doing in QEMU and it makes
> things a lot clearer to users exactly what is/isn't enabled.

As I've said elsewhere, profiles mean ISA + extensions.

"Profiles only describe ISA features, not a complete execution environment."

https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc#2-profiles-versus-platforms

For someone who understands what a specific profile is, it should be implemented
in the new meta/lib/oe/tune.py file. Any missing TUNE_FEATURES should be added.

I'd recommend a new function like:

riscv_profile_to_tune(profile):

and/or

riscv_profile_to_isa(profile):

(the later could call the existing riscv_isa_to_tune)

Then in the tune-<name>.inc file, the user would implement it as:

require conf/machine/include/riscv/arch-riscv.inc

DEFAULTTUNE ?= "my-magic-cpu"

AVAILTUNES += "my-magic-cpu"

TUNE_FEATURES:tune-my-magic-cpu := "${@riscv_profile_to_tune("rva20u32")} m a"
PACKAGE_EXTRA_ARCHS:tune-my-magic-cpu = "${TUNE_RISCV_PKGARCH}"

The above should result in:

rv 32 i m a , since RVI20U32 says "no mandatory extensions" but M A F D C
Zifencei and Zicntr are optional. (rvi20u64 is similar)

Note: rv 32 i m a is not Linux compatible, we need zicsr and zifencei as well,
but Zicsr is not listed as mandatory or optional

while RVA22U64 defines a specific set that contains extensions which my parts do
NOT support.

Thus we _MUST_ have a way to be able to use ISA + extension which is the lowest
common denominator of what _WE_ support, while giving users views into the
approaches they want.

_I_ do not intend to implement the profile_to_... functions, as I won't see any
use in the parts that I have to support. But as a project, I do think someone
should implement thing table and function to make it easier for people who want
to use profiles to specify something.

--Mark

> Alistair
>
>>
>> Previously defined feature 'big-endian' has been removed as it was not used.
>>
>> Signed-off-by: Mark Hatle <mark.hatle@amd.com>
>> ---
>> meta/conf/machine/include/riscv/README | 122 ++++++++++++++++
>> .../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++-
>> .../conf/machine/include/riscv/tune-riscv.inc | 40 ++---
>> meta/conf/machine/qemuriscv32.conf | 4 +-
>> meta/lib/oe/__init__.py | 2 +-
>> meta/lib/oe/tune.py | 81 ++++++++++
>> 6 files changed, 349 insertions(+), 38 deletions(-)
>> create mode 100644 meta/conf/machine/include/riscv/README
>> create mode 100644 meta/lib/oe/tune.py
>>
>> diff --git a/meta/conf/machine/include/riscv/README b/meta/conf/machine/include/riscv/README
>> new file mode 100644
>> index 0000000000..beef68f523
>> --- /dev/null
>> +++ b/meta/conf/machine/include/riscv/README
>> @@ -0,0 +1,122 @@
>> +2025/06/08 - Mark Hatle <mark.hatle@amd.com>
>> + - Initial Revision
>> +
>> +The RISC-V ISA is broken into two parts, a base ISA and extensions. As
>> +of the writing of this document these are documented at:
>> +
>> +https://lf-riscv.atlassian.net/wiki/spaces/HOME/pages/16154769/RISC-V+Technical+Specifications
>> +
>> +Specifically "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA"
>> +was used to create this implementation.
>> +
>> +Requirements
>> +------------
>> +As RISC-V is a “variable” ISA (a base isa plus numerous extensions), a
>> +mechanism is required to specify a series of ISA features that a user or
>> +tune can use to specify a specific CPU instantiation.
>> +
>> +Not all ratified or draft features should or can be implemented with the
>> +available resources.
>> +
>> +The implementation should work for Linux, baremetal (newlib), zephyr and
>> +other operating systems. Supported extensions should be based on
>> +real-world examples.
>> +
>> +Linux
>> +-----
>> +Linux required base and support extensions should be available. Linux
>> +requires:
>> +* Base: rv32ima & rv64ima
>> +* Optional FPU: fd
>> +* Optional RISCV_ISA_C: c
>> +* Optiona RISCV_ISA_V: v
>> +* Required additional: _zicsr_zifencei
>> +* Optional RISCV_ISA_ZBA: _zba
>> +* Optional RISCV_ISA_ZBB: _zbb
>> +* Optional RISCV_ISA_ZBC: _zbc (not supported by current QEMU design)
>> +
>> +See: https://git.yoctoproject.org/linux-yocto/tree/arch/riscv/Makefile?h=v6.12/base
>> +
>> +Baremetal
>> +---------
>> +AMD Microblaze-V FPGA support uses the following static configurations:
>> +Base: rv32e, rv32i, rv64i
>> +Extensions: m, a, f, d, c, b, zicsr, zifencei
>> +
>> +Zephyr
>> +------
>> +AMD Microblaze-V development for Zephyr is the same as Baremetal, with a
>> +few additional extensions: zbc, zicbom
>> +
>> +ABI
>> +---
>> +The following ABIs are supported GNU tools and some combination of systems.
>> +* ilp32 - Integer, long and pointer are 32-bit
>> +* lp64 - Long and pointer are 64-bit (integer is 32-bit)
>> +
>> +The ABI is dependent upon the core system implementation, as ilp32 can
>> +only used on an ‘rv32’ system, while lp64 can only be used on an ‘rv64’
>> +system.
>> +
>> +There are additional variations of each ABI:
>> +* e - used with the Reduced register extension
>> +* f - used when single precision floating point (but not double precision) is
>> + enabled
>> +* d - used when both single and double precision floating point is enabled
>> +
>> +Based on the above, the ABI should be automatically determined based on
>> +the selected Base ISA and Extensions.
>> +
>> +Implementation
>> +--------------
>> +To make it easier to generate the RISC-V canonical arch, ISA based -march,
>> +and the ABI string, a few new variables are added for specific RISC-V items.
>> +
>> +TUNE_RISCV_ARCH - This contains the canonical GNU style arch, generally this
>> + will evaluate to "riscv32" or "riscv64".
>> +
>> +TUNE_RISCV_MARCH - This will contain an ISA based -march string compatible
>> + with gcc and similar toolchains. For example:
>> + rv32imacfd_zicsr_zifencei
>> +
>> +TUNE_RISCV_ABI - This is the generated ABI that corresponds to the ARCH and
>> + MARCH/ISA values. For riscv32, the value will be ilp32
>> + (int, long and pointer is 32-bit) with the ISA
>> + variation. For riscv64, the value will be lp64 (long
>> + and pointer are 64-bit bit, while int is 32-bit) with the
>> + ISA variation. The ISA affects the ABI when the 'e', 'f'
>> + and 'd' extension are used.
>> +
>> +TUNE_RISCV_PKGARCH - This is the generated PKGARCH value.
>> +
>> +The standard variables are defined as:
>> +
>> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}"
>> +
>> +The above will allow the user to specify an implementation specific
>> +TUNE_CCARGS for a given processor tune if the default implementtion is
>> +not adequate for some reason. It is expected that most, if not all,
>> +implementations will use the default behavior.
>> +
>> +TUNE_ARCH = "${TUNE_RISCV_ARCH}"
>> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}"
>> +
>> +The above two will always base their setting off the standard TUNE_FEATURES.
>> +
>> +Ratified and draft extensions should be implemented as TUNE_FEATURES in
>> +the arch-riscv.inc file.
>> +
>> +Vendor specific extensions and processor specific settings should go
>> +into a 'tune-<vendor>.inc' file, with tune-riscv.inc being reserved for
>> +general purpose tunes.
>> +
>> +TUNE_FEATURE Helper
>> +-------------------
>> +A special helper function has been written that will convert RISC-V ISA
>> +notation into TUNE_FEATURE notion, for example:
>> +
>> +rv32g -> rv 32 i m a f d zicsr zifencei
>> +
>> +The helper can be called using oe.tune.riscv_isa_to_tune("<ISA>") such as
>> +oe.tune.riscv_isa_to_tune("rv64gc") which would return:
>> + rv 64 i m a f d c zicsr zifencei
>> diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc
>> index b34064e78f..99bed8fde5 100644
>> --- a/meta/conf/machine/include/riscv/arch-riscv.inc
>> +++ b/meta/conf/machine/include/riscv/arch-riscv.inc
>> @@ -1,14 +1,140 @@
>> # RISCV Architecture definition
>>
>> -DEFAULTTUNE ?= "riscv64"
>> +# Based on the RISC-V Instruction Set Manual Volume I: Unprivileged ISA from May 2025
>> +# As well as the RISC-V options for using GCC (as of June 2025)
>>
>> -TUNE_ARCH = "${TUNE_ARCH:tune-${DEFAULTTUNE}}"
>> -TUNE_PKGARCH = "${TUNE_PKGARCH:tune-${DEFAULTTUNE}}"
>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nf', ' -mabi=lp64', ' ', d)}"
>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv32nf', ' -mabi=ilp32', ' ', d)}"
>> +# Note: the following should be implemented in the order that GCC expects
>> +# -march= values to be defined in.
>>
>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -march=rv64imafd', ' ', d)}"
>> +# Base ISA
>> +# All supported march strings must start with rv32 or rv64
>> +TUNEVALID[rv] = "RISC-V"
>> +TUNE_RISCV_ARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "riscv", "", d)}"
>> +TUNE_RISCV_MARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "rv", "", d)}"
>> +TUNE_RISCV_ABI = ""
>>
>> +# There are two primary ABIs, ilp32 and lp64
>> +# There are variants of both, that appears to be based on extensions above
>> +# For example:
>> +# rv32i uses ilp32, rv32e uses ilp32e, rv32f uses ilp32f
>> +# rv64i uses lp64, rv64if uses lp64f, rv64id uses lp64d
>> +TUNEVALID[32] = "ISA XLEN - 32-bit"
>> +TUNECONFLICTS[32] = "64"
>> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}"
>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "32", "ilp32", "", d)}"
>> +
>> +TUNEVALID[64] = "ISA XLEN - 64-bit"
>> +TUNECONFLICTS[64] = "32"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}"
>> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}"
>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "64", "lp64", "", d)}"
>> +
>> +# The package arch starts with the canonical arch, but adds some extensions to make
>> +# package compatibility clear
>> +TUNE_RISCV_PKGARCH = "${TUNE_RISCV_ARCH}"
>> +
>> +# i, e, or g are defined by gcc, but 'g' refers to 'i' + extensions 'MAFD Zicsr Zifencei'
>> +# So 'g' will not be defined here as it is an abbreviation of the expanded version
>> +TUNEVALID[e] = "Reduced register base integer extension"
>> +TUNECONFLICTS[e] = "i"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}"
>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}"
>> +
>> +TUNEVALID[i] = "Base integer extension"
>> +TUNECONFLICTS[i] = "e"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}"
>> +
>> +# Extensions
>> +TUNEVALID[m] = "Integer multiplication and division extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}"
>> +
>> +TUNEVALID[a] = "Atomic extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}"
>> +
>> +TUNEVALID[f] = "Single-precision floating-point extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}"
>> +
>> +TUNEVALID[d] = "Double-precision floating-point extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}"
>> +
>> +# Only f OR d, but just one
>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", bb.utils.contains("TUNE_FEATURES", "f", "f", "", d), d)}"
>> +
>> +TUNEVALID[c] = "Compressed extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}"
>> +
>> +TUNEVALID[b] = "Bit Manipulation extension"
>> +# Handled below via zba, zbb, zbs
>> +# This matches current Linux kernel behavior
>> +#TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}"
>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}"
>> +
>> +TUNEVALID[v] = "Vector operations extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}"
>> +
>> +# Now the special Z extensions
>> +TUNEVALID[zicbom] = "Cache-block management extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}"
>> +
>> +TUNEVALID[zicsr] = "Control and status register access extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}"
>> +# If zicsr (or zifencei) is in the path, OpenSBI fails to use the extensions, do to (Makefile):
>> +# # Check whether the assembler and the compiler support the Zicsr and Zifencei extensions
>> +# CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y)
>> +# this will match on the path containing zicsr or zifencei when an error is reported, which
>> +# will always happens in this check.
>> +#
>> +# Yocto Project Bugzilla 15897
>> +#
>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}"
>> +
>> +TUNEVALID[zifencei] = "Instruction-fetch fence extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}"
>> +# See above Bug 15897
>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}"
>> +
>> +TUNEVALID[zba] = "Address bit manipulation extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}"
>> +
>> +TUNEVALID[zbb] = "Basic bit manipulation extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}"
>> +
>> +TUNEVALID[zbc] = "Carry-less multiplication extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}"
>> +
>> +TUNEVALID[zbs] = "Single-bit manipulation extension"
>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}"
>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}"
>> +
>> +# Construct TUNE_CCARGS
>> +# This should result in a CCARG similar to:
>> +# -march=rv32imac -mabi=ilp32
>> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}"
>> +
>> +# Construct TUNE_ARCH
>> +# This should result in an arch string similar to:
>> +# riscv32
>> +TUNE_ARCH = "${TUNE_RISCV_ARCH}"
>> +
>> +# Construct TUNE_PKGARCH
>> +# This should result in a package are like:
>> +# riscv32imac
>> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}"
>> +
>> +# Misc settings
>> # Fix: ld: unrecognized option '--hash-style=sysv'
>> LINKER_HASH_STYLE:libc-newlib = ""
>> LINKER_HASH_STYLE:libc-picolibc = ""
>> diff --git a/meta/conf/machine/include/riscv/tune-riscv.inc b/meta/conf/machine/include/riscv/tune-riscv.inc
>> index 804712077e..12c1125c8b 100644
>> --- a/meta/conf/machine/include/riscv/tune-riscv.inc
>> +++ b/meta/conf/machine/include/riscv/tune-riscv.inc
>> @@ -1,41 +1,23 @@
>> require conf/machine/include/riscv/arch-riscv.inc
>>
>> -TUNEVALID[riscv64] = "Enable 64-bit RISC-V optimizations"
>> -TUNEVALID[riscv32] = "Enable 32-bit RISC-V optimizations"
>> -
>> -TUNEVALID[riscv64nf] = "Enable 64-bit RISC-V optimizations no floating point"
>> -TUNEVALID[riscv32nf] = "Enable 32-bit RISC-V optimizations no floating point"
>> -
>> -TUNEVALID[riscv64nc] = "Enable 64-bit RISC-V optimizations without compressed instructions"
>> -
>> -TUNEVALID[bigendian] = "Big endian mode"
>> +DEFAULTTUNE ?= "riscv64"
>>
>> AVAILTUNES += "riscv64 riscv32 riscv64nc riscv64nf riscv32nf"
>>
>> # Default
>> -TUNE_FEATURES:tune-riscv64 = "riscv64"
>> -TUNE_ARCH:tune-riscv64 = "riscv64"
>> -TUNE_PKGARCH:tune-riscv64 = "riscv64"
>> -PACKAGE_EXTRA_ARCHS:tune-riscv64 = "riscv64"
>> +TUNE_FEATURES:tune-riscv64 := "${@oe.tune.riscv_isa_to_tune("rv64gc")}"
>> +PACKAGE_EXTRA_ARCHS:tune-riscv64 = "${TUNE_RISCV_PKGARCH}"
>>
>> -TUNE_FEATURES:tune-riscv32 = "riscv32"
>> -TUNE_ARCH:tune-riscv32 = "riscv32"
>> -TUNE_PKGARCH:tune-riscv32 = "riscv32"
>> -PACKAGE_EXTRA_ARCHS:tune-riscv32 = "riscv32"
>> +TUNE_FEATURES:tune-riscv32 := "${@oe.tune.riscv_isa_to_tune("rv32gc")}"
>> +PACKAGE_EXTRA_ARCHS:tune-riscv32 = "${TUNE_RISCV_PKGARCH}"
>>
>> # No float
>> -TUNE_FEATURES:tune-riscv64nf = "${TUNE_FEATURES:tune-riscv64} riscv64nf"
>> -TUNE_ARCH:tune-riscv64nf = "riscv64"
>> -TUNE_PKGARCH:tune-riscv64nf = "riscv64nf"
>> -PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "riscv64nf"
>> +TUNE_FEATURES:tune-riscv64nf := "${@oe.tune.riscv_isa_to_tune("rv64imac_zicsr_zifencei")}"
>> +PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "${TUNE_RISCV_PKGARCH}"
>>
>> -TUNE_FEATURES:tune-riscv32nf = "${TUNE_FEATURES:tune-riscv32} riscv32nf"
>> -TUNE_ARCH:tune-riscv32nf = "riscv32"
>> -TUNE_PKGARCH:tune-riscv32nf = "riscv32nf"
>> -PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "riscv32nf"
>> +TUNE_FEATURES:tune-riscv32nf := "${@oe.tune.riscv_isa_to_tune("rv32imac_zicsr_zifencei")}"
>> +PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "${TUNE_RISCV_PKGARCH}"
>>
>> # no compressed
>> -TUNE_FEATURES:tune-riscv64nc = "${TUNE_FEATURES:tune-riscv64} riscv64nc"
>> -TUNE_ARCH:tune-riscv64nc = "riscv64"
>> -TUNE_PKGARCH:tune-riscv64nc = "riscv64nc"
>> -PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "riscv64nc"
>> +TUNE_FEATURES:tune-riscv64nc := "${@oe.tune.riscv_isa_to_tune("rv64imafd_zicsr_zifencei")}"
>> +PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "${TUNE_RISCV_PKGARCH}"
>> diff --git a/meta/conf/machine/qemuriscv32.conf b/meta/conf/machine/qemuriscv32.conf
>> index d3858dc051..aff36c28a5 100644
>> --- a/meta/conf/machine/qemuriscv32.conf
>> +++ b/meta/conf/machine/qemuriscv32.conf
>> @@ -2,9 +2,9 @@
>> #@NAME: generic riscv32 machine
>> #@DESCRIPTION: Machine configuration for running a generic riscv32
>>
>> -require conf/machine/include/riscv/qemuriscv.inc
>> +DEFAULTTUNE ?= "riscv32"
>>
>> -DEFAULTTUNE = "riscv32"
>> +require conf/machine/include/riscv/qemuriscv.inc
>>
>> PREFERRED_VERSION_openocd-native = "riscv"
>> PREFERRED_VERSION_openocd = "riscv"
>> diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py
>> index dd094a874a..73de774266 100644
>> --- a/meta/lib/oe/__init__.py
>> +++ b/meta/lib/oe/__init__.py
>> @@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__)
>> BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \
>> "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \
>> "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \
>> - "cve_check"]
>> + "cve_check", "tune"]
>> diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py
>> new file mode 100644
>> index 0000000000..7fda19430d
>> --- /dev/null
>> +++ b/meta/lib/oe/tune.py
>> @@ -0,0 +1,81 @@
>> +#
>> +# Copyright OpenEmbedded Contributors
>> +#
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +
>> +# riscv_isa_to_tune(isa)
>> +#
>> +# Automatically translate a RISC-V ISA string to TUNE_FEATURES
>> +#
>> +# Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported.
>> +#
>> +# Profiles, such as rva22u64, are NOT supported, you must use ISA strings.
>> +#
>> +def riscv_isa_to_tune(isa):
>> + _isa = isa.lower()
>> +
>> + feature = []
>> + iter = 0
>> +
>> + # rv or riscv
>> + if _isa[iter:].startswith('rv'):
>> + feature.append('rv')
>> + iter = iter + 2
>> + elif _isa[iter:].startswith('riscv'):
>> + feature.append('rv')
>> + iter = iter + 5
>> + else:
>> + # Not a risc-v ISA!
>> + return _isa
>> +
>> + while (_isa[iter:]):
>> + # Skip _ and whitespace
>> + if _isa[iter] == '_' or _isa[iter].isspace():
>> + iter = iter + 1
>> + continue
>> +
>> + # Length, just capture numbers here
>> + if _isa[iter].isdigit():
>> + iter_end = iter
>> + while iter_end < len(_isa) and _isa[iter_end].isdigit():
>> + iter_end = iter_end + 1
>> +
>> + feature.append(_isa[iter:iter_end])
>> + iter = iter_end
>> + continue
>> +
>> + # Typically i, e or g is next, followed by extensions.
>> + # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X
>> +
>> + # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end
>> + if _isa[iter] in ['z', 's', 'x']:
>> + ext_type = _isa[iter]
>> + iter_end = iter + 1
>> +
>> + # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension
>> + # See 37.4 and 37.5:
>> + # 37.4: Underscores "_" may be used to separate ISA extensions...
>> + # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore...
>> + # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters
>> + while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace():
>> + iter_end = iter_end + 1
>> +
>> + feature.append(_isa[iter:iter_end])
>> + iter = iter_end
>> + continue
>> +
>> + # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei
>> + # When expanding the abbreviation, any additional letters must appear before the _z* extensions
>> + if _isa[iter] == 'g':
>> + _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei'
>> + iter = 0
>> + continue
>> +
>> + feature.append(_isa[iter])
>> + iter = iter + 1
>> + continue
>> +
>> + # Eliminate duplicates, but preserve the order
>> + feature = list(dict.fromkeys(feature))
>> + return ' '.join(feature)
>> --
>> 2.34.1
>>
>>
>> -=-=-=-=-=-=-=-=-=-=-=-
>> Links: You receive all messages sent to this group.
>> View/Reply Online (#218948): https://lists.openembedded.org/g/openembedded-core/message/218948
>> Mute This Topic: https://lists.openembedded.org/mt/113700338/3619028
>> Group Owner: openembedded-core+owner@lists.openembedded.org
>> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [alistair23@gmail.com]
>> -=-=-=-=-=-=-=-=-=-=-=-
>>