From ecc37c12d7da31963a35c69feaa113c19043731e Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 26 Jun 2025 13:53:56 +0700 Subject: [PATCH] feat(build): enable -mtune=esp-base option for RISC-V targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `-mtune=esp-base` option is identical to the default tuning profile, except that `slow_unaligned_access` is set to false. This reduces the instruction count for built-in `memcpy` and improves performance, since our chips can handle misaligned access with minimal penalty (without triggering exceptions). Example: void load(uint32_t *r, char* x) { memcpy(r, x, sizeof(uint32_t)); } void store(char* x, uint32_t v) { memcpy(x, &v, sizeof(uint32_t)); } Previously generated code: load: lbu a5,2(a1) lbu a3,0(a1) lbu a4,1(a1) sb a5,2(a0) sb a3,0(a0) sb a4,1(a0) lbu a5,3(a1) sb a5,3(a0) ret store: srli a3,a1,8 srli a4,a1,16 srli a5,a1,24 addi sp,sp,-16 sb a1,0(a0) sb a3,1(a0) sb a4,2(a0) sb a5,3(a0) addi sp,sp,16 jr ra With `-mtune=esp-base`: load: lw a5,0(a1) sw a5,0(a0) ret store: sw a1,0(a0) ret Inlining behavior ================= Without `-mtune=esp-base`: - `memcpy()` is inlined only when the compile-time size is ≤ 12 bytes. - Maximum cost: ~25 instructions With `-mtune=esp-base`: - `memcpy()` is inlined for all compile-time constant sizes. - Maximum cost: ~14 instructions As a result, some applications may see reduced code size, while others may increase slightly. However, performance always improves because extra `memcpy` calls are eliminated. Performance results =================== esp32p4 (Ethernet iperf): - No noticeable difference esp32c61 (Wi-Fi iperf): - ~2 Mb/s increase for TCP and UDP TX (may be within measurement error) NOTE ==== Applies only to RISC-V chips that do not have the hardware issue marked by the SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE macro. --- components/soc/esp32c2/include/soc/Kconfig.soc_caps.in | 4 ---- components/soc/esp32c2/include/soc/soc_caps.h | 2 -- components/soc/esp32c3/include/soc/Kconfig.soc_caps.in | 4 ---- components/soc/esp32c3/include/soc/soc_caps.h | 2 -- tools/cmake/toolchain-esp32c2.cmake | 4 ++-- tools/cmake/toolchain-esp32c3.cmake | 4 ++-- tools/cmake/toolchain-esp32c5.cmake | 4 ++-- tools/cmake/toolchain-esp32c61.cmake | 4 ++-- tools/cmake/toolchain-esp32h4.cmake | 4 ++-- tools/cmake/toolchain-esp32p4.cmake | 4 ++-- 10 files changed, 12 insertions(+), 24 deletions(-) diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 60b9c54c59..d0d74a5292 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -263,10 +263,6 @@ config SOC_CPU_IDRAM_SPLIT_USING_PMP bool default y -config SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE - bool - default y - config SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index af19a55d4d..facf692980 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -112,8 +112,6 @@ #define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes #define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 -// DIG-694: misaligned access across PMP regions must be spaced at least by two instructions -#define SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE 1 /*-------------------------- ECC CAPS --------------------------*/ #define SOC_ECC_SUPPORT_POINT_VERIFY_QUIRK 1 // C2 ECC peripheral has a bug in ECC point verification, if value of K is zero the verification fails diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index b0ce79412c..07d3891d96 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -351,10 +351,6 @@ config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE hex default 0x80000000 -config SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE - bool - default y - config SOC_DS_SIGNATURE_MAX_BIT_LEN int default 3072 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index eaae1d8db9..f56e816ff8 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -143,8 +143,6 @@ #define SOC_CPU_BREAKPOINTS_NUM 8 #define SOC_CPU_WATCHPOINTS_NUM 8 #define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes -// DIG-694: misaligned access across PMP regions must be spaced at least by two instructions -#define SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE 1 /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /** The maximum length of a Digital Signature in bits. */ diff --git a/tools/cmake/toolchain-esp32c2.cmake b/tools/cmake/toolchain-esp32c2.cmake index 9182080127..87a50ea656 100644 --- a/tools/cmake/toolchain-esp32c2.cmake +++ b/tools/cmake/toolchain-esp32c2.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imc_zicsr_zifencei") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS) diff --git a/tools/cmake/toolchain-esp32c3.cmake b/tools/cmake/toolchain-esp32c3.cmake index 9182080127..87a50ea656 100644 --- a/tools/cmake/toolchain-esp32c3.cmake +++ b/tools/cmake/toolchain-esp32c3.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imc_zicsr_zifencei") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS) diff --git a/tools/cmake/toolchain-esp32c5.cmake b/tools/cmake/toolchain-esp32c5.cmake index 7ca12da3b4..99e8281713 100644 --- a/tools/cmake/toolchain-esp32c5.cmake +++ b/tools/cmake/toolchain-esp32c5.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS) diff --git a/tools/cmake/toolchain-esp32c61.cmake b/tools/cmake/toolchain-esp32c61.cmake index 7ca12da3b4..99e8281713 100644 --- a/tools/cmake/toolchain-esp32c61.cmake +++ b/tools/cmake/toolchain-esp32c61.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS) diff --git a/tools/cmake/toolchain-esp32h4.cmake b/tools/cmake/toolchain-esp32h4.cmake index e8ec46654f..36fbc09076 100644 --- a/tools/cmake/toolchain-esp32h4.cmake +++ b/tools/cmake/toolchain-esp32h4.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xespdsp -mabi=ilp32f") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS) diff --git a/tools/cmake/toolchain-esp32p4.cmake b/tools/cmake/toolchain-esp32p4.cmake index b546ed96fd..de7b8d02df 100644 --- a/tools/cmake/toolchain-esp32p4.cmake +++ b/tools/cmake/toolchain-esp32p4.cmake @@ -9,10 +9,10 @@ set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-) set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xespv_xesploop -mabi=ilp32f") -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS) set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE) -remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) +remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS) set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE) remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)