From 5d588d003166877630a0f71ed90ee9b50c390ce1 Mon Sep 17 00:00:00 2001 From: Stephanos Ioannidis Date: Fri, 27 Jun 2025 10:15:26 +0900 Subject: [PATCH] arch: riscv: Add Zc* compressed instruction extension support This commit adds the support for the following new Zc* series compressed instruction extensions: Zca - Subset of the C extension without FP loads and stores Zcb - "Simple" instructions Zcd - Double-precision floating-point instructions Zcf - Single-precision floating-point instructions Zcmp - "Complex" instructions for embedded CPUs Zcmt - Table jump instructions for embedded CPUs With the introduction of the Zc* extensions, the C extension now implies the following Zc* extensions: * Zca, always * Zcf if F is specified (RV32 only) * Zcd if D is specified The Zc* extensions that are implied by the C extension are not specified in the GCC `-march` flag because they are redundant and can interfere with the resolution of the correct multi-lib for the selected architecture unless the the alternate mappings for the redundant forms are manually specified. All the implementation details in this commit are based on the Zc* v1.0.0 specification, which is the ratified version. Signed-off-by: Stephanos Ioannidis --- arch/riscv/Kconfig.isa | 62 +++++++++++++++++++++++++++ cmake/compiler/gcc/target_riscv.cmake | 30 +++++++++++++ 2 files changed, 92 insertions(+) diff --git a/arch/riscv/Kconfig.isa b/arch/riscv/Kconfig.isa index 0b81ce5dd3a5..0ce7b4b12aec 100644 --- a/arch/riscv/Kconfig.isa +++ b/arch/riscv/Kconfig.isa @@ -89,6 +89,9 @@ config RISCV_ISA_EXT_Q config RISCV_ISA_EXT_C bool + select RISCV_ISA_EXT_ZCA + select RISCV_ISA_EXT_ZCD if RISCV_ISA_EXT_D + select RISCV_ISA_EXT_ZCF if RISCV_ISA_EXT_F && (RISCV_ISA_RV32I || RISCV_ISA_RV32E) help (C) - Standard Extension for Compressed Instructions @@ -127,6 +130,65 @@ config RISCV_ISA_EXT_ZALRSC The Zalrsc extension enables support for LR.W/D and SC.W/D-style instructions. +config RISCV_ISA_EXT_ZCA + bool + help + (Zca) - Zba Extension for Compressed Instructions + + The Zca extension is a subset of the C extension that does not include + the floating-point load and store instructions. + +config RISCV_ISA_EXT_ZCB + bool + depends on RISCV_ISA_EXT_ZCA + help + (Zcb) - Zcb Extension for Simple Compressed Instructions + + The Zcb extension is a set of simple code-size saving instructions + which are easy to implement on all CPUs. + +config RISCV_ISA_EXT_ZCD + bool + depends on RISCV_ISA_EXT_D + depends on RISCV_ISA_EXT_ZCA + help + (Zcd) - Zcd Extension for Double-Precision FP Compressed Instructions + + The Zcd extension consists of compressed double-precision + floating-point load and store instructions. + +config RISCV_ISA_EXT_ZCF + bool + depends on RISCV_ISA_RV32I || RISCV_ISA_RV32E + depends on RISCV_ISA_EXT_F + depends on RISCV_ISA_EXT_ZCA + help + (Zcf) - Zcf Extension for Single-Precision FP Compressed Instructions + + The Zcf extension consists of compressed single-precision + floating-point load and store instructions. + +config RISCV_ISA_EXT_ZCMP + bool + depends on RISCV_ISA_EXT_ZCA + depends on !RISCV_ISA_EXT_ZCD + help + (Zcmp) - Zcmp Extension for Complex Compressed Instructions + + The Zcmp extension consists of complex operations intended for + embedded CPUs. + +config RISCV_ISA_EXT_ZCMT + bool + depends on RISCV_ISA_EXT_ZICSR + depends on RISCV_ISA_EXT_ZCA + depends on !RISCV_ISA_EXT_ZCD + help + (Zcmt) - Zcmt Extension for Compressed Table Jump Instructions + + The Zcmt extension consists of compressed table jump instructions for + embedded CPUs. + config RISCV_ISA_EXT_ZBA bool help diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index ccfc4df4f524..cc9e0c3754e6 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -66,6 +66,36 @@ if(NOT CONFIG_RISCV_ISA_EXT_A) endif() endif() +# Zca is implied by C +if(CONFIG_RISCV_ISA_EXT_ZCA AND + NOT CONFIG_RISCV_ISA_EXT_C) + string(CONCAT riscv_march ${riscv_march} "_zca") +endif() + +if(CONFIG_RISCV_ISA_EXT_ZCB) + string(CONCAT riscv_march ${riscv_march} "_zcb") +endif() + +# Zcd is implied by C+D +if(CONFIG_RISCV_ISA_EXT_ZCD AND + NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_D)) + string(CONCAT riscv_march ${riscv_march} "_zcd") +endif() + +# Zcf is implied by C+F +if(CONFIG_RISCV_ISA_EXT_ZCF AND + NOT (CONFIG_RISCV_ISA_EXT_C AND CONFIG_RISCV_ISA_EXT_F)) + string(CONCAT riscv_march ${riscv_march} "_zcf") +endif() + +if(CONFIG_RISCV_ISA_EXT_ZCMP) + string(CONCAT riscv_march ${riscv_march} "_zcmp") +endif() + +if(CONFIG_RISCV_ISA_EXT_ZCMT) + string(CONCAT riscv_march ${riscv_march} "_zcmt") +endif() + if(CONFIG_RISCV_ISA_EXT_ZBA) string(CONCAT riscv_march ${riscv_march} "_zba") endif()