RISC-V: Add size optimized memcpy, memmove, memset and strcmp.

This patch adds implementations of memcpy, memmove, memset and strcmp
optimized for size. The changes have been tested in
riscv/riscv-gnu-toolchain by riscv-dejagnu with
riscv-sim.exp/riscv-sim-nano.exp.
This commit is contained in:
Jim Wilson 2019-05-22 17:36:57 -07:00
parent a9a0d219a4
commit 5c86f0da5f
8 changed files with 146 additions and 2 deletions

View File

@ -8,7 +8,8 @@ AM_CCASFLAGS = $(INCLUDES)
noinst_LIBRARIES = lib.a
lib_a_SOURCES = memset.S memcpy.c strlen.c strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_SOURCES = memmove.S memmove-stub.c memset.S memcpy-asm.S memcpy.c strlen.c \
strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_CCASFLAGS=$(AM_CCASFLAGS)
lib_a_CFLAGS=$(AM_CFLAGS)

View File

@ -70,6 +70,8 @@ ARFLAGS = cru
lib_a_AR = $(AR) $(ARFLAGS)
lib_a_LIBADD =
am_lib_a_OBJECTS = lib_a-memset.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
lib_a-memcpy-asm.$(OBJEXT) \
lib_a-memmove.$(OBJEXT) lib_a-memmove-stub.$(OBJEXT) \
lib_a-strlen.$(OBJEXT) lib_a-strcpy.$(OBJEXT) \
lib_a-strcmp.$(OBJEXT) lib_a-setjmp.$(OBJEXT) \
lib_a-ieeefp.$(OBJEXT) lib_a-ffs.$(OBJEXT)
@ -198,7 +200,8 @@ AUTOMAKE_OPTIONS = cygnus
INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
AM_CCASFLAGS = $(INCLUDES)
noinst_LIBRARIES = lib.a
lib_a_SOURCES = memset.S memcpy.c strlen.c strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_SOURCES = memcpy-asm.S memmove.S memmove-stub.c memset.S memcpy.c strlen.c \
strcpy.c strcmp.S setjmp.S ieeefp.c ffs.c
lib_a_CCASFLAGS = $(AM_CCASFLAGS)
lib_a_CFLAGS = $(AM_CFLAGS)
ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
@ -261,6 +264,18 @@ distclean-compile:
.S.obj:
$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
lib_a-memmove.o: memmove.S
$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memmove.o `test -f 'memmove.S' || echo '$(srcdir)/'`memmove.S
lib_a-memmove.obj: memmove.S
$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memmove.obj `if test -f 'memmove.S'; then $(CYGPATH_W) 'memmove.S'; else $(CYGPATH_W) '$(srcdir)/memmove.S'; fi`
lib_a-memcpy-asm.o: memcpy-asm.S
$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy-asm.o `test -f 'memcpy-asm.S' || echo '$(srcdir)/'`memcpy-asm.S
lib_a-memcpy-asm.obj: memcpy-asm.S
$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memcpy-asm.obj `if test -f 'memcpy-asm.S'; then $(CYGPATH_W) 'memcpy-asm.S'; else $(CYGPATH_W) '$(srcdir)/memcpy-asm.S'; fi`
lib_a-memset.o: memset.S
$(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-memset.o `test -f 'memset.S' || echo '$(srcdir)/'`memset.S
@ -285,6 +300,12 @@ lib_a-setjmp.obj: setjmp.S
.c.obj:
$(COMPILE) -c `$(CYGPATH_W) '$<'`
lib_a-memmove-stub.o: memmove-stub.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove-stub.o `test -f 'memmove-stub.c' || echo '$(srcdir)/'`memmove-stub.c
lib_a-memmove-stub.obj: memmove-stub.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memmove-stub.obj `if test -f 'memmove-stub.c'; then $(CYGPATH_W) 'memmove-stub.c'; else $(CYGPATH_W) '$(srcdir)/memmove-stub.c'; fi`
lib_a-memcpy.o: memcpy.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memcpy.o `test -f 'memcpy.c' || echo '$(srcdir)/'`memcpy.c

View File

@ -0,0 +1,32 @@
/* Copyright (c) 2019 SiFive Inc. All rights reserved.
This copyrighted material is made available to anyone wishing to use,
modify, copy, or redistribute it subject to the terms and conditions
of the FreeBSD License. This program is distributed in the hope that
it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
including the implied warranties of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. A copy of this license is available at
http://www.opensource.org/licenses.
*/
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
.text
.global memcpy
.type memcpy, @function
memcpy:
mv t1, a0
beqz a2, 2f
1:
lb t2, 0(a1)
sb t2, 0(t1)
add a2, a2, -1
add t1, t1, 1
add a1, a1, 1
bnez a2, 1b
2:
ret
.size memcpy, .-memcpy
#endif

View File

@ -9,6 +9,10 @@
http://www.opensource.org/licenses.
*/
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
//memcpy defined in memcpy-asm.S
#else
#include <string.h>
#include <stdint.h>
#include "../../string/local.h"
@ -81,3 +85,4 @@ small:
goto small;
return aa;
}
#endif

View File

@ -0,0 +1,14 @@
/* Copyright (c) 2019 SiFive Inc. All rights reserved.
This copyrighted material is made available to anyone wishing to use,
modify, copy, or redistribute it subject to the terms and conditions
of the FreeBSD License. This program is distributed in the hope that
it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
including the implied warranties of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. A copy of this license is available at
http://www.opensource.org/licenses.
*/
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
#include "../../string/memmove.c"
#endif

View File

@ -0,0 +1,40 @@
/* Copyright (c) 2019 SiFive Inc. All rights reserved.
This copyrighted material is made available to anyone wishing to use,
modify, copy, or redistribute it subject to the terms and conditions
of the FreeBSD License. This program is distributed in the hope that
it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
including the implied warranties of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. A copy of this license is available at
http://www.opensource.org/licenses.
*/
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
.text
.global memmove
.type memmove, @function
memmove:
beqz a2, 2f
mv t1, a0
li a3, 1
bgtu a1, a0, 1f
li a3, -1
addi a4, a2 , -1
add t1, t1, a4
add a1, a1, a4
1:
lb t2, 0(a1)
sb t2, 0(t1)
add a2, a2, -1
add t1, t1, a3
add a1, a1, a3
bnez a2, 1b
2:
ret
.size memmove, .-memmove
#endif

View File

@ -13,6 +13,20 @@
.global memset
.type memset, @function
memset:
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
mv t1, a0
beqz a2, 2f
1:
sb a1, 0(t1)
add a2, a2, -1
add t1, t1, 1
bnez a2, 1b
2:
ret
#else
li t1, 15
move a4, a0
bleu a2, t1, .Ltiny
@ -95,4 +109,5 @@ memset:
add a2, a2, a5
bleu a2, t1, .Ltiny
j .Laligned
#endif
.size memset, .-memset

View File

@ -19,6 +19,21 @@
.globl strcmp
.type strcmp, @function
strcmp:
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
1:
lbu a2, 0(a0)
lbu a3, 0(a1)
add a0, a0, 1
add a1, a1, 1
bne a2, a3, 2f
bnez a2, 1b
2:
sub a0, a2, a3
ret
.size strcmp, .-strcmp
#else
or a4, a0, a1
li t2, -1
and a4, a4, SZREG-1
@ -146,3 +161,4 @@ strcmp:
mask:
.dword 0x7f7f7f7f7f7f7f7f
#endif
#endif