From: Charlie Jenkins <charlie@rivosinc.com>
To: "Paul Walmsley" <pjw@kernel.org>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Anup Patel" <anup@brainfault.org>,
"Atish Patra" <atish.patra@linux.dev>,
"Samuel Holland" <samuel.holland@sifive.com>,
"Björn Töpel" <bjorn@kernel.org>,
"Luke Nelson" <luke.r.nels@gmail.com>,
"Xi Wang" <xi.wang@gmail.com>,
"Eric Biggers" <ebiggers@kernel.org>,
"Conor Dooley" <conor@kernel.org>
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
Charlie Jenkins <thecharlesjenkins@gmail.com>
Subject: [PATCH RFC 06/10] riscv: Makefile: Add enabled extensions to compiler flags
Date: Wed, 10 Dec 2025 08:13:43 -0800 [thread overview]
Message-ID: <20251210-profiles-v1-6-315a6ff2ca5a@gmail.com> (raw)
In-Reply-To: <20251210-profiles-v1-0-315a6ff2ca5a@gmail.com>
Build an optimized kernel with all extensions that the hardware is
expected to support. Extensions that might be supported by hardware and
will be detected at runtime will be added to the assembler flags but not
to the compiler flags.
Signed-off-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
---
arch/riscv/Makefile | 135 ++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 116 insertions(+), 19 deletions(-)
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index ef1a7b1bffe8..efe43537e984 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -57,37 +57,134 @@ ifeq ($(CONFIG_SHADOW_CALL_STACK),y)
KBUILD_LDFLAGS += --no-relax-gp
endif
-# ISA string setting
-riscv-march-y := $(CONFIG_ARCH)
-riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
-riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
-riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
+# Handling of riscv extensions
+# There are a couple of considerations when enabling extensions:
+# 1. Does the toolchain support the extension?
+# 2. Is the extension supported by the hardware the kernel will run on?
+# 3. Does the extension have registers that need to be save/restored on
+# a context switch?
+# 4. Is this extension emitted by the compiler or only by hand-coded
+# assembly?
+#
+# This section has helpers to support extensions with varying answers to these questions.
+#
+# The compiler will be allowed to emit an extension if all of the following
+# are satisfied:
+# - The extension is a "stateless" extension (i.e. doesn't introduce additional
+# registers)
+# - The extension is supported by the toolchain (selected by CONFIG_TOOLCHAIN_HAS_*)
+# - The extension is enabled for use in the kernel (selected by CONFIG_RISCV_ISA_*=y)
+#
+# Assembler support for the instruction will be added if the extension is
+# supported by the assembler (selected by CONFIG_TOOLCHAIN_HAS_*).
+
+# Extensions that the compiler is allowed to emit anywhere.
+riscv-march-standard := $(CONFIG_ARCH)
+
+# Extensions that the compiler is allowed to emit in FPU contexts.
+# This should riscv-march-standard plus the FPU-specific extensions.
+riscv-march-fpu := $(CONFIG_ARCH)
+
+# All extensions supported by the kernel. Some of these extensions require
+# special care so they cannot be arbitrarily emitted by the compiler.
+riscv-march-full := $(CONFIG_ARCH)
+
+# Returns the instruction if it is supported, returns the empty string otherwise.
+# An instruction is only "supported" if RISCV_ISA_*!=n.
+# An instruction that is "supported" can be emitted through alternatives, but an instruction that is
+# "enabled" can be emitted arbitrarily by the compiler.
+# Arguments:
+# $1 - name of extension
+# $2 - extension delimiter. Should be empty for base extensions and
+# underscore otherwise
+extension_supported=$(if $(and $(or $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),m), $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),y)), $(filter $(CONFIG_TOOLCHAIN_HAS_$(shell echo $1 | tr a-z A-Z)),y)),$2$1)
+
+# Returns the instruction if it is enabled, returns the empty string otherwise.
+# An instruction is only "enabled" if RISCV_ISA_*=y.
+# An instruction that is "supported" can be emitted through alternatives, but an instruction that is
+# "enabled" can be emitted arbitrarily by the compiler.
+# Arguments:
+# $1 - name of extension
+# $2 - extension delimiter. Should be empty for base extensions and
+# underscore otherwise
+extension_enabled=$(if $(and $(filter $(CONFIG_RISCV_ISA_$(shell echo $1 | tr a-z A-Z)),y), $(filter $(CONFIG_TOOLCHAIN_HAS_$(shell echo $1 | tr a-z A-Z)),y)),$2$1)
+
+# Use this macro to add support for an extension that is stateless.
+# A "stateless" extension is one that does not add additional registers.
+#
+# Arguments:
+# $1 - name of extension
+# $2 - extension delimiter. Should be empty for base extensions and
+# underscore otherwise
+define add_stateless_extension
+$(eval riscv-march-standard=$(riscv-march-standard)$(call extension_enabled,$1,$2))
+$(eval riscv-march-fpu=$(riscv-march-fpu)$(call extension_enabled,$1,$2))
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
-ifneq ($(CONFIG_RISCV_ISA_C),y)
- KBUILD_RUSTFLAGS += -Ctarget-feature=-c
-endif
+# Use this macro to add support for a floating point extension.
+# Floating point extensions are not able to be used in all contexts, so they
+# are kept separate.
+#
+# Arguments:
+# $1 - name of extension
+# $2 - extension delimiter. Should be empty for base extensions and
+# underscore otherwise
+define add_fpu_extension
+$(eval riscv-march-fpu=$(riscv-march-fpu)$(call extension_enabled,$1,$2))
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
+
+# Use this macro to add support for an extension that is stateful.
+# A "stateful" extension is one that adds additional registers, or requires
+# hand-coded assembly (instead of being arbitrarily emitted by the compiler).
+#
+# Arguments:
+# $1 - name of extension
+# $2 - extension delimiter. Should be empty for base extensions and
+# underscore otherwise
+define add_stateful_extension
+$(eval riscv-march-full=$(riscv-march-full)$(call extension_supported,$1,$2))
+endef
+
+# Extensions must be added in the canonical ISA string order
+
+# Base extensions
+$(call add_fpu_extension,f)
+$(call add_fpu_extension,d)
+$(call add_stateless_extension,c)
+$(call add_stateful_extension,v)
ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC
KBUILD_CFLAGS += -Wa,-misa-spec=2.2
KBUILD_AFLAGS += -Wa,-misa-spec=2.2
else
-riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
+$(call add_stateless_extension,zicsr,_)
+$(call add_stateless_extension,zifencei,_)
endif
-# Check if the toolchain supports Zacas
-riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
+# Standard extensions
+$(call add_stateless_extension,zabha,_)
+$(call add_stateless_extension,zacas,_)
+$(call add_stateless_extension,zba,_)
+$(call add_stateless_extension,zbb,_)
+$(call add_stateless_extension,zbc,_)
+$(call add_stateless_extension,zbkb,_)
-# Check if the toolchain supports Zabha
-riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) := $(riscv-march-y)_zabha
+ifneq ($(CONFIG_RISCV_ISA_C),y)
+ KBUILD_RUSTFLAGS += -Ctarget-feature=-c
+endif
-# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
-# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
-KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
+# Only include extensions that do not introduce additional state. This
+# "additional state" most often means extra registers.
+KBUILD_CFLAGS += -march=$(riscv-march-standard)
-KBUILD_AFLAGS += -march=$(riscv-march-y)
+# Make all instructions available to the assembler
+KBUILD_AFLAGS += -march=$(riscv-march-full)
-# For C code built with floating-point support, exclude V but keep F and D.
-CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)([^v_]*)v?/\1\2/')
+# As an extension of the "standard" march string, include any extensions that
+# are able to be used when the FPU is enabled.
+CC_FLAGS_FPU := -march=$(riscv-march-fpu)
KBUILD_CFLAGS += -mno-save-restore
--
2.43.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2025-12-10 16:14 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-10 16:13 [PATCH RFC 00/10] riscv: Add support for rva23 Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 01/10] riscv: Standardize extension capitilization Charlie Jenkins
2026-01-15 2:48 ` Paul Walmsley
2026-01-15 16:03 ` Andrew Jones
2025-12-10 16:13 ` [PATCH RFC 02/10] riscv: kconfig: Reorganize extensions Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 03/10] riscv: kconfig: Simply arch selection Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 04/10] riscv: kconfig: Make extensions tristate Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 05/10] riscv: kconfig: Add zve32x Charlie Jenkins
2025-12-10 16:13 ` Charlie Jenkins [this message]
2025-12-10 16:13 ` [PATCH RFC 07/10] riscv: kconfig: Make vendor extensions tristate Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 08/10] riscv: Optimize cpufeature macros for extension assumptions Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 09/10] riscv: kconfig: Add rva23 config Charlie Jenkins
2025-12-10 16:13 ` [PATCH RFC 10/10] riscv: csum: Remove inline assembly Charlie Jenkins
2026-01-14 18:16 ` [PATCH RFC 00/10] riscv: Add support for rva23 Paul Walmsley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251210-profiles-v1-6-315a6ff2ca5a@gmail.com \
--to=charlie@rivosinc.com \
--cc=alex@ghiti.fr \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=bjorn@kernel.org \
--cc=conor@kernel.org \
--cc=ebiggers@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=luke.r.nels@gmail.com \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=samuel.holland@sifive.com \
--cc=thecharlesjenkins@gmail.com \
--cc=xi.wang@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox