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] |
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__))
Attachment:
newlib-str-5.patch
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |