]> sourceware.org Git - newlib-cygwin.git/commitdiff
2013-01-10 Marcus Shawcroft <marcus.shawcroft@linaro.org>
authorMarcus Shawcroft <marcus.shawcroft@arm.com>
Thu, 10 Jan 2013 12:57:11 +0000 (12:57 +0000)
committerMarcus Shawcroft <marcus.shawcroft@arm.com>
Thu, 10 Jan 2013 12:57:11 +0000 (12:57 +0000)
        * libc/machine/aarch64/Makefile.am (lib_a_SOURCES):
        Add strlen.S and strlen-stub.c.
        * libc/machine/aarch64/Makefile.in: Regenerated.
        * libc/machine/aarch64/strlen-stub.c: New file.
        * libc/machine/aarch64/strlen.S: New file.

newlib/ChangeLog
newlib/libc/machine/aarch64/Makefile.am
newlib/libc/machine/aarch64/Makefile.in
newlib/libc/machine/aarch64/strlen-stub.c [new file with mode: 0644]
newlib/libc/machine/aarch64/strlen.S [new file with mode: 0644]

index 2377ec10bc62e76ce2bfaaa8de40cef93d6f1a3d..ecff125ffe3321b079f90fc094167be8fe674d8d 100644 (file)
@@ -1,3 +1,11 @@
+2013-01-10  Marcus Shawcroft  <marcus.shawcroft@linaro.org>
+
+       * libc/machine/aarch64/Makefile.am (lib_a_SOURCES):
+       Add strlen.S and strlen-stub.c.
+       * libc/machine/aarch64/Makefile.in: Regenerated.
+       * libc/machine/aarch64/strlen-stub.c: New file.
+       * libc/machine/aarch64/strlen.S: New file.
+
 2013-01-10  Marcus Shawcroft  <marcus.shawcroft@linaro.org>
 
        * libc/machine/aarch64/Makefile.am (lib_a_SOURCES):
index 5623bbd76fd2a2d1216346a9513410f02032bb0d..d454975d746a4b2fbedb36b89e4da00bf022f8da 100644 (file)
@@ -18,6 +18,8 @@ lib_a_SOURCES += memset.S
 lib_a_SOURCES += setjmp.S
 lib_a_SOURCES += strcmp-stub.c
 lib_a_SOURCES += strcmp.S
+lib_a_SOURCES += strlen-stub.c
+lib_a_SOURCES += strlen.S
 lib_a_SOURCES += strncmp-stub.c
 lib_a_SOURCES += strncmp.S
 
index c3d5882ffc0e720f4eaea7e337f0af4498978f6e..78a312d34dd5939e24f647db867c3ea3115f949c 100644 (file)
@@ -73,7 +73,8 @@ am_lib_a_OBJECTS = lib_a-memcpy-stub.$(OBJEXT) lib_a-memcpy.$(OBJEXT) \
        lib_a-memmove-stub.$(OBJEXT) lib_a-memmove.$(OBJEXT) \
        lib_a-memset-stub.$(OBJEXT) lib_a-memset.$(OBJEXT) \
        lib_a-setjmp.$(OBJEXT) lib_a-strcmp-stub.$(OBJEXT) \
-       lib_a-strcmp.$(OBJEXT) lib_a-strncmp-stub.$(OBJEXT) \
+       lib_a-strcmp.$(OBJEXT) lib_a-strlen-stub.$(OBJEXT) \
+       lib_a-strlen.$(OBJEXT) lib_a-strncmp-stub.$(OBJEXT) \
        lib_a-strncmp.$(OBJEXT)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@
@@ -202,7 +203,7 @@ AM_CCASFLAGS = $(INCLUDES)
 noinst_LIBRARIES = lib.a
 lib_a_SOURCES = memcpy-stub.c memcpy.S memmove-stub.c memmove.S \
        memset-stub.c memset.S setjmp.S strcmp-stub.c strcmp.S \
-       strncmp-stub.c strncmp.S
+       strlen-stub.c strlen.S strncmp-stub.c strncmp.S
 lib_a_CCASFLAGS = $(AM_CCASFLAGS)
 lib_a_CFLAGS = $(AM_CFLAGS)
 ACLOCAL_AMFLAGS = -I ../../.. -I ../../../..
@@ -295,6 +296,12 @@ lib_a-strcmp.o: strcmp.S
 lib_a-strcmp.obj: strcmp.S
        $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strcmp.obj `if test -f 'strcmp.S'; then $(CYGPATH_W) 'strcmp.S'; else $(CYGPATH_W) '$(srcdir)/strcmp.S'; fi`
 
+lib_a-strlen.o: strlen.S
+       $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strlen.o `test -f 'strlen.S' || echo '$(srcdir)/'`strlen.S
+
+lib_a-strlen.obj: strlen.S
+       $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strlen.obj `if test -f 'strlen.S'; then $(CYGPATH_W) 'strlen.S'; else $(CYGPATH_W) '$(srcdir)/strlen.S'; fi`
+
 lib_a-strncmp.o: strncmp.S
        $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CCASFLAGS) $(CCASFLAGS) -c -o lib_a-strncmp.o `test -f 'strncmp.S' || echo '$(srcdir)/'`strncmp.S
 
@@ -331,6 +338,12 @@ lib_a-strcmp-stub.o: 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`
 
+lib_a-strlen-stub.o: strlen-stub.c
+       $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strlen-stub.o `test -f 'strlen-stub.c' || echo '$(srcdir)/'`strlen-stub.c
+
+lib_a-strlen-stub.obj: strlen-stub.c
+       $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strlen-stub.obj `if test -f 'strlen-stub.c'; then $(CYGPATH_W) 'strlen-stub.c'; else $(CYGPATH_W) '$(srcdir)/strlen-stub.c'; fi`
+
 lib_a-strncmp-stub.o: strncmp-stub.c
        $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-strncmp-stub.o `test -f 'strncmp-stub.c' || echo '$(srcdir)/'`strncmp-stub.c
 
diff --git a/newlib/libc/machine/aarch64/strlen-stub.c b/newlib/libc/machine/aarch64/strlen-stub.c
new file mode 100644 (file)
index 0000000..717e209
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright (c) 2013, Linaro Limited
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the Linaro nor the
+         names of its contributors may be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "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 THE COPYRIGHT
+   HOLDER OR CONTRIBUTORS 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. */
+
+#if (defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED))
+# include "../../string/strlen.c"
+#else
+/* See strlen.S  */
+#endif
diff --git a/newlib/libc/machine/aarch64/strlen.S b/newlib/libc/machine/aarch64/strlen.S
new file mode 100644 (file)
index 0000000..36fde1f
--- /dev/null
@@ -0,0 +1,136 @@
+/* Copyright (c) 2013, Linaro Limited
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the Linaro nor the
+         names of its contributors may be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "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 THE COPYRIGHT
+   HOLDER OR CONTRIBUTORS 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. */
+
+#if (defined (__OPTIMIZE_SIZE__) || defined (PREFER_SIZE_OVER_SPEED))
+/* See strlen-stub.c  */
+#else
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64
+ */
+
+/* Arguments and results.  */
+#define srcin          x0
+#define len            x0
+
+/* Locals and temporaries.  */
+#define src            x1
+#define data1          x2
+#define data2          x3
+#define data2a         x4
+#define has_nul1       x5
+#define has_nul2       x6
+#define tmp1           x7
+#define tmp2           x8
+#define tmp3           x9
+#define tmp4           x10
+#define zeroones       x11
+#define pos            x12
+
+       .macro def_fn f p2align=0
+       .text
+       .p2align \p2align
+       .global \f
+       .type \f, %function
+\f:
+       .endm
+
+#define REP8_01 0x0101010101010101
+#define REP8_7f 0x7f7f7f7f7f7f7f7f
+#define REP8_80 0x8080808080808080
+
+       /* Start of critial section -- keep to one 64Byte cache line.  */
+def_fn strlen p2align=6
+       mov     zeroones, #REP8_01
+       bic     src, srcin, #15
+       ands    tmp1, srcin, #15
+       b.ne    .Lmisaligned
+       /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
+          (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
+          can be done in parallel across the entire word.  */
+       /* The inner loop deals with two Dwords at a time.  This has a
+          slightly higher start-up cost, but we should win quite quickly,
+          especially on cores with a high number of issue slots per
+          cycle, as we get much better parallelism out of the operations.  */
+.Lloop:
+       ldp     data1, data2, [src], #16
+.Lrealigned:
+       sub     tmp1, data1, zeroones
+       orr     tmp2, data1, #REP8_7f
+       sub     tmp3, data2, zeroones
+       orr     tmp4, data2, #REP8_7f
+       bic     has_nul1, tmp1, tmp2
+       bics    has_nul2, tmp3, tmp4
+       ccmp    has_nul1, #0, #0, eq    /* NZCV = 0000  */
+       b.eq    .Lloop
+       /* End of critical section -- keep to one 64Byte cache line.  */
+
+       sub     len, src, srcin
+       cbz     has_nul1, .Lnul_in_data2
+#ifdef __AARCH64EB__
+       mov     data2, data1
+#endif
+       sub     len, len, #8
+       mov     has_nul2, has_nul1
+.Lnul_in_data2:
+#ifdef __AARCH64EB__
+       /* For big-endian, carry propagation (if the final byte in the
+          string is 0x01) means we cannot use has_nul directly.  The
+          easiest way to get the correct byte is to byte-swap the data
+          and calculate the syndrome a second time.  */
+       rev     data2, data2
+       sub     tmp1, data2, zeroones
+       orr     tmp2, data2, #REP8_7f
+       bic     has_nul2, tmp1, tmp2
+#endif
+       sub     len, len, #8
+       rev     has_nul2, has_nul2
+       clz     pos, has_nul2
+       add     len, len, pos, lsr #3           /* Bits to bytes.  */
+       ret
+
+.Lmisaligned:
+       cmp     tmp1, #8
+       neg     tmp1, tmp1
+       ldp     data1, data2, [src], #16
+       lsl     tmp1, tmp1, #3          /* Bytes beyond alignment -> bits.  */
+       mov     tmp2, #~0
+#ifdef __AARCH64EB__
+       /* Big-endian.  Early bytes are at MSB.  */
+       lsl     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
+#else
+       /* Little-endian.  Early bytes are at LSB.  */
+       lsr     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
+#endif
+       orr     data1, data1, tmp2
+       orr     data2a, data2, tmp2
+       csinv   data1, data1, xzr, le
+       csel    data2, data2, data2a, le
+       b       .Lrealigned
+
+       .size   strlen, . - strlen
+#endif
This page took 0.059847 seconds and 5 git commands to generate.