This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Update newlib to support efficient string operation functions for Thumb.


Hi,

The source files in newlib/libc/machine/arm/ are not so efficient enough to
sopport Thumb. 

For Cortex-M0, if we don't define '__OPTIMIZE_SIZE__' or
'PREFER_SIZE_OVER_SPEED' which means size is not preferred, inefficient code
will be used. This may result in pool benchmark performance.

In this case, we can include newlib/libc/string/strcmp.c to improve the
performance. And if size is preferred, the original code will be used.

I have done some tests on Dhrystone benchmark, and the performance of
Cortex-M0 can be improved to 13% with this solution.

The strlen.c can be improved in the similar way.

Bootstrap and no make check regression on X86-64.

Patch also attached for convenience.

Thanks and Best Regards,
Hale Wang

newlib/ChangeLog:

2014-08-14  Hale Wang  <hale.wang@arm.com>

	* libc/machine/arm/strcmp-stub.c: New file.
	* libc/machine/arm/strcmp.S: Replace with wrapper.
	* libc/machine/arm/strlen.c: Likewise.
	* libc/machine/arm/Makefile.am: Add dependencies.
	* libc/machine/arm/Makefile.in: Regenerated.

============================================================================
=

diff --git a/newlib/libc/machine/arm/Makefile.am
b/newlib/libc/machine/arm/Makefile.am
index fb33926..9940eec 100644
--- a/newlib/libc/machine/arm/Makefile.am
+++ b/newlib/libc/machine/arm/Makefile.am
@@ -8,7 +8,7 @@ AM_CCASFLAGS = $(INCLUDES)
 
 noinst_LIBRARIES = lib.a
 
-lib_a_SOURCES = setjmp.S access.c strlen.c strcmp.S strcpy.c \
+lib_a_SOURCES = setjmp.S access.c strlen.c strcmp-stub.c strcmp.S strcpy.c
\
 	        memcpy.S memcpy-stub.c memchr-stub.c memchr.S \
 		strlen.c strlen-armv7.S
 lib_a_CCASFLAGS=$(AM_CCASFLAGS)
diff --git a/newlib/libc/machine/arm/Makefile.in
b/newlib/libc/machine/arm/Makefile.in
index 1ccfac5..ba088a6 100644
--- a/newlib/libc/machine/arm/Makefile.in
+++ b/newlib/libc/machine/arm/Makefile.in
@@ -70,7 +70,7 @@ ARFLAGS = cru
 lib_a_AR = $(AR) $(ARFLAGS)
 lib_a_LIBADD =
 am_lib_a_OBJECTS = lib_a-setjmp.$(OBJEXT) lib_a-access.$(OBJEXT) \
-	lib_a-strlen.$(OBJEXT) lib_a-strcmp.$(OBJEXT) \
+	lib_a-strlen.$(OBJEXT) lib_a-strcmp.$(OBJEXT)
lib_a-strcmp-stub.$(OBJEXT)\
 	lib_a-strcpy.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
 	lib_a-memcpy-stub.$(OBJEXT) lib_a-memchr-stub.$(OBJEXT) \
 	lib_a-memchr.$(OBJEXT) lib_a-strlen.$(OBJEXT) \
@@ -200,7 +200,7 @@ AUTOMAKE_OPTIONS = cygnus
 INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
 AM_CCASFLAGS = $(INCLUDES)
 noinst_LIBRARIES = lib.a
-lib_a_SOURCES = setjmp.S access.c strlen.c strcmp.S strcpy.c \
+lib_a_SOURCES = setjmp.S access.c strlen.c strcmp-stub.c strcmp.S strcpy.c
\
 	        memcpy.S memcpy-stub.c memchr-stub.c memchr.S \
 		strlen.c strlen-armv7.S
 
@@ -336,6 +336,12 @@ lib_a-memchr-stub.o: memchr-stub.c
 lib_a-memchr-stub.obj: memchr-stub.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS)
$(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-memchr-stub.obj `if test
-f 'memchr-stub.c'; then $(CYGPATH_W) 'memchr-stub.c'; else $(CYGPATH_W)
'$(srcdir)/memchr-stub.c'; fi`
 
+lib_a-strcmp-stub.o: strcmp-stub.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS)
$(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcmp-stub.o `test -f
'strcmp-stub.c' || echo '$(srcdir)/'`strcmp-stub.c
+
+lib_a-strcmp-stub.obj: strcmp-stub.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS)
$(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strcmp-stub.obj `if test
-f 'strcmp-stub.c'; then $(CYGPATH_W) 'strcmp-stub.c'; else $(CYGPATH_W)
'$(srcdir)/strcmp-stub.c'; fi`
+
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
diff --git a/newlib/libc/machine/arm/strcmp-stub.c
b/newlib/libc/machine/arm/strcmp-stub.c
new file mode 100644
index 0000000..1533205
--- /dev/null
+++ b/newlib/libc/machine/arm/strcmp-stub.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 ARM Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR
IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* The sole purpose of this file is to include the plain strcmp provided
+   in newlib.  An optimized version of strcmp is provided in the c
+   file strcmp.c in "../../string/."  */
+#if defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) \
+	|| (__ARM_ARCH == 6 && __ARM_ARCH_PROFILE == 'M')
+
+# if defined (__thumb__) && !defined (__thumb2__)
+/* Thumb1 only variant.  If size is preferred, see strcmp.S.
+   If speed is preferred, use "../../string/strcmp.c."  */
+
+#  if !defined (__OPTIMIZE_SIZE__) && !defined (PREFER_SIZE_OVER_SPEED)
+#   include "../../string/strcmp.c"
+#  endif
+
+# endif
+#endif
diff --git a/newlib/libc/machine/arm/strcmp.S
b/newlib/libc/machine/arm/strcmp.S
index 1742322..7bcb838 100644
--- a/newlib/libc/machine/arm/strcmp.S
+++ b/newlib/libc/machine/arm/strcmp.S
@@ -64,8 +64,13 @@
 	|| (__ARM_ARCH == 6 && __ARM_ARCH_PROFILE == 'M')
 
 # if defined (__thumb__) && !defined (__thumb2__)
-/* Thumb1 only variant.  */
-#  include "strcmp-armv4t.S"
+/* Thumb1 only variant.  If size is preferred, use strcmp-armv4t.S.
+   If speed is preferred, see strcmp-stub.c in the same directory.  */
+
+#  if defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED)
+#   include "strcmp-armv4t.S"
+#  endif
+
 # else
 #  include "strcmp-arm-tiny.S"
 # endif
diff --git a/newlib/libc/machine/arm/strlen.c
b/newlib/libc/machine/arm/strlen.c
index b8de229..9945fee 100644
--- a/newlib/libc/machine/arm/strlen.c
+++ b/newlib/libc/machine/arm/strlen.c
@@ -32,8 +32,13 @@
 #include <limits.h>
 
 #if defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED) || \
-  (defined (__thumb__) && !defined (__thumb2__))
+	(defined (__thumb__) && !defined (__thumb2__))
 
+# if !defined (PREFER_SIZE_OVER_SPEED) && !defined (__OPTIMIZE_SIZE__)
+/* Thumb1 only variant.
+   If speed is preferred, use "../../string/strlen.c".  */
+#  include "../../string/strlen.c"
+# else
 size_t
 strlen (const char* str)
 {
@@ -43,7 +48,7 @@ strlen (const char* str)
   asm ("mov	%0, #0\n"
        "1:\n\t"
        "ldrb	%1, [%2, %0]\n\t"
-       "add 	%0, %0, #1\n\t"
+       "add	%0, %0, #1\n\t"
        "cmp	%1, #0\n\t"
        "bne	1b"
        : "=&r" (len), "=&r" (scratch) : "r" (str) : "memory", "cc");
@@ -58,6 +63,7 @@ strlen (const char* str)
   return end - str - 1;
 #endif
 }
+#endif
 #else
 
 #if !(defined(_ISA_ARM_7) || defined(__ARM_ARCH_6T2__))



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]