[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/string/i386/Makefile b/ap/build/uClibc/libc/string/i386/Makefile
new file mode 100644
index 0000000..0a95346
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir:=../../../
+top_builddir:=../../../
+all: objs
+include $(top_builddir)Rules.mak
+include ../Makefile.in
+include $(top_srcdir)Makerules
diff --git a/ap/build/uClibc/libc/string/i386/memchr.c b/ap/build/uClibc/libc/string/i386/memchr.c
new file mode 100644
index 0000000..1960f6b
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/memchr.c
@@ -0,0 +1,75 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef memchr
+/*#define memchr TESTING*/
+void *memchr(const void *s, int c, size_t count)
+{
+ void *edi;
+ int ecx;
+ __asm__ __volatile__(
+ " jecxz 1f\n"
+ " repne; scasb\n"
+ " leal -1(%%edi), %%edi\n"
+ " je 2f\n"
+ "1:\n"
+ " xorl %%edi, %%edi\n" /* NULL */
+ "2:\n"
+ : "=&D" (edi), "=&c" (ecx)
+ : "a" (c), "0" (s), "1" (count)
+ /* : no clobbers */
+ );
+ return edi;
+}
+#ifndef memchr
+libc_hidden_def(memchr)
+#else
+/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os memchr.c -o memchr
+ * and run ./memchr
+ */
+int main()
+{
+ static const char str[] = "abc.def";
+ printf((char*)memchr(str, '.',-2) - str == 3 ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.',-1) - str == 3 ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 0) == NULL ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 1) == NULL ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 2) == NULL ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 3) == NULL ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 4) - str == 3 ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str, '.', 5) - str == 3 ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str+3, '.', 0) == NULL ? "ok\n" : "BAD!\n");
+ printf((char*)memchr(str+3, '.', 5) - str == 3 ? "ok\n" : "BAD!\n");
+}
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/memcpy.c b/ap/build/uClibc/libc/string/i386/memcpy.c
new file mode 100644
index 0000000..697d0bd
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/memcpy.c
@@ -0,0 +1,54 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef memcpy
+void *memcpy(void * to, const void * from, size_t n)
+{
+ int d0, d1, d2;
+ __asm__ __volatile__(
+ " rep; movsl\n"
+ " movl %4, %%ecx\n"
+ " andl $3, %%ecx\n"
+ /* jz is optional. avoids "rep; movsb" with ecx == 0,
+ * but adds a branch, which is currently (2008) faster */
+ " jz 1f\n"
+ " rep; movsb\n"
+ "1:\n"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from)
+ : "memory"
+ );
+ return to;
+}
+libc_hidden_def(memcpy)
diff --git a/ap/build/uClibc/libc/string/i386/memmove.c b/ap/build/uClibc/libc/string/i386/memmove.c
new file mode 100644
index 0000000..0ec8016
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/memmove.c
@@ -0,0 +1,71 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef memmove
+/*#define memmove TESTING*/
+void *memmove(void *dest, const void *src, size_t n)
+{
+ int eax, ecx, esi, edi;
+ __asm__ __volatile__(
+ " movl %%eax, %%edi\n"
+ " cmpl %%esi, %%eax\n"
+ " je 2f\n" /* (optional) src == dest -> NOP */
+ " jb 1f\n" /* src > dest -> simple copy */
+ " leal -1(%%esi,%%ecx), %%esi\n"
+ " leal -1(%%eax,%%ecx), %%edi\n"
+ " std\n"
+ "1: rep; movsb\n"
+ " cld\n"
+ "2:\n"
+ : "=&c" (ecx), "=&S" (esi), "=&a" (eax), "=&D" (edi)
+ : "0" (n), "1" (src), "2" (dest)
+ : "memory"
+ );
+ return (void*)eax;
+}
+#ifndef memmove
+libc_hidden_def(memmove)
+#else
+/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os memmove.c -o memmove
+ * and run ./memmove
+ */
+int main()
+{
+ static char str[] = "abcdef.123";
+ memmove(str + 1, str, 5);
+ printf(strcmp(str, "aabcde.123") == 0 ? "ok\n" : "BAD!\n");
+ memmove(str, str + 1, 5);
+ printf(strcmp(str, "abcdee.123") == 0 ? "ok\n" : "BAD!\n");
+}
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/memset.c b/ap/build/uClibc/libc/string/i386/memset.c
new file mode 100644
index 0000000..9f51f3c
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/memset.c
@@ -0,0 +1,95 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ *
+ * 2009-04: modified by Denys Vlasenko <vda.linux@googlemail.com>
+ * Fill byte-by-byte is a bit too slow. I prefer 46 byte function
+ * which fills x4 faster than 21 bytes one.
+ */
+
+#include <string.h>
+
+#undef memset
+void *memset(void *s, int c, size_t count)
+{
+ int reg, edi;
+ __asm__ __volatile__(
+
+ /* Most of the time, count is divisible by 4 and nonzero */
+ /* It's better to make this case faster */
+ /* " jecxz 9f\n" - (optional) count == 0: goto ret */
+ " mov %%ecx, %1\n"
+ " shr $2, %%ecx\n"
+ " jz 1f\n" /* zero words: goto fill_bytes */
+ /* extend 8-bit fill to 32 bits */
+ " movzx %%al, %%eax\n" /* 3 bytes */
+ /* or: " and $0xff, %%eax\n" - 5 bytes */
+ " imul $0x01010101, %%eax\n" /* 6 bytes */
+ /* fill full words */
+ " rep; stosl\n"
+ /* fill 0-3 bytes */
+ "1: and $3, %1\n"
+ " jz 9f\n" /* (count & 3) == 0: goto end */
+ "2: stosb\n"
+ " dec %1\n"
+ " jnz 2b\n"
+ /* end */
+ "9:\n"
+
+ : "=&D" (edi), "=&r" (reg)
+ : "0" (s), "a" (c), "c" (count)
+ : "memory"
+ );
+ return s;
+}
+libc_hidden_def(memset)
+
+/*
+gcc 4.3.1
+=========
+57 push %edi
+8b 7c 24 08 mov 0x8(%esp),%edi
+8b 4c 24 10 mov 0x10(%esp),%ecx
+8b 44 24 0c mov 0xc(%esp),%eax
+89 ca mov %ecx,%edx
+c1 e9 02 shr $0x2,%ecx
+74 0b je 1f <__GI_memset+0x1f>
+0f b6 c0 movzbl %al,%eax
+69 c0 01 01 01 01 imul $0x1010101,%eax,%eax
+f3 ab rep stos %eax,%es:(%edi)
+83 e2 03 and $0x3,%edx
+74 04 je 28 <__GI_memset+0x28>
+aa stos %al,%es:(%edi)
+4a dec %edx
+75 fc jne 24 <__GI_memset+0x24>
+8b 44 24 08 mov 0x8(%esp),%eax
+5f pop %edi
+c3 ret
+*/
diff --git a/ap/build/uClibc/libc/string/i386/rawmemchr.c b/ap/build/uClibc/libc/string/i386/rawmemchr.c
new file mode 100644
index 0000000..be0b142
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/rawmemchr.c
@@ -0,0 +1,24 @@
+/*
+ * Adapted from strlen.c code
+ *
+ * Copyright (C) 2008 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <string.h>
+
+#undef rawmemchr
+void *rawmemchr(const void *s, int c)
+{
+ void *eax;
+ int ecx, edi;
+ __asm__ __volatile__(
+ " repne; scasb\n"
+ " leal -1(%%edi), %%eax\n"
+ : "=&c" (ecx), "=&D" (edi), "=&a" (eax)
+ : "0" (0xffffffff), "1" (s), "2" (c)
+ );
+ return eax;
+}
+libc_hidden_def(rawmemchr)
diff --git a/ap/build/uClibc/libc/string/i386/strcat.c b/ap/build/uClibc/libc/string/i386/strcat.c
new file mode 100644
index 0000000..e71aad4
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strcat.c
@@ -0,0 +1,50 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+char *strcat(char * dest, const char * src)
+{
+ int d0, d1, d2, d3;
+ __asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "decl %1\n"
+ "1:\tlodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+ : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
+ return dest;
+}
+libc_hidden_def(strcat)
diff --git a/ap/build/uClibc/libc/string/i386/strchr.c b/ap/build/uClibc/libc/string/i386/strchr.c
new file mode 100644
index 0000000..93cc958
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strchr.c
@@ -0,0 +1,58 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strchr
+char *strchr(const char *s, int c)
+{
+ int esi;
+ register char * eax;
+ __asm__ __volatile__(
+ " movb %%al, %%ah\n"
+ "1: lodsb\n"
+ " cmpb %%ah, %%al\n"
+ " je 2f\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ " movl $1, %%esi\n" /* can use shorter xor + inc */
+ "2: leal -1(%%esi), %%eax\n"
+ : "=a" (eax), "=&S" (esi)
+ : "0" (c), "1" (s)
+ /* no clobbers */
+ );
+ return eax;
+}
+libc_hidden_def(strchr)
+#ifdef __UCLIBC_SUSV3_LEGACY__
+strong_alias(strchr,index)
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strchrnul.c b/ap/build/uClibc/libc/string/i386/strchrnul.c
new file mode 100644
index 0000000..d484272
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strchrnul.c
@@ -0,0 +1,47 @@
+/*
+ * Adapted from strchr.c code
+ *
+ * Copyright (C) 2008 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <string.h>
+
+#undef strchrnul
+/*#define strchrnul TESTING*/
+char *strchrnul(const char *s, int c)
+{
+ int esi;
+ char *eax;
+ __asm__ __volatile__(
+ " movb %%al, %%ah\n"
+ "1: lodsb\n"
+ " cmpb %%ah, %%al\n"
+ " je 2f\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ /* with this, we'd get strchr(): */
+ /* " movl $1, %%esi\n" */
+ "2: leal -1(%%esi), %%eax\n"
+ : "=a" (eax), "=&S" (esi)
+ : "0" (c), "1" (s)
+ /* no clobbers */
+ );
+ return eax;
+}
+#ifndef strchrnul
+libc_hidden_def(strchrnul)
+#else
+/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strchrnul.c -o strchrnul
+ * and run ./strchrnul
+ */
+int main()
+{
+ static const char str[] = "abc.def";
+ printf((char*)strchrnul(str, '.') - str == 3 ? "ok\n" : "BAD!\n");
+ printf((char*)strchrnul(str, '*') - str == 7 ? "ok\n" : "BAD!\n");
+ printf((char*)strchrnul(str, 0) - str == 7 ? "ok\n" : "BAD!\n");
+ printf((char*)strchrnul(str+3, '.') - str == 3 ? "ok\n" : "BAD!\n");
+}
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strcmp.c b/ap/build/uClibc/libc/string/i386/strcmp.c
new file mode 100644
index 0000000..9621f66
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strcmp.c
@@ -0,0 +1,59 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+int strcmp(const char *cs, const char *ct)
+{
+ int d0, d1;
+ register int __res;
+ __asm__ __volatile__(
+ "1:\tlodsb\n\t"
+ "scasb\n\t"
+ "jne 2f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n\t"
+ "jmp 3f\n"
+ "2:\tsbbl %%eax,%%eax\n\t"
+ "orb $1,%%al\n"
+ "3:"
+ :"=a" (__res), "=&S" (d0), "=&D" (d1)
+ :"1" (cs),"2" (ct));
+ return __res;
+}
+libc_hidden_def(strcmp)
+
+#ifndef __UCLIBC_HAS_LOCALE__
+strong_alias(strcmp,strcoll)
+libc_hidden_def(strcoll)
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strcpy.c b/ap/build/uClibc/libc/string/i386/strcpy.c
new file mode 100644
index 0000000..fff1bd0
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strcpy.c
@@ -0,0 +1,48 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strcpy
+char *strcpy(char * dest, const char * src)
+{
+ int d0, d1, d2;
+ __asm__ __volatile__(
+ "1:\tlodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2)
+ :"0" (src),"1" (dest) : "memory");
+ return dest;
+}
+libc_hidden_def(strcpy)
diff --git a/ap/build/uClibc/libc/string/i386/string.h b/ap/build/uClibc/libc/string/i386/string.h
new file mode 100644
index 0000000..cf4333d
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/string.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2008 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball
+ */
+
+#if !defined _STRING_H
+#error "Never use <libc-string_i386.h> directly; include <string.h> instead"
+#endif
+
+#ifndef _LIBC_STRING_i386_H
+#define _LIBC_STRING_i386_H 1
+
+static __always_inline
+void *inlined_memset_const_c_count4(void *s, unsigned eax, unsigned count)
+{
+ int ecx, edi;
+
+ if (count == 0)
+ return s;
+
+ /* Very small (2 stores or less) are best done with direct
+ * mov <const>,<mem> instructions (they do not clobber registers) */
+ if (count == 1) {
+ *(char *)(s + 0) = eax;
+ return s;
+ }
+
+ /* You wonder why & 0xff is needed? Try memset(p, '\xff', size).
+ * If char is signed, '\xff' == -1! */
+ eax = (eax & 0xff) * 0x01010101; /* done at compile time */
+
+ if (count == 2) {
+ *(short *)(s + 0) = eax;
+ return s;
+ }
+ if (count == 3) {
+ *(short *)(s + 0) = eax;
+ *(char *) (s + 2) = eax;
+ return s;
+ }
+ if (count == 1*4 + 0) {
+ *(int *)(s + 0) = eax;
+ return s;
+ }
+ if (count == 1*4 + 1) {
+ *(int *) (s + 0) = eax;
+ *(char *)(s + 4) = eax;
+ return s;
+ }
+ if (count == 1*4 + 2) {
+ *(int *) (s + 0) = eax;
+ *(short *)(s + 4) = eax;
+ return s;
+ }
+
+ /* Small string stores: don't clobber ecx
+ * (clobbers only eax and edi) */
+#define small_store(arg) { \
+ __asm__ __volatile__( \
+ arg \
+ : "=&D" (edi) \
+ : "a" (eax), "0" (s) \
+ : "memory" \
+ ); \
+ return s; \
+}
+ if (count == 1*4 + 3) small_store("stosl; stosw; stosb");
+ if (count == 2*4 + 0) {
+ ((int *)s)[0] = eax;
+ ((int *)s)[1] = eax;
+ return s;
+ }
+ if (count == 2*4 + 1) small_store("stosl; stosl; stosb");
+ if (count == 2*4 + 2) small_store("stosl; stosl; stosw");
+ if (count == 2*4 + 3) small_store("stosl; stosl; stosw; stosb");
+ if (count == 3*4 + 0) small_store("stosl; stosl; stosl");
+ if (count == 3*4 + 1) small_store("stosl; stosl; stosl; stosb");
+ if (count == 3*4 + 2) small_store("stosl; stosl; stosl; stosw");
+ if (count == 3*4 + 3) small_store("stosl; stosl; stosl; stosw; stosb");
+ if (count == 4*4 + 0) small_store("stosl; stosl; stosl; stosl");
+ if (count == 4*4 + 1) small_store("stosl; stosl; stosl; stosl; stosb");
+ /* going over 7 bytes is suboptimal */
+ /* stosw is 2-byte insn, so this one takes 6 bytes: */
+ if (count == 4*4 + 2) small_store("stosl; stosl; stosl; stosl; stosw");
+ /* 7 bytes */
+ if (count == 4*4 + 3) small_store("stosl; stosl; stosl; stosl; stosw; stosb");
+ /* 5 bytes */
+ if (count == 5*4 + 0) small_store("stosl; stosl; stosl; stosl; stosl");
+ /* 6 bytes */
+ if (count == 5*4 + 1) small_store("stosl; stosl; stosl; stosl; stosl; stosb");
+ /* 7 bytes */
+ if (count == 5*4 + 2) small_store("stosl; stosl; stosl; stosl; stosl; stosw");
+ /* 8 bytes, but oh well... */
+ if (count == 5*4 + 3) small_store("stosl; stosl; stosl; stosl; stosl; stosw; stosb");
+ /* 6 bytes */
+ if (count == 6*4 + 0) small_store("stosl; stosl; stosl; stosl; stosl; stosl");
+ /* the rest would be 7+ bytes and is handled below instead */
+#undef small_store
+
+ /* Not small, but multiple-of-4 store.
+ * "mov <const>,%ecx; rep; stosl" sequence is 7 bytes */
+ __asm__ __volatile__(
+ " rep; stosl\n"
+ : "=&c" (ecx), "=&D" (edi)
+ : "a" (eax), "0" (count / 4), "1" (s)
+ : "memory"
+ );
+ return s;
+}
+#if 1 /* -51 bytes on shared i386 build with gcc 4.3.0 */
+#define memset(s, c, count) ( \
+ ( !(__builtin_constant_p(c) && __builtin_constant_p(count)) \
+ || ((count) > (6*4 + 0) && ((count) % 4) != 0) \
+ ) \
+ ? memset((s), (c), (count)) \
+ : inlined_memset_const_c_count4((s), (c), (count)) \
+ )
+#endif
+
+
+static __always_inline
+void *inlined_mempcpy_const_count4(void *d, const void *s, unsigned count)
+{
+ int ecx;
+ char *esi, *edi;
+
+ if (count == 0)
+ return d;
+
+ if (count == 1) {
+ *(char *)d = *(char *)s;
+ return d + 1;
+ }
+ if (count == 2) {
+ *(short *)d = *(short *)s;
+ return d + 2;
+ }
+ /* Small string moves: don't clobber ecx
+ * (clobbers only esi and edi) */
+#define small_move(arg) { \
+ __asm__ __volatile__( \
+ arg \
+ : "=&S" (esi), "=&D" (edi) \
+ : "0" (s), "1" (d) \
+ : "memory" \
+ ); \
+ return edi; \
+}
+ if (count == 3) small_move("movsw; movsb");
+ if (count == 1*4 + 0) {
+ *(int *)d = *(int *)s;
+ return d + 4;
+ }
+ if (count == 1*4 + 1) small_move("movsl; movsb");
+ if (count == 1*4 + 2) small_move("movsl; movsw");
+ if (count == 1*4 + 3) small_move("movsl; movsw; movsb");
+ if (count == 2*4 + 0) small_move("movsl; movsl");
+ if (count == 2*4 + 1) small_move("movsl; movsl; movsb");
+ if (count == 2*4 + 2) small_move("movsl; movsl; movsw");
+ if (count == 2*4 + 3) small_move("movsl; movsl; movsw; movsb");
+ if (count == 3*4 + 0) small_move("movsl; movsl; movsl");
+ if (count == 3*4 + 1) small_move("movsl; movsl; movsl; movsb");
+ if (count == 3*4 + 2) small_move("movsl; movsl; movsl; movsw");
+ if (count == 3*4 + 3) small_move("movsl; movsl; movsl; movsw; movsb");
+ if (count == 4*4 + 0) small_move("movsl; movsl; movsl; movsl");
+ if (count == 4*4 + 1) small_move("movsl; movsl; movsl; movsl; movsb");
+ /* going over 7 bytes is suboptimal */
+ /* movsw is 2-byte insn, so this one takes 6 bytes: */
+ if (count == 4*4 + 2) small_move("movsl; movsl; movsl; movsl; movsw");
+ /* 7 bytes */
+ if (count == 4*4 + 3) small_move("movsl; movsl; movsl; movsl; movsw; movsb");
+ /* 5 bytes */
+ if (count == 5*4 + 0) small_move("movsl; movsl; movsl; movsl; movsl");
+ /* 6 bytes */
+ if (count == 5*4 + 1) small_move("movsl; movsl; movsl; movsl; movsl; movsb");
+ /* 7 bytes */
+ if (count == 5*4 + 2) small_move("movsl; movsl; movsl; movsl; movsl; movsw");
+ /* 8 bytes, but oh well... */
+ if (count == 5*4 + 3) small_move("movsl; movsl; movsl; movsl; movsl; movsw; movsb");
+ /* 6 bytes */
+ if (count == 6*4 + 0) small_move("movsl; movsl; movsl; movsl; movsl; movsl");
+ /* the rest would be 7+ bytes and is handled below instead */
+#undef small_move
+
+ /* Not small, but multiple-of-4 move.
+ * "mov <const>,%ecx; rep; movsl" sequence is 7 bytes */
+ __asm__ __volatile__(
+ " rep; movsl\n"
+ : "=&c" (ecx), "=&S" (esi), "=&D" (edi)
+ : "0" (count / 4), "1" (s), "2" (d)
+ : "memory"
+ );
+ return edi;
+}
+static __always_inline
+void *inlined_memcpy_const_count4(void *d, const void *s, unsigned count)
+{
+ inlined_mempcpy_const_count4(d, s, count);
+ return d;
+}
+#if 1 /* +34 bytes on shared i386 build with gcc 4.3.0 */
+#define mempcpy(d, s, count) ( \
+ ( !(__builtin_constant_p(count)) \
+ || ((count) > (6*4 + 0) && ((count) % 4) != 0) \
+ ) \
+ ? mempcpy((d), (s), (count)) \
+ : inlined_mempcpy_const_count4((d), (s), (count)) \
+ )
+#define memcpy(d, s, count) ( \
+ ( !(__builtin_constant_p(count)) \
+ || ((count) > (6*4 + 0) && ((count) % 4) != 0) \
+ ) \
+ ? memcpy((d), (s), (count)) \
+ : inlined_memcpy_const_count4((d), (s), (count)) \
+ )
+#endif
+
+
+static __always_inline
+size_t inlined_strlen(const char *s)
+{
+ int edi;
+ int ecx;
+ __asm__ __volatile__(
+ " repne; scasb\n"
+ /* " notl %0\n" */
+ /* " decl %0\n" */
+ : "=c" (ecx), "=&D" (edi)
+ : "1" (s), "a" (0), "0" (0xffffffffu)
+ /* : no clobbers */
+ );
+ return -ecx - 1;
+}
+#if 0 /* +1108 bytes on shared i386 build with gcc 4.3.0 */
+#define strlen(s) inlined_strlen(s)
+#endif
+
+
+static __always_inline
+char *inlined_stpcpy(char *dest, const char *src)
+{
+ char *esi, *edi;
+ int eax;
+ __asm__ __volatile__(
+ "1: lodsb\n"
+ " stosb\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ : "=&S" (esi), "=&D" (edi), "=&a" (eax)
+ : "0" (src), "1" (dest)
+ : "memory"
+ );
+ return edi - 1;
+}
+static __always_inline
+char *inlined_strcpy(char *dest, const char *src)
+{
+ inlined_stpcpy(dest, src);
+ return dest;
+}
+#if 0 /* +562 bytes on shared i386 build with gcc 4.3.0 */
+#define stpcpy(dest, src) inlined_stpcpy(dest, src)
+#define strcpy(dest, src) inlined_strcpy(dest, src)
+#endif
+
+
+static __always_inline
+void *inlined_memchr(const void *s, int c, size_t count)
+{
+ void *edi;
+ int ecx;
+ /* Unfortunately, c gets loaded to %eax (wide insn), not %al */
+ __asm__ __volatile__(
+ " jecxz 1f\n"
+ " repne; scasb\n"
+ " leal -1(%%edi), %%edi\n"
+ " je 2f\n"
+ "1:\n"
+ " xorl %%edi, %%edi\n"
+ "2:\n"
+ : "=&D" (edi), "=&c" (ecx)
+ : "a" (c), "0" (s), "1" (count)
+ /* : no clobbers */
+ );
+ return edi;
+}
+static __always_inline
+void *inlined_memchr_const_c(const void *s, int c, size_t count)
+{
+#if defined __OPTIMIZE__
+ void *edi;
+ int ecx, eax;
+ __asm__ __volatile__(
+ " jecxz 1f\n"
+ " movb %4, %%al\n" /* const c to %%al */
+ " repne; scasb\n"
+ " leal -1(%%edi), %%edi\n"
+ " je 2f\n"
+ "1:\n"
+ " xorl %%edi, %%edi\n"
+ "2:\n"
+ : "=&D" (edi), "=&c" (ecx), "=&a" (eax)
+ : "0" (s), "i" (c), "1" (count)
+ /* : no clobbers */
+ );
+ return edi;
+#else
+ /* With -O0, gcc can't figure out how to encode CONST c
+ * as an immediate operand. Generating slightly bigger code
+ * (usually "movl CONST,%eax", 3 bytes bigger than needed):
+ */
+ void *edi;
+ int ecx, eax;
+ __asm__ __volatile__(
+ " jecxz 1f\n"
+ " repne; scasb\n"
+ " leal -1(%%edi), %%edi\n"
+ " je 2f\n"
+ "1:\n"
+ " xorl %%edi, %%edi\n"
+ "2:\n"
+ : "=&D" (edi), "=&c" (ecx), "=&a" (eax)
+ : "0" (s), "2" (c), "1" (count)
+ /* : no clobbers */
+ );
+ return edi;
+#endif
+}
+#if 1 /* +2 bytes on shared i386 build with gcc 4.3.0 */
+#define memchr(s, c, count) ( \
+ __builtin_constant_p(c) \
+ ? inlined_memchr_const_c(s, (c) & 0xff, count) \
+ : inlined_memchr(s, c, count) \
+ )
+#endif
+
+#endif /* _LIBC_STRING_i386_H */
diff --git a/ap/build/uClibc/libc/string/i386/strlen.c b/ap/build/uClibc/libc/string/i386/strlen.c
new file mode 100644
index 0000000..ff2baeb
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strlen.c
@@ -0,0 +1,48 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strlen
+size_t strlen(const char *s)
+{
+ int eax, ecx, edi;
+ __asm__ __volatile__(
+ " repne; scasb\n"
+ " notl %%ecx\n"
+ " leal -1(%%ecx), %%eax\n"
+ : "=&c" (ecx), "=&D" (edi), "=&a" (eax)
+ : "0" (0xffffffff), "1" (s), "2" (0)
+ );
+ return eax;
+}
+libc_hidden_def(strlen)
diff --git a/ap/build/uClibc/libc/string/i386/strncat.c b/ap/build/uClibc/libc/string/i386/strncat.c
new file mode 100644
index 0000000..12f0a30
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strncat.c
@@ -0,0 +1,86 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strncat
+/*#define strncat TESTING*/
+char *strncat(char * dest, const char * src, size_t count)
+{
+ int esi, edi, eax, ecx, edx;
+ __asm__ __volatile__(
+ " xorl %%eax, %%eax\n"
+ " incl %%edx\n"
+ " pushl %%edi\n" /* save dest */
+ " repne; scasb\n"
+ " decl %%edi\n" /* edi => NUL in dest */
+ /* count-- */
+ "1: decl %%edx\n"
+ /* if count reached 0, store NUL and bail out */
+ " movl %%edx, %%eax\n"
+ " jz 2f\n"
+ /* else copy a char */
+ " lodsb\n"
+ "2: stosb\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ /* end of loop */
+ " popl %%eax\n" /* restore dest into eax */
+ : "=&S" (esi), "=&D" (edi), "=&a" (eax), "=&c" (ecx), "=&d" (edx)
+ : "0" (src), "1" (dest), "3" (0xffffffff), "4" (count)
+ : "memory"
+ );
+ return (char *)eax;
+}
+#ifndef strncat
+libc_hidden_def(strncat)
+#else
+/* Uncomment TESTING, gcc -m32 -Os strncat.c -o strncat
+ * and run ./strncat
+ */
+int main()
+{
+ char buf[99];
+
+ strcpy(buf, "abc"); buf[4] = '*'; strncat(buf, "def", 0);
+ printf(strcmp(buf, "abc") == 0 && buf[4] == '*' ? "ok\n" : "BAD!\n");
+
+ strcpy(buf, "abc"); buf[6] = 1; buf[7] = '*'; strncat(buf, "def", 50);
+ printf(strcmp(buf, "abcdef") == 0 && buf[7] == '*' ? "ok\n" : "BAD!\n");
+
+ strcpy(buf, "abc"); buf[6] = 1; buf[7] = '*'; strncat(buf, "def", -1);
+ printf(strcmp(buf, "abcdef") == 0 && buf[7] == '*' ? "ok\n" : "BAD!\n");
+
+ strcpy(buf, "abc"); buf[6] = 1; buf[7] = '*'; strncat(buf, "def123", 3);
+ printf(strcmp(buf, "abcdef") == 0 && buf[7] == '*' ? "ok\n" : "BAD!\n");
+}
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strncmp.c b/ap/build/uClibc/libc/string/i386/strncmp.c
new file mode 100644
index 0000000..bfb20c3
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strncmp.c
@@ -0,0 +1,59 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strncmp
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+ int eax;
+ int esi, edi, ecx;
+ __asm__ __volatile__(
+ " incl %%ecx\n"
+ "1: decl %%ecx\n"
+ " jz 2f\n"
+ " lodsb\n"
+ " scasb\n"
+ " jne 3f\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ "2: xorl %%eax, %%eax\n"
+ " jmp 4f\n"
+ "3: sbbl %%eax, %%eax\n"
+ " orb $1, %%al\n"
+ "4:\n"
+ : "=a" (eax), "=&S" (esi), "=&D" (edi), "=&c" (ecx)
+ : "1" (cs), "2" (ct), "3" (count)
+ );
+ return eax;
+}
+libc_hidden_weak(strncmp)
diff --git a/ap/build/uClibc/libc/string/i386/strncpy.c b/ap/build/uClibc/libc/string/i386/strncpy.c
new file mode 100644
index 0000000..99d104b
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strncpy.c
@@ -0,0 +1,75 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#undef strncpy
+/*#define strncpy TESTING*/
+char *strncpy(char * dest, const char * src, size_t count)
+{
+ int esi, edi, ecx, eax;
+ __asm__ __volatile__(
+ "1: subl $1, %%ecx\n" /* not dec! it doesnt set CF */
+ " jc 2f\n"
+ " lodsb\n"
+ " stosb\n"
+ " testb %%al, %%al\n"
+ " jnz 1b\n"
+ " rep; stosb\n"
+ "2:\n"
+ : "=&S" (esi), "=&D" (edi), "=&c" (ecx), "=&a" (eax)
+ : "0" (src), "1" (dest), "2" (count)
+ : "memory"
+ );
+ return dest;
+}
+#ifndef strncpy
+libc_hidden_def(strncpy)
+#else
+/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strncpy.c -o strncpy
+ * and run ./strncpy
+ */
+int main()
+{
+ static char str[99];
+
+ str[3] = '*'; str[4] = 0; strncpy(str, "abc", 3);
+ printf(strcmp(str, "abc*") == 0 ? "ok\n" : "BAD!\n");
+
+ str[4] = '*'; str[5] = '+'; strncpy(str, "abc", 5);
+ printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ?
+ "ok\n" : "BAD!\n");
+ strncpy(str, "def", 0); /* should do nothing */
+ printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ?
+ "ok\n" : "BAD!\n");
+}
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strnlen.c b/ap/build/uClibc/libc/string/i386/strnlen.c
new file mode 100644
index 0000000..f58f698
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strnlen.c
@@ -0,0 +1,75 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+#ifdef __USE_GNU
+
+#undef strnlen
+/*#define strnlen TESTING*/
+size_t strnlen(const char *s, size_t count)
+{
+ int edx;
+ int eax;
+ __asm__ __volatile__(
+ " leal -1(%%ecx), %%eax\n"
+ "1: incl %%eax\n"
+ " decl %%edx\n"
+ " jz 3f\n"
+ " cmpb $0, (%%eax)\n"
+ " jnz 1b\n"
+ "3: subl %%ecx, %%eax"
+ : "=a" (eax), "=&d" (edx)
+ : "c" (s), "1" (count + 1)
+ );
+ return eax;
+}
+#ifndef strnlen
+libc_hidden_def(strnlen)
+#else
+/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strnlen.c -o strnlen
+ * and run ./strnlen
+ */
+int main()
+{
+ printf(strnlen("abc\0def", -2) == 3 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", -1) == 3 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 0) == 0 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 1) == 1 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 2) == 2 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 3) == 3 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 4) == 3 ? "ok\n" : "BAD!\n");
+ printf(strnlen("abc\0def", 5) == 3 ? "ok\n" : "BAD!\n");
+}
+#endif
+
+#endif
diff --git a/ap/build/uClibc/libc/string/i386/strrchr.c b/ap/build/uClibc/libc/string/i386/strrchr.c
new file mode 100644
index 0000000..5c349f6
--- /dev/null
+++ b/ap/build/uClibc/libc/string/i386/strrchr.c
@@ -0,0 +1,58 @@
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ * Modified for uClibc by Erik Andersen <andersen@codepoet.org>
+ * These make no attempt to use nifty things like mmx/3dnow/etc.
+ * These are not inline, and will therefore not be as fast as
+ * modifying the headers to use inlines (and cannot therefore
+ * do tricky things when dealing with const memory). But they
+ * should (I hope!) be faster than their generic equivalents....
+ *
+ * More importantly, these should provide a good example for
+ * others to follow when adding arch specific optimizations.
+ * -Erik
+ */
+
+#include <string.h>
+
+char *strrchr(const char *s, int c)
+{
+ char *eax;
+
+ __asm__ __volatile__(
+ " movb %%cl, %%ch\n"
+ "1: movb (%1), %%cl\n" /* load char */
+ " cmpb %%cl, %%ch\n" /* char == c? */
+ " jne 2f\n"
+ " movl %1, %%eax\n"
+ "2: incl %1\n"
+ " testb %%cl, %%cl\n" /* char == NUL? */
+ " jnz 1b\n"
+ /* "=c": use ecx, not ebx (-fpic uses it). */
+ : "=a" (eax), "=r" (s), "=c" (c)
+ : "0" (0), "1" (s), "2" (c)
+ /* : no clobbers */
+ );
+ return eax;
+}
+libc_hidden_def(strrchr)
+#ifdef __UCLIBC_SUSV3_LEGACY__
+strong_alias(strrchr,rindex)
+#endif