From e28af6a0029fc270f8f99a1649d29989f916b921 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 1 May 2025 13:35:20 +0700 Subject: [PATCH] fix(newlib): use optimized misalign access functions from libc.a --- components/newlib/CMakeLists.txt | 41 ++++++++++--------- ...sp32-spiram-rom-functions-c.lf => libc.lf} | 6 +-- components/newlib/src/newlib.lf | 15 +++++++ ...sp32-spiram-rom-functions-c.lf => libc.lf} | 4 ++ 4 files changed, 42 insertions(+), 24 deletions(-) rename components/newlib/src/{esp32-spiram-rom-functions-c.lf => libc.lf} (97%) rename components/newlib/src/picolibc/{esp32-spiram-rom-functions-c.lf => libc.lf} (96%) diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 99a11e810f..3d4769ca67 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -38,20 +38,23 @@ if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND) endif() if(CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS) - list(APPEND srcs - "src/string/memcmp.c" - "src/string/memmove.c" - "src/string/strncmp.c" - "src/string/strncpy.c" - "src/port/riscv/memcpy.c" - "src/port/riscv/strcpy.c" - "src/port/riscv/strcmp.S") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_memcmp_impl") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_memmove_impl") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strncmp_impl") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strncpy_impl") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strcpy_impl") - list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strcmp_impl") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + # TODO IDF-13089: remove this block and modify src/newlib.lf when clang was upgraded + list(APPEND srcs + "src/string/memcmp.c" + "src/string/memmove.c" + "src/string/strncmp.c" + "src/string/strncpy.c" + "src/port/riscv/memcpy.c" + "src/port/riscv/strcpy.c" + "src/port/riscv/strcmp.S") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_memcmp_impl") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_memmove_impl") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strncmp_impl") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strncpy_impl") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strcpy_impl") + list(APPEND EXTRA_LINK_FLAGS "-u esp_libc_include_strcmp_impl") + endif() endif() if(CONFIG_LIBC_NEWLIB) @@ -69,12 +72,10 @@ endif() set(ldfragments "") list(APPEND ldfragments "src/newlib.lf" "src/system_libs.lf") -if(CONFIG_SPIRAM_CACHE_WORKAROUND) - if(CONFIG_LIBC_NEWLIB) - list(APPEND ldfragments src/esp32-spiram-rom-functions-c.lf) - else() - list(APPEND ldfragments src/picolibc/esp32-spiram-rom-functions-c.lf) - endif() +if(CONFIG_LIBC_NEWLIB) + list(APPEND ldfragments src/libc.lf) +else() + list(APPEND ldfragments src/picolibc/libc.lf) endif() idf_component_register(SRCS "${srcs}" diff --git a/components/newlib/src/esp32-spiram-rom-functions-c.lf b/components/newlib/src/libc.lf similarity index 97% rename from components/newlib/src/esp32-spiram-rom-functions-c.lf rename to components/newlib/src/libc.lf index 1e066d61b1..1f31f191c1 100644 --- a/components/newlib/src/esp32-spiram-rom-functions-c.lf +++ b/components/newlib/src/libc.lf @@ -3,10 +3,6 @@ # and/or applications may assume that because these functions normally are in ROM, they are accessible even when flash is # inaccessible. To work around this, this ld fragment places these functions in RAM instead. If the ROM functions are used, # these defines do nothing, so they can still be included in that situation. -# -# -# Note: the only difference between esp32-spiram-rom-functions-c.lf -# and esp32-spiram-rom-functions-psram-workaround.lf is the archive name. [mapping:libc] archive: @@ -15,6 +11,8 @@ archive: else: libc.a entries: + if LIBC_OPTIMIZED_MISALIGNED_ACCESS = y: + libc_a-memcpy (noflash) if SPIRAM_CACHE_WORKAROUND = y: # The following libs are either used in a lot of places or in critical # code. (such as panic or abort) diff --git a/components/newlib/src/newlib.lf b/components/newlib/src/newlib.lf index 7ca47a0b9b..359acd6345 100644 --- a/components/newlib/src/newlib.lf +++ b/components/newlib/src/newlib.lf @@ -9,3 +9,18 @@ entries: stdatomic (noflash) if STDATOMIC_S32C1I_SPIRAM_WORKAROUND = y: stdatomic_s32c1i (noflash) + if STDATOMIC_S32C1I_SPIRAM_WORKAROUND = y: + stdatomic_s32c1i (noflash) + if CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS = y && IDF_TOOLCHAIN_GCC = y: + # memcpy() should be in IRAM due to early system use + # Others can stay in flash (performance difference is minimal) + # + # Performance Comparison: + # | func | flash | iram | + # |---------|-------|-------| + # | memcmp | 15986 | 15170 | + # | strcpy | 17499 | 16660 | + # | strcmp | 13125 | 11147 | + # | strncpy | 17386 | 16668 | + # | strncmp | 22161 | 21782 | + libc_a-memcpy (noflash) diff --git a/components/newlib/src/picolibc/esp32-spiram-rom-functions-c.lf b/components/newlib/src/picolibc/libc.lf similarity index 96% rename from components/newlib/src/picolibc/esp32-spiram-rom-functions-c.lf rename to components/newlib/src/picolibc/libc.lf index f2a97b4cc9..0892557473 100644 --- a/components/newlib/src/picolibc/esp32-spiram-rom-functions-c.lf +++ b/components/newlib/src/picolibc/libc.lf @@ -8,6 +8,10 @@ archive: libc.a entries: + if LIBC_OPTIMIZED_MISALIGNED_ACCESS = y && IDF_TARGET_ARCH_RISCV = y: + memcpy-asm (noflash) + if LIBC_OPTIMIZED_MISALIGNED_ACCESS = y && IDF_TARGET_ARCH_XTENSA = y: + libc_machine_xtensa_memcpy (noflash) if SPIRAM_CACHE_WORKAROUND = y: # The following libs are either used in a lot of places or in critical code. (such as panic or abort) # Thus, they shall always be placed in IRAM.