Hello,
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.
From fc910e60c0ce876285b0437e8d8c5995b6cf9757 Mon Sep 17 00:00:00 2001
From: Ilia Diachkov <[email protected]>
Date: Sat, 18 May 2019 01:49:27 +0300
Subject: [PATCH 1/2] RISC-V: Add memcpy, memmove, memset and strcmp
implementations optimized for size.
---
newlib/libc/machine/riscv/Makefile.am | 3 ++-
newlib/libc/machine/riscv/Makefile.in | 23 +++++++++++++++++-
newlib/libc/machine/riscv/memcpy-asm.S | 33
++++++++++++++++++++++++++
newlib/libc/machine/riscv/memcpy.c | 6 +++++
newlib/libc/machine/riscv/memmove-stub.c | 14 +++++++++++
newlib/libc/machine/riscv/memmove.S | 40
++++++++++++++++++++++++++++++++
newlib/libc/machine/riscv/memset.S | 15 ++++++++++++
newlib/libc/machine/riscv/strcmp.S | 16 +++++++++++++
8 files changed, 148 insertions(+), 2 deletions(-)
create mode 100644 newlib/libc/machine/riscv/memcpy-asm.S
create mode 100644 newlib/libc/machine/riscv/memmove-stub.c
create mode 100644 newlib/libc/machine/riscv/memmove.S
diff --git a/newlib/libc/machine/riscv/Makefile.am
b/newlib/libc/machine/riscv/Makefile.am
index 676df3e..017b4be 100644
--- a/newlib/libc/machine/riscv/Makefile.am
+++ b/newlib/libc/machine/riscv/Makefile.am
@@ -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)
diff --git a/newlib/libc/machine/riscv/Makefile.in
b/newlib/libc/machine/riscv/Makefile.in
index fd6d2ef..304dd35 100644
--- a/newlib/libc/machine/riscv/Makefile.in
+++ b/newlib/libc/machine/riscv/Makefile.in
@@ -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
diff --git a/newlib/libc/machine/riscv/memcpy-asm.S
b/newlib/libc/machine/riscv/memcpy-asm.S
new file mode 100644
index 0000000..33d47a4
--- /dev/null
+++ b/newlib/libc/machine/riscv/memcpy-asm.S
@@ -0,0 +1,33 @@
+/* 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
+
diff --git a/newlib/libc/machine/riscv/memcpy.c
b/newlib/libc/machine/riscv/memcpy.c
index c717f9f..8099b14 100644
--- a/newlib/libc/machine/riscv/memcpy.c
+++ b/newlib/libc/machine/riscv/memcpy.c
@@ -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>
@@ -79,3 +83,5 @@ small:
goto small;
return aa;
}
+#endif
+
diff --git a/newlib/libc/machine/riscv/memmove-stub.c
b/newlib/libc/machine/riscv/memmove-stub.c
new file mode 100644
index 0000000..d882e46
--- /dev/null
+++ b/newlib/libc/machine/riscv/memmove-stub.c
@@ -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
diff --git a/newlib/libc/machine/riscv/memmove.S
b/newlib/libc/machine/riscv/memmove.S
new file mode 100644
index 0000000..98289a4
--- /dev/null
+++ b/newlib/libc/machine/riscv/memmove.S
@@ -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
diff --git a/newlib/libc/machine/riscv/memset.S
b/newlib/libc/machine/riscv/memset.S
index 337ed53..d28a219 100644
--- a/newlib/libc/machine/riscv/memset.S
+++ b/newlib/libc/machine/riscv/memset.S
@@ -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
diff --git a/newlib/libc/machine/riscv/strcmp.S
b/newlib/libc/machine/riscv/strcmp.S
index 71c0853..1a9303e 100644
--- a/newlib/libc/machine/riscv/strcmp.S
+++ b/newlib/libc/machine/riscv/strcmp.S
@@ -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
--
1.8.3.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.