Skip to content

libs/libc/risc-v: Refresh memcpy and memset with XLEN-adaptive loops. - #19781

Merged
xiaoxiang781216 merged 1 commit into
apache:masterfrom
Shanks0224:riscv-memcpy-memset-refresh
Aug 12, 2026
Merged

libs/libc/risc-v: Refresh memcpy and memset with XLEN-adaptive loops.#19781
xiaoxiang781216 merged 1 commit into
apache:masterfrom
Shanks0224:riscv-memcpy-memset-refresh

Conversation

@Shanks0224

Copy link
Copy Markdown
Contributor

libs/libc/risc-v: Refresh memcpy and memset with XLEN-adaptive loops.

Summary

Rewrite arch_memcpy.S and arch_memset.S to be register-width aware on
both RV32 and RV64 using REG_L/REG_S/SZREG macros from asm.h.

The old memcpy always used lw/sw even on RV64, wasting half the memory
bandwidth, and unrolled only 64 bytes per iteration. The old memset
unrolled only 16 bytes per iteration.

Changes:

  • memcpy: 16xSZREG unrolled main loop (128B/iter on RV64, 64B on RV32),
    shift-merge path for misaligned source so no load or store is ever
    unaligned, single SZREG and byte loops for remainder.
  • memset: 32xSZREG unrolled main loop (256B/iter on RV64, 128B on RV32)
    with Duff's device for non-power-of-two remainders. .option norvc
    ensures fixed 4-byte instruction width for correct jump calculation.
    Zero-length input handled correctly.

Impact

  • Is new feature added? NO. Existing functions refreshed.
  • Impact on user? NO.
  • Impact on build? NO.
  • Impact on hardware? NO.
  • Impact on documentation? NO.
  • Impact on security? NO.
  • Impact on compatibility? NO. Only active when CONFIG_RISCV_STRING_FUNCTION=y (default n).

Testing

I confirm that changes are verified on local setup and works as intended:

  • Build Host: Linux x86_64, riscv-none-elf-gcc 13.2.1
  • Target(s): QEMU rv-virt RV32 (rv-virt:nsh), QEMU rv-virt RV64 (rv-virt:nsh64)

Correctness: arch_libctest reports PASSED for memcpy and memset across
alignments 0-7 and sizes 1-128.

Performance (QEMU RV32, rdcycle, 128 bytes, 100 iterations average):

                     baseline    optimized    speedup
  memcpy(128)           952          676       1.41x
  memset(128)           562          237       2.37x

Testing logs (optimized):

nsh> arch_libctest
Testing memcpy...
memcpy: PASSED
memcpy(128) avg cycles: 676
Testing memset...
memset: PASSED
memset(128) avg cycles: 237
...
arch_libc_test Passed

Rewrite arch_memcpy.S and arch_memset.S to be register-width aware on
both RV32 and RV64 using REG_L/REG_S/SZREG macros from asm.h.

memcpy gains:
 - 16xSZREG unrolled main loop (128B/iter on RV64, 64B on RV32).
 - Shift-merge path for misaligned src: reads two aligned words
   straddling each output word and shifts them together, so no load
   or store is ever misaligned.
 - Single SZREG and byte loops for remainder and small copies.

memset gains:
 - 32xSZREG unrolled main loop (256B/iter on RV64, 128B on RV32)
   using Duff's device for non-power-of-two remainders.
 - .option norvc ensures fixed 4-byte instruction width for correct
   jump offset calculation in the Duff's device entry.
 - Zero-length input handled correctly (branch to guarded tail).

The old memcpy always used lw/sw even on RV64, wasting half the
memory bandwidth. The old memset unrolled only 16 bytes per iteration.

Signed-off-by: ganjing <ganjing@xiaomi.com>
@github-actions github-actions Bot added Area: OS Components OS Components issues Size: M The size of the change in this PR is medium labels Aug 11, 2026
@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@xiaoxiang781216

Copy link
Copy Markdown
Contributor

@Fishwaldo could you benchmark this patch on your hardware?

@xiaoxiang781216
xiaoxiang781216 merged commit a0fcbb7 into apache:master Aug 12, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: OS Components OS Components issues Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants