[1/2] RISC-V: Add memcpy, memmove, memset and strcmp implementations optimized for size.

Message ID 30172b5bd911a7bf61b800568cfd7fb1@optimitech.com
State New
Headers show
Series
  • [1/2] RISC-V: Add memcpy, memmove, memset and strcmp implementations optimized for size.
Related show

Commit Message

ilia.diachkov@optimitech.com May 17, 2019, 11:53 p.m.
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 <ilia.diachkov@optimitech.com>

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

-- 
1.8.3.1

Comments

Jim Wilson May 20, 2019, 9:09 p.m. | #1
On Fri, May 17, 2019 at 4:53 PM <ilia.diachkov@optimitech.com> wrote:
> 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.


The patch was corrupted by the mailer.   Long lines were line wrapped.
Lines that should have only a single space are now blank lines.  Line
that should start with one space now have two.  Using git send-email
should work better if you can use that.  Otherwise, you probably need
to include the patches as attachments instead of trying to insert the
text of the patch into an email.

Optimitech is working on a contract for SiFive, so having the SiFive
name in the copyright statements is OK.  Though I don't mind if the
Optimitech name is in there too.

I tested an earlier version of this (without the memmove-stub.c fix),
and it gets a thumbs up from me, though I'm not an official newlib
maintainer so can't approve it.

Jim
ilia.diachkov@optimitech.com May 20, 2019, 11:29 p.m. | #2
Thanks for you notice, Jim. Currently I cannot use git send-email, so I 
try to provide the patches in attachment.

Jim Wilson писал 2019-05-20 16:09:
> On Fri, May 17, 2019 at 4:53 PM <ilia.diachkov@optimitech.com> wrote:

>> 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.

> 

> The patch was corrupted by the mailer.   Long lines were line wrapped.

> Lines that should have only a single space are now blank lines.  Line

> that should start with one space now have two.  Using git send-email

> should work better if you can use that.  Otherwise, you probably need

> to include the patches as attachments instead of trying to insert the

> text of the patch into an email.

> 

> Optimitech is working on a contract for SiFive, so having the SiFive

> name in the copyright statements is OK.  Though I don't mind if the

> Optimitech name is in there too.

> 

> I tested an earlier version of this (without the memmove-stub.c fix),

> and it gets a thumbs up from me, though I'm not an official newlib

> maintainer so can't approve it.

> 

> Jim
From 99b42109278140daac310e3064c59ac21db42564 Mon Sep 17 00:00:00 2001
From: Ilia Diachkov <ilia.diachkov@optimitech.com>
Date: Tue, 21 May 2019 01:48:46 +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
Kito Cheng May 21, 2019, 3:18 a.m. | #3
Hi Ilia:

Just few minor comment:

1. There is some trailing white space in the patch, could you clean up that?

/home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:101:
trailing whitespace.
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
/home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:117:
trailing whitespace.
2:
/home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:181:
trailing whitespace.
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
/home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:205:
trailing whitespace.
2:
/home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:218:
trailing whitespace.
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

2. Patch conflict with current master branch, seems like you forgot
rebase with trunk before send patch.

error: patch failed: newlib/libc/machine/riscv/memcpy.c:9
error: newlib/libc/machine/riscv/memcpy.c: patch does not apply


On Tue, May 21, 2019 at 7:30 AM <ilia.diachkov@optimitech.com> wrote:
>

> Thanks for you notice, Jim. Currently I cannot use git send-email, so I

> try to provide the patches in attachment.

>

> Jim Wilson писал 2019-05-20 16:09:

> > On Fri, May 17, 2019 at 4:53 PM <ilia.diachkov@optimitech.com> wrote:

> >> 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.

> >

> > The patch was corrupted by the mailer.   Long lines were line wrapped.

> > Lines that should have only a single space are now blank lines.  Line

> > that should start with one space now have two.  Using git send-email

> > should work better if you can use that.  Otherwise, you probably need

> > to include the patches as attachments instead of trying to insert the

> > text of the patch into an email.

> >

> > Optimitech is working on a contract for SiFive, so having the SiFive

> > name in the copyright statements is OK.  Though I don't mind if the

> > Optimitech name is in there too.

> >

> > I tested an earlier version of this (without the memmove-stub.c fix),

> > and it gets a thumbs up from me, though I'm not an official newlib

> > maintainer so can't approve it.

> >

> > Jim
ilia.diachkov@optimitech.com May 21, 2019, 9:21 a.m. | #4
Hi Kito,

Thanks. I have attached the corrected patch.

Kito Cheng писал 2019-05-20 22:18:
> Hi Ilia:

> 

> Just few minor comment:

> 

> 1. There is some trailing white space in the patch, could you clean up 

> that?

> 

> /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:101:

> trailing whitespace.

> #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:117:

> trailing whitespace.

> 2:

> /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:181:

> trailing whitespace.

> #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:205:

> trailing whitespace.

> 2:

> /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:218:

> trailing whitespace.

> #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> 

> 2. Patch conflict with current master branch, seems like you forgot

> rebase with trunk before send patch.

> 

> error: patch failed: newlib/libc/machine/riscv/memcpy.c:9

> error: newlib/libc/machine/riscv/memcpy.c: patch does not apply

> 

> 

> On Tue, May 21, 2019 at 7:30 AM <ilia.diachkov@optimitech.com> wrote:

>> 

>> Thanks for you notice, Jim. Currently I cannot use git send-email, so 

>> I

>> try to provide the patches in attachment.

>> 

>> Jim Wilson писал 2019-05-20 16:09:

>> > On Fri, May 17, 2019 at 4:53 PM <ilia.diachkov@optimitech.com> wrote:

>> >> 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.

>> >

>> > The patch was corrupted by the mailer.   Long lines were line wrapped.

>> > Lines that should have only a single space are now blank lines.  Line

>> > that should start with one space now have two.  Using git send-email

>> > should work better if you can use that.  Otherwise, you probably need

>> > to include the patches as attachments instead of trying to insert the

>> > text of the patch into an email.

>> >

>> > Optimitech is working on a contract for SiFive, so having the SiFive

>> > name in the copyright statements is OK.  Though I don't mind if the

>> > Optimitech name is in there too.

>> >

>> > I tested an earlier version of this (without the memmove-stub.c fix),

>> > and it gets a thumbs up from me, though I'm not an official newlib

>> > maintainer so can't approve it.

>> >

>> > Jim
From 49ac400f0a0bf4d9b976b5bdfa02152e16dd3dd4 Mon Sep 17 00:00:00 2001
From: Ilia Diachkov <ilia.diachkov@optimitech.com>
Date: Tue, 21 May 2019 11:56:54 +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   | 32 +++++++++++++++++++++++++
 newlib/libc/machine/riscv/memcpy.c       |  5 ++++
 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, 146 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..5571e47
--- /dev/null
+++ b/newlib/libc/machine/riscv/memcpy-asm.S
@@ -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
diff --git a/newlib/libc/machine/riscv/memcpy.c b/newlib/libc/machine/riscv/memcpy.c
index a0ab78a..07e8e00 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>
 #include "../../string/local.h"
@@ -81,3 +85,4 @@ 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..66d9cd4
--- /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..a717ae7 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..eaf6d4b 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
Kito Cheng May 22, 2019, 9 a.m. | #5
Hi Illa:

Thanks, this patch LGTM :)


On Tue, May 21, 2019 at 5:21 PM <ilia.diachkov@optimitech.com> wrote:
>

> Hi Kito,

>

> Thanks. I have attached the corrected patch.

>

> Kito Cheng писал 2019-05-20 22:18:

> > Hi Ilia:

> >

> > Just few minor comment:

> >

> > 1. There is some trailing white space in the patch, could you clean up

> > that?

> >

> > /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:101:

> > trailing whitespace.

> > #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> > /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:117:

> > trailing whitespace.

> > 2:

> > /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:181:

> > trailing whitespace.

> > #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> > /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:205:

> > trailing whitespace.

> > 2:

> > /home/users/kito/riscv-gnu-toolchain-workspace/riscv-gnu-toolchain/.git/modules/riscv-newlib/rebase-apply/patch:218:

> > trailing whitespace.

> > #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)

> >

> > 2. Patch conflict with current master branch, seems like you forgot

> > rebase with trunk before send patch.

> >

> > error: patch failed: newlib/libc/machine/riscv/memcpy.c:9

> > error: newlib/libc/machine/riscv/memcpy.c: patch does not apply

> >

> >

> > On Tue, May 21, 2019 at 7:30 AM <ilia.diachkov@optimitech.com> wrote:

> >>

> >> Thanks for you notice, Jim. Currently I cannot use git send-email, so

> >> I

> >> try to provide the patches in attachment.

> >>

> >> Jim Wilson писал 2019-05-20 16:09:

> >> > On Fri, May 17, 2019 at 4:53 PM <ilia.diachkov@optimitech.com> wrote:

> >> >> 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.

> >> >

> >> > The patch was corrupted by the mailer.   Long lines were line wrapped.

> >> > Lines that should have only a single space are now blank lines.  Line

> >> > that should start with one space now have two.  Using git send-email

> >> > should work better if you can use that.  Otherwise, you probably need

> >> > to include the patches as attachments instead of trying to insert the

> >> > text of the patch into an email.

> >> >

> >> > Optimitech is working on a contract for SiFive, so having the SiFive

> >> > name in the copyright statements is OK.  Though I don't mind if the

> >> > Optimitech name is in there too.

> >> >

> >> > I tested an earlier version of this (without the memmove-stub.c fix),

> >> > and it gets a thumbs up from me, though I'm not an official newlib

> >> > maintainer so can't approve it.

> >> >

> >> > Jim
Jim Wilson May 23, 2019, 12:42 a.m. | #6
On Wed, May 22, 2019 at 2:00 AM Kito Cheng <kito.cheng@gmail.com> wrote:
> Hi Illa:

> Thanks, this patch LGTM :)


I committed and pushed the two patches.

Jim

Patch

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