]> sourceware.org Git - newlib-cygwin.git/commitdiff
RISC-V: Add size optimized memcpy, memmove, memset and strcmp.
authorJim Wilson <jimw@sifive.com>
Thu, 23 May 2019 00:36:57 +0000 (17:36 -0700)
committerJim Wilson <jimw@sifive.com>
Thu, 23 May 2019 00:36:57 +0000 (17:36 -0700)
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.

newlib/libc/machine/riscv/Makefile.am
newlib/libc/machine/riscv/Makefile.in
newlib/libc/machine/riscv/memcpy-asm.S [new file with mode: 0644]
newlib/libc/machine/riscv/memcpy.c
newlib/libc/machine/riscv/memmove-stub.c [new file with mode: 0644]
newlib/libc/machine/riscv/memmove.S [new file with mode: 0644]
newlib/libc/machine/riscv/memset.S
newlib/libc/machine/riscv/strcmp.S

index 676df3e88784662b0a763ea08b5b7304c39163b1..017b4be2e98895463dafbfa983c0fdf31e74b5a1 100644 (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)
 
index fd6d2ef14ac50c1d01ea89a871170d27d8049faa..304dd35ae77379582ddf1b92c6772ae35d3e2120 100644 (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
 
diff --git a/newlib/libc/machine/riscv/memcpy-asm.S b/newlib/libc/machine/riscv/memcpy-asm.S
new file mode 100644 (file)
index 0000000..5571e47
--- /dev/null
@@ -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
index a0ab78a0a08505c1c50a9da2913a67009f5efd5d..07e8e0076cc0a2cd680baf685683bf4ccab81fb9 100644 (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
diff --git a/newlib/libc/machine/riscv/memmove-stub.c b/newlib/libc/machine/riscv/memmove-stub.c
new file mode 100644 (file)
index 0000000..d882e46
--- /dev/null
@@ -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 (file)
index 0000000..66d9cd4
--- /dev/null
@@ -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
index 337ed5365eb2ec4091ea8c086711f76f6a802cf1..a717ae7fbbcee9858875aa9a6f83d946e3e5e354 100644 (file)
 .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
index 71c08537e5d9b8ba02de62494c0a866c4e6ed22b..eaf6d4b3c81635c5010c0c7446e62eda2cb17659 100644 (file)
 .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
This page took 0.040659 seconds and 5 git commands to generate.