[PATCH 2/5] RISC-V: memmove() speed optimized: Replace macros and use fixed-width types

Alexey Lapshin alexey.lapshin@espressif.com
Tue May 27 06:04:16 GMT 2025


These changes makes newlib ignore "_HAVE_HW_MISALIGNED_ACCESS".

What purpose of replacing macros? (I can't see advantages to this).
Is "sizeof(long)" gives something different compared to SZREG ?

On Mon, 2025-05-26 at 17:05 +0200, m fally wrote:
> Remove macros or replace them with static inline functions or RISC-V
> specific macros where applicable.
> Change data types to fixed-width and/or RISC-V specific types.
> 
> Reviewed-by: Christian Herber <christian.herber@oss.nxp.com>
> Signed-off-by: m fally <marlene.fally@gmail.com>
> ---
>  newlib/libc/machine/riscv/memmove.c | 60 +++++++++++++++++------------
>  1 file changed, 35 insertions(+), 25 deletions(-)
> 
> diff --git a/newlib/libc/machine/riscv/memmove.c b/newlib/libc/machine/riscv/memmove.c
> index b48da0905..2e5c6ca9b 100644
> --- a/newlib/libc/machine/riscv/memmove.c
> +++ b/newlib/libc/machine/riscv/memmove.c
> @@ -14,19 +14,29 @@
>  #else
>  
>  #include "../../string/local.h"
> -#include <_ansi.h>
> +#include "sys/asm.h"
> +#include "xlenint.h"
>  #include <limits.h>
>  #include <stddef.h>
>  #include <string.h>
>  
> -/*SUPPRESS 20*/
> +static inline uint8_t
> +__libc_fast_xlen_aligned (void *dst, const void *src)
> +{
> +#if defined(__riscv_misaligned_fast)
> +  return 1;
> +#else
> +  return !(((uintxlen_t)src & (SZREG - 1)) | ((uintxlen_t)dst & (SZREG - 1)));
> +#endif
> +}
> +
>  void *__inhibit_loop_to_libcall
>  memmove (void *dst_void, const void *src_void, size_t length)
>  {
> -  char *dst = dst_void;
> -  const char *src = src_void;
> -  long *aligned_dst;
> -  const long *aligned_src;
> +  unsigned char *dst = dst_void;
> +  const unsigned char *src = src_void;
> +  uintxlen_t *aligned_dst;
> +  const uintxlen_t *aligned_src;
>  
>    if (src < dst && dst < src + length)
>      {
> @@ -34,21 +44,21 @@ memmove (void *dst_void, const void *src_void, size_t length)
>        src += length;
>        dst += length;
>  
> -      if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst))
> +      if (length >= SZREG && __libc_fast_xlen_aligned (dst, src))
>          {
> -          aligned_dst = (long *)dst;
> -          aligned_src = (long *)src;
> +          aligned_dst = (uintxlen_t *)dst;
> +          aligned_src = (uintxlen_t *)src;
>  
> -          /* Copy one long word at a time if possible.  */
> -          while (!TOO_SMALL_LITTLE_BLOCK (length))
> +          /* Copy one uintxlen_t word at a time if possible.  */
> +          while (length >= SZREG)
>              {
>                *--aligned_dst = *--aligned_src;
> -              length -= LITTLE_BLOCK_SIZE;
> +              length -= SZREG;
>              }
>  
>            /* Pick up any residual with a byte copier.  */
> -          dst = (char *)aligned_dst;
> -          src = (char *)aligned_src;
> +          dst = (unsigned char *)aligned_dst;
> +          src = (unsigned char *)aligned_src;
>          }
>  
>        while (length--)
> @@ -61,31 +71,31 @@ memmove (void *dst_void, const void *src_void, size_t length)
>        /* Use optimizing algorithm for a non-destructive copy to closely
>           match memcpy. If the size is small or either SRC or DST is unaligned,
>           then punt into the byte copy loop.  This should be rare.  */
> -      if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst))
> +      if (length >= SZREG && __libc_fast_xlen_aligned (dst, src))
>          {
> -          aligned_dst = (long *)dst;
> -          aligned_src = (long *)src;
> +          aligned_dst = (uintxlen_t *)dst;
> +          aligned_src = (uintxlen_t *)src;
>  
> -          /* Copy 4X long words at a time if possible.  */
> -          while (!TOO_SMALL_BIG_BLOCK (length))
> +          /* Copy 4X uintxlen_t words at a time if possible.  */
> +          while (length >= (SZREG * 4))
>              {
>                *aligned_dst++ = *aligned_src++;
>                *aligned_dst++ = *aligned_src++;
>                *aligned_dst++ = *aligned_src++;
>                *aligned_dst++ = *aligned_src++;
> -              length -= BIG_BLOCK_SIZE;
> +              length -= SZREG * 4;
>              }
>  
> -          /* Copy one long word at a time if possible.  */
> -          while (!TOO_SMALL_LITTLE_BLOCK (length))
> +          /* Copy one uintxlen_t word at a time if possible.  */
> +          while (length >= SZREG)
>              {
>                *aligned_dst++ = *aligned_src++;
> -              length -= LITTLE_BLOCK_SIZE;
> +              length -= SZREG;
>              }
>  
>            /* Pick up any residual with a byte copier.  */
> -          dst = (char *)aligned_dst;
> -          src = (char *)aligned_src;
> +          dst = (unsigned char *)aligned_dst;
> +          src = (unsigned char *)aligned_src;
>          }
>  
>        while (length--)



More information about the Newlib mailing list