summaryrefslogtreecommitdiff
path: root/libc/sysdeps/i386/i686
diff options
context:
space:
mode:
authorgcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2006-08-17 01:18:26 +0000
committergcc <gcc@7b3dc134-2b1b-0410-93df-9e9f96275f8d>2006-08-17 01:18:26 +0000
commit15f34685e7a9b5caf761af2ebf6afa20438d440b (patch)
treedc04ce3cdf040f198743c15b64557824de174680 /libc/sysdeps/i386/i686
parent1e848e0e775a36f6359161f5deb890942ef42ff3 (diff)
downloadeglibc2-15f34685e7a9b5caf761af2ebf6afa20438d440b.tar.gz
Import glibc-mainline for 2006-08-16
git-svn-id: svn://svn.eglibc.org/fsf/trunk@4 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/i386/i686')
-rw-r--r--libc/sysdeps/i386/i686/Implies4
-rw-r--r--libc/sysdeps/i386/i686/Makefile7
-rw-r--r--libc/sysdeps/i386/i686/add_n.S122
-rw-r--r--libc/sysdeps/i386/i686/bzero.S3
-rw-r--r--libc/sysdeps/i386/i686/dl-hash.h79
-rw-r--r--libc/sysdeps/i386/i686/ffs.c49
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdim.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdimf.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fdiml.S44
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmax.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmaxf.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmaxl.S40
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fmin.S38
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fminf.S38
-rw-r--r--libc/sysdeps/i386/i686/fpu/s_fminl.S38
-rw-r--r--libc/sysdeps/i386/i686/hp-timing.c24
-rw-r--r--libc/sysdeps/i386/i686/hp-timing.h157
-rw-r--r--libc/sysdeps/i386/i686/memcmp.S423
-rw-r--r--libc/sysdeps/i386/i686/memcpy.S69
-rw-r--r--libc/sysdeps/i386/i686/memcpy_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memmove.S115
-rw-r--r--libc/sysdeps/i386/i686/memmove_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/mempcpy.S73
-rw-r--r--libc/sysdeps/i386/i686/mempcpy_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memset.S113
-rw-r--r--libc/sysdeps/i386/i686/memset_chk.S35
-rw-r--r--libc/sysdeps/i386/i686/memusage.h22
-rw-r--r--libc/sysdeps/i386/i686/strcmp.S72
-rw-r--r--libc/sysdeps/i386/i686/strtok.S281
-rw-r--r--libc/sysdeps/i386/i686/strtok_r.S5
-rw-r--r--libc/sysdeps/i386/i686/tst-stack-align.h45
31 files changed, 2169 insertions, 0 deletions
diff --git a/libc/sysdeps/i386/i686/Implies b/libc/sysdeps/i386/i686/Implies
new file mode 100644
index 000000000..e1fcccd5f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/Implies
@@ -0,0 +1,4 @@
+# Due to the reordering and the other nifty extensions in the i686 it is
+# not really good to use heavily i586 optimized code on a i686. It's
+# better to use i486/i386 code.
+i386/i486
diff --git a/libc/sysdeps/i386/i686/Makefile b/libc/sysdeps/i386/i686/Makefile
new file mode 100644
index 000000000..c7378ab21
--- /dev/null
+++ b/libc/sysdeps/i386/i686/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
+
+# So that we can test __m128's alignment
+stack-align-test-flags += -msse
diff --git a/libc/sysdeps/i386/i686/add_n.S b/libc/sysdeps/i386/i686/add_n.S
new file mode 100644
index 000000000..3cce33acf
--- /dev/null
+++ b/libc/sysdeps/i386/i686/add_n.S
@@ -0,0 +1,122 @@
+/* Add two limb vectors of the same length > 0 and store sum in a third
+ limb vector.
+ Copyright (C) 1992,94,95,97,98,2000,2005 Free Software Foundation, Inc.
+ This file is part of the GNU MP Library.
+
+ The GNU MP Library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ The GNU MP Library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+8 /* space for 2 saved regs */
+#define RES PARMS
+#define S1 RES+PTR_SIZE
+#define S2 S1+PTR_SIZE
+#define SIZE S2+PTR_SIZE
+
+ .text
+#ifdef PIC
+L(1): addl (%esp), %eax
+ ret
+#endif
+ENTRY (BP_SYM (__mpn_add_n))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+
+ movl RES(%esp),%edi
+ cfi_rel_offset (edi, 4)
+ movl S1(%esp),%esi
+ cfi_rel_offset (esi, 0)
+ movl S2(%esp),%edx
+ movl SIZE(%esp),%ecx
+#if __BOUNDED_POINTERS__
+ shll $2, %ecx /* convert limbs to bytes */
+ CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, S1(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%edx, S2(%esp), %ecx)
+ shrl $2, %ecx
+#endif
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz L(oop) /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. */
+ leal (L(oop)-L(0)-3)(%eax,%eax,8),%eax
+ call L(1)
+L(0):
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (L(oop) - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+L(oop): movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz L(oop)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ ret
+END (BP_SYM (__mpn_add_n))
diff --git a/libc/sysdeps/i386/i686/bzero.S b/libc/sysdeps/i386/i686/bzero.S
new file mode 100644
index 000000000..c1e4a6d50
--- /dev/null
+++ b/libc/sysdeps/i386/i686/bzero.S
@@ -0,0 +1,3 @@
+#define memset __bzero
+#include <sysdeps/i386/i686/memset.S>
+weak_alias (BP_SYM (__bzero), BP_SYM (bzero))
diff --git a/libc/sysdeps/i386/i686/dl-hash.h b/libc/sysdeps/i386/i686/dl-hash.h
new file mode 100644
index 000000000..4bdd998aa
--- /dev/null
+++ b/libc/sysdeps/i386/i686/dl-hash.h
@@ -0,0 +1,79 @@
+/* Compute hash alue for given string according to ELF standard.
+ Copyright (C) 1998, 2003, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _DL_HASH_H
+#define _DL_HASH_H 1
+
+
+/* This is the hashing function specified by the ELF ABI. It is highly
+ optimized for the PII processors. Though it will run on i586 it
+ would be much slower than the generic C implementation. So don't
+ use it. */
+static unsigned int
+_dl_elf_hash (const char *name)
+{
+ unsigned int result;
+ unsigned int temp0;
+ unsigned int temp1;
+
+ __asm__ __volatile__
+ ("movzbl (%1),%2\n\t"
+ "testl %2, %2\n\t"
+ "jz 1f\n\t"
+ "movl %2, %0\n\t"
+ "movzbl 1(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 2(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 3(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl %2, %0\n\t"
+ "movzbl 4(%1), %2\n\t"
+ "jecxz 1f\n\t"
+ "shll $4, %0\n\t"
+ "addl $5, %1\n\t"
+ "addl %2, %0\n\t"
+ "movzbl (%1), %2\n\t"
+ "jecxz 1f\n"
+ "2:\t"
+ "shll $4, %0\n\t"
+ "movl $0xf0000000, %3\n\t"
+ "incl %1\n\t"
+ "addl %2, %0\n\t"
+ "andl %0, %3\n\t"
+ "andl $0x0fffffff, %0\n\t"
+ "shrl $24, %3\n\t"
+ "movzbl (%1), %2\n\t"
+ "xorl %3, %0\n\t"
+ "testl %2, %2\n\t"
+ "jnz 2b\n"
+ "1:\t"
+ : "=&r" (result), "=r" (name), "=&c" (temp0), "=&r" (temp1)
+ : "0" (0), "1" ((const unsigned char *) name));
+
+ return result;
+}
+
+#endif /* dl-hash.h */
diff --git a/libc/sysdeps/i386/i686/ffs.c b/libc/sysdeps/i386/i686/ffs.c
new file mode 100644
index 000000000..684ae2182
--- /dev/null
+++ b/libc/sysdeps/i386/i686/ffs.c
@@ -0,0 +1,49 @@
+/* ffs -- find first set bit in a word, counted from least significant end.
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1991, 92, 93, 94, 97, 98, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define ffsl __something_else
+#include <string.h>
+
+#undef ffs
+
+#ifdef __GNUC__
+
+int
+__ffs (x)
+ int x;
+{
+ int cnt;
+ int tmp;
+
+ asm ("bsfl %2,%0\n" /* Count low bits in X and store in %1. */
+ "cmovel %1,%0\n" /* If number was zero, use -1 as result. */
+ : "=&r" (cnt), "=r" (tmp) : "rm" (x), "1" (-1));
+
+ return cnt + 1;
+}
+weak_alias (__ffs, ffs)
+libc_hidden_builtin_def (ffs)
+#undef ffsl
+weak_alias (__ffs, ffsl)
+
+#else
+#include <string/ffs.c>
+#endif
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdim.S b/libc/sysdeps/i386/i686/fpu/s_fdim.S
new file mode 100644
index 000000000..30ecff4e7
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdim.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdim)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdim)
+weak_alias (__fdim, fdim)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdimf.S b/libc/sysdeps/i386/i686/fpu/s_fdimf.S
new file mode 100644
index 000000000..888df14b6
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdimf.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdimf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdimf)
+weak_alias (__fdimf, fdimf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fdiml.S b/libc/sysdeps/i386/i686/fpu/s_fdiml.S
new file mode 100644
index 000000000..cb0e26e36
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fdiml.S
@@ -0,0 +1,44 @@
+/* Compute positive difference.
+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fdiml)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(1), %st
+ jp 1f
+
+ jc 3f
+ fstp %st(1)
+ fldz
+ jmp 2f
+
+3: fsubrp %st, %st(1)
+ ret
+
+1: fucomi %st(0), %st
+ fcmovnu %st(1), %st
+2: fstp %st(1)
+ ret
+END(__fdiml)
+weak_alias (__fdiml, fdiml)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmax.S b/libc/sysdeps/i386/i686/fpu/s_fmax.S
new file mode 100644
index 000000000..b28226987
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmax.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmax)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmax)
+weak_alias (__fmax, fmax)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmaxf.S b/libc/sysdeps/i386/i686/fpu/s_fmaxf.S
new file mode 100644
index 000000000..fbf3e5bff
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmaxf.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmaxf)
+weak_alias (__fmaxf, fmaxf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmaxl.S b/libc/sysdeps/i386/i686/fpu/s_fmaxl.S
new file mode 100644
index 000000000..229febf52
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmaxl.S
@@ -0,0 +1,40 @@
+/* Compute maximum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmaxl)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fxch
+
+ fucomi %st(1), %st
+ fcmovb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmaxl)
+weak_alias (__fmaxl, fmaxl)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fmin.S b/libc/sysdeps/i386/i686/fpu/s_fmin.S
new file mode 100644
index 000000000..d821cda2f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fmin.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fmin)
+ fldl 4(%esp) // x
+ fldl 12(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fmin)
+weak_alias (__fmin, fmin)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fminf.S b/libc/sysdeps/i386/i686/fpu/s_fminf.S
new file mode 100644
index 000000000..8ef12035e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fminf.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminf)
+ flds 4(%esp) // x
+ flds 8(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fminf)
+weak_alias (__fminf, fminf)
diff --git a/libc/sysdeps/i386/i686/fpu/s_fminl.S b/libc/sysdeps/i386/i686/fpu/s_fminl.S
new file mode 100644
index 000000000..e158ff895
--- /dev/null
+++ b/libc/sysdeps/i386/i686/fpu/s_fminl.S
@@ -0,0 +1,38 @@
+/* Compute minimum of two numbers, regarding NaN as missing argument.
+ Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .text
+ENTRY(__fminl)
+ fldt 4(%esp) // x
+ fldt 16(%esp) // x : y
+
+ fucomi %st(0), %st
+ fcmovu %st(1), %st // now %st contains y if not NaN, x otherwise
+
+ fucomi %st(1), %st
+ fcmovnb %st(1), %st
+
+ fstp %st(1)
+
+ ret
+END(__fminl)
+weak_alias (__fminl, fminl)
diff --git a/libc/sysdeps/i386/i686/hp-timing.c b/libc/sysdeps/i386/i686/hp-timing.c
new file mode 100644
index 000000000..c8c88650c
--- /dev/null
+++ b/libc/sysdeps/i386/i686/hp-timing.c
@@ -0,0 +1,24 @@
+/* Support for high precision, low overhead timing functions. i686 version.
+ Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/libc/sysdeps/i386/i686/hp-timing.h b/libc/sysdeps/i386/i686/hp-timing.h
new file mode 100644
index 000000000..b92486964
--- /dev/null
+++ b/libc/sysdeps/i386/i686/hp-timing.h
@@ -0,0 +1,157 @@
+/* High precision, low overhead timing functions. i686 version.
+ Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+
+/* The macros defined here use the timestamp counter in i586 and up versions
+ of the x86 processors. They provide a very accurate way to measure the
+ time with very little overhead. The time values themself have no real
+ meaning, only differences are interesting.
+
+ This version is for the i686 processors. The difference to the i586
+ version is that the timerstamp register is unconditionally used. This is
+ not the case for the i586 version where we have to perform runtime test
+ whether the processor really has this capability. We have to make this
+ distinction since the sysdeps/i386/i586 code is supposed to work on all
+ platforms while the i686 already contains i686-specific code.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register. */
+#define HP_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 64bit values for the times. */
+typedef unsigned long long int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+/* That's quite simple. Use the `rdtsc' instruction. Note that the value
+ might not be 100% accurate since there might be some more instructions
+ running in this moment. This could be changed by using a barrier like
+ 'cpuid' right before the `rdtsc' instruciton. But we are not interested
+ in accurate clock cycles here so we don't do this. */
+#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var))
+
+/* Use two 'rdtsc' instructions in a row to find out how long it takes. */
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ if (GLRO(dl_hp_timing_overhead) == 0) \
+ { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } \
+ } while (0)
+
+/* It's simple arithmetic for us. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* We have to jump through hoops to get this correctly implemented. */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ int __not_done; \
+ hp_timing_t __oldval = (Sum); \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ do \
+ { \
+ hp_timing_t __newval = __oldval + __diff; \
+ int __temp0, __temp1; \
+ __asm__ __volatile__ ("xchgl %0, %%ebx\n\t" \
+ "lock; cmpxchg8b %1\n\t" \
+ "sete %%bl\n\t" \
+ "xchgl %0, %%ebx" \
+ : "=SD" (__not_done), "=m" (Sum), \
+ "=A" (__oldval), "=c" (__temp0) \
+ : "m" (Sum), "2" (__oldval), \
+ "3" ((unsigned int) (__newval >> 32)), \
+ "0" ((unsigned int) __newval)); \
+ } \
+ while ((unsigned char) __not_done); \
+ } while (0)
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ size_t __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/libc/sysdeps/i386/i686/memcmp.S b/libc/sysdeps/i386/i686/memcmp.S
new file mode 100644
index 000000000..4bd5394be
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcmp.S
@@ -0,0 +1,423 @@
+/* Compare two memory blocks for differences in the first COUNT bytes.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* Preserve EBX. */
+#define BLK1 PARMS
+#define BLK2 BLK1+PTR_SIZE
+#define LEN BLK2+PTR_SIZE
+#define ENTRANCE pushl %ebx; cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (ebx, 0); ENTER
+#define RETURN popl %ebx; cfi_adjust_cfa_offset (-4); \
+ cfi_restore (ebx); LEAVE; ret; \
+ cfi_adjust_cfa_offset (4); cfi_rel_offset (ebx, 0);
+
+/* Load an entry in a jump table into EBX. TABLE is a jump table
+ with relative offsets. INDEX is a register contains the index
+ into the jump table. */
+#define LOAD_JUMP_TABLE_ENTRY(TABLE, INDEX) \
+ /* We first load PC into EBX. */ \
+ call __i686.get_pc_thunk.bx; \
+ /* Get the address of the jump table. */ \
+ addl $(TABLE - .), %ebx; \
+ /* Get the entry and convert the relative offset to the \
+ absolute address. */ \
+ addl (%ebx,INDEX,4), %ebx
+
+#ifdef HAVE_HIDDEN
+ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
+ .globl __i686.get_pc_thunk.bx
+ .hidden __i686.get_pc_thunk.bx
+#else
+ .text
+#endif
+ ALIGN (4)
+ .type __i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+ movl (%esp), %ebx
+ ret
+
+ .text
+ ALIGN (4)
+ENTRY (BP_SYM (memcmp))
+ ENTRANCE
+
+ movl BLK1(%esp), %eax
+ movl BLK2(%esp), %edx
+ movl LEN(%esp), %ecx
+
+ cmpl $1, %ecx
+ jne L(not_1)
+ movzbl (%eax), %ecx /* LEN == 1 */
+ cmpb (%edx), %cl
+ jne L(neq)
+L(bye):
+ xorl %eax, %eax
+ RETURN
+
+L(neq):
+ sbbl %eax, %eax
+ sbbl $-1, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+L(not_1):
+ jl L(bye) /* LEN == 0 */
+
+ pushl %esi
+ cfi_adjust_cfa_offset (4)
+ movl %eax, %esi
+ cfi_rel_offset (esi, 0)
+ cmpl $32, %ecx;
+ jge L(32bytesormore) /* LEN => 32 */
+
+ LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
+ addl %ecx, %edx
+ addl %ecx, %esi
+ jmp *%ebx
+
+ ALIGN (4)
+L(28bytes):
+ movl -28(%esi), %eax
+ movl -28(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(24bytes):
+ movl -24(%esi), %eax
+ movl -24(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(20bytes):
+ movl -20(%esi), %eax
+ movl -20(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(16bytes):
+ movl -16(%esi), %eax
+ movl -16(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(12bytes):
+ movl -12(%esi), %eax
+ movl -12(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(8bytes):
+ movl -8(%esi), %eax
+ movl -8(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(4bytes):
+ movl -4(%esi), %eax
+ movl -4(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(0bytes):
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(29bytes):
+ movl -29(%esi), %eax
+ movl -29(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(25bytes):
+ movl -25(%esi), %eax
+ movl -25(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(21bytes):
+ movl -21(%esi), %eax
+ movl -21(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(17bytes):
+ movl -17(%esi), %eax
+ movl -17(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(13bytes):
+ movl -13(%esi), %eax
+ movl -13(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(9bytes):
+ movl -9(%esi), %eax
+ movl -9(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(5bytes):
+ movl -5(%esi), %eax
+ movl -5(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(1bytes):
+ movzbl -1(%esi), %eax
+ cmpb -1(%edx), %al
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(30bytes):
+ movl -30(%esi), %eax
+ movl -30(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(26bytes):
+ movl -26(%esi), %eax
+ movl -26(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(22bytes):
+ movl -22(%esi), %eax
+ movl -22(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(18bytes):
+ movl -18(%esi), %eax
+ movl -18(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(14bytes):
+ movl -14(%esi), %eax
+ movl -14(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(10bytes):
+ movl -10(%esi), %eax
+ movl -10(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(6bytes):
+ movl -6(%esi), %eax
+ movl -6(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(2bytes):
+ movzwl -2(%esi), %eax
+ movzwl -2(%edx), %ecx
+ cmpb %cl, %al
+ jne L(set)
+ cmpl %ecx, %eax
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+L(31bytes):
+ movl -31(%esi), %eax
+ movl -31(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(27bytes):
+ movl -27(%esi), %eax
+ movl -27(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(23bytes):
+ movl -23(%esi), %eax
+ movl -23(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(19bytes):
+ movl -19(%esi), %eax
+ movl -19(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(15bytes):
+ movl -15(%esi), %eax
+ movl -15(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(11bytes):
+ movl -11(%esi), %eax
+ movl -11(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(7bytes):
+ movl -7(%esi), %eax
+ movl -7(%edx), %ecx
+ cmpl %ecx, %eax
+ jne L(find_diff)
+L(3bytes):
+ movzwl -3(%esi), %eax
+ movzwl -3(%edx), %ecx
+ cmpb %cl, %al
+ jne L(set)
+ cmpl %ecx, %eax
+ jne L(set)
+ movzbl -1(%esi), %eax
+ cmpb -1(%edx), %al
+ jne L(set)
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ xorl %eax, %eax
+ RETURN
+
+ cfi_adjust_cfa_offset (8)
+ cfi_rel_offset (esi, 0)
+ cfi_rel_offset (ebx, 4)
+ ALIGN (4)
+/* ECX >= 32. */
+L(32bytesormore):
+ subl $32, %ecx
+
+ movl (%esi), %eax
+ cmpl (%edx), %eax
+ jne L(load_ecx)
+
+ movl 4(%esi), %eax
+ cmpl 4(%edx), %eax
+ jne L(load_ecx_4)
+
+ movl 8(%esi), %eax
+ cmpl 8(%edx), %eax
+ jne L(load_ecx_8)
+
+ movl 12(%esi), %eax
+ cmpl 12(%edx), %eax
+ jne L(load_ecx_12)
+
+ movl 16(%esi), %eax
+ cmpl 16(%edx), %eax
+ jne L(load_ecx_16)
+
+ movl 20(%esi), %eax
+ cmpl 20(%edx), %eax
+ jne L(load_ecx_20)
+
+ movl 24(%esi), %eax
+ cmpl 24(%edx), %eax
+ jne L(load_ecx_24)
+
+ movl 28(%esi), %eax
+ cmpl 28(%edx), %eax
+ jne L(load_ecx_28)
+
+ addl $32, %esi
+ addl $32, %edx
+ cmpl $32, %ecx
+ jge L(32bytesormore)
+
+ LOAD_JUMP_TABLE_ENTRY (L(table_32bytes), %ecx)
+ addl %ecx, %edx
+ addl %ecx, %esi
+ jmp *%ebx
+
+L(load_ecx_28):
+ addl $0x4, %edx
+L(load_ecx_24):
+ addl $0x4, %edx
+L(load_ecx_20):
+ addl $0x4, %edx
+L(load_ecx_16):
+ addl $0x4, %edx
+L(load_ecx_12):
+ addl $0x4, %edx
+L(load_ecx_8):
+ addl $0x4, %edx
+L(load_ecx_4):
+ addl $0x4, %edx
+L(load_ecx):
+ movl (%edx), %ecx
+
+L(find_diff):
+ cmpb %cl, %al
+ jne L(set)
+ cmpb %ch, %ah
+ jne L(set)
+ shrl $16,%eax
+ shrl $16,%ecx
+ cmpb %cl, %al
+ jne L(set)
+ /* We get there only if we already know there is a
+ difference. */
+ cmpl %ecx, %eax
+L(set):
+ sbbl %eax, %eax
+ sbbl $-1, %eax
+ popl %esi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (esi)
+ RETURN
+END (BP_SYM (memcmp))
+
+ .section .rodata
+ ALIGN (2)
+L(table_32bytes) :
+ .long L(0bytes) - . + 0x0
+ .long L(1bytes) - . + 0x4
+ .long L(2bytes) - . + 0x8
+ .long L(3bytes) - . + 0xc
+ .long L(4bytes) - . + 0x10
+ .long L(5bytes) - . + 0x14
+ .long L(6bytes) - . + 0x18
+ .long L(7bytes) - . + 0x1c
+ .long L(8bytes) - . + 0x20
+ .long L(9bytes) - . + 0x24
+ .long L(10bytes) - . + 0x28
+ .long L(11bytes) - . + 0x2c
+ .long L(12bytes) - . + 0x30
+ .long L(13bytes) - . + 0x34
+ .long L(14bytes) - . + 0x38
+ .long L(15bytes) - . + 0x3c
+ .long L(16bytes) - . + 0x40
+ .long L(17bytes) - . + 0x44
+ .long L(18bytes) - . + 0x48
+ .long L(19bytes) - . + 0x4c
+ .long L(20bytes) - . + 0x50
+ .long L(21bytes) - . + 0x54
+ .long L(22bytes) - . + 0x58
+ .long L(23bytes) - . + 0x5c
+ .long L(24bytes) - . + 0x60
+ .long L(25bytes) - . + 0x64
+ .long L(26bytes) - . + 0x68
+ .long L(27bytes) - . + 0x6c
+ .long L(28bytes) - . + 0x70
+ .long L(29bytes) - . + 0x74
+ .long L(30bytes) - . + 0x78
+ .long L(31bytes) - . + 0x7c
+
+
+#undef bcmp
+weak_alias (BP_SYM (memcmp), BP_SYM (bcmp))
+libc_hidden_builtin_def (BP_SYM (memcmp))
diff --git a/libc/sysdeps/i386/i686/memcpy.S b/libc/sysdeps/i386/i686/memcpy.S
new file mode 100644
index 000000000..00e84ec2e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcpy.S
@@ -0,0 +1,69 @@
+/* Copy memory block and return pointer to beginning of destination block
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memcpy_chk)
+#endif
+ENTRY (BP_SYM (memcpy))
+ ENTER
+
+ movl LEN(%esp), %ecx
+ movl %edi, %eax
+ movl DEST(%esp), %edi
+ movl %esi, %edx
+ movl SRC(%esp), %esi
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ movl %eax, %edi
+ movl %edx, %esi
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (memcpy))
+libc_hidden_builtin_def (memcpy)
diff --git a/libc/sysdeps/i386/i686/memcpy_chk.S b/libc/sysdeps/i386/i686/memcpy_chk.S
new file mode 100644
index 000000000..2893911cd
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking memcpy for i686.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memcpy.S.
+ For libc.a, this is a separate source to avoid
+ memcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memcpy
+END (__memcpy_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memmove.S b/libc/sysdeps/i386/i686/memmove.S
new file mode 100644
index 000000000..b93b5c729
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memmove.S
@@ -0,0 +1,115 @@
+/* Copy memory block and return pointer to beginning of destination block
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE+4 /* one spilled register */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memmove_chk)
+#endif
+ENTRY (BP_SYM (memmove))
+ ENTER
+
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+
+ movl LEN(%esp), %ecx
+ movl DEST(%esp), %edi
+ cfi_rel_offset (edi, 0)
+ movl %esi, %edx
+ movl SRC(%esp), %esi
+ cfi_register (esi, edx)
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+
+ movl %edi, %eax
+ subl %esi, %eax
+ cmpl %eax, %edi
+ jae 3f
+
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ movl %edx, %esi
+ cfi_restore (esi)
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (edi, 0)
+ cfi_register (esi, edx)
+
+ /* Backward copying. */
+3: std
+ leal -1(%edi, %ecx), %edi
+ leal -1(%esi, %ecx), %esi
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: subl $1, %edi
+ subl $1, %esi
+ shrl $1, %ecx
+ jnc 2f
+ movsw
+2: subl $2, %edi
+ subl $2, %esi
+ rep
+ movsl
+ movl %edx, %esi
+ cfi_restore (esi)
+ movl DEST(%esp), %eax
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ cld
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (memmove))
+libc_hidden_builtin_def (memmove)
diff --git a/libc/sysdeps/i386/i686/memmove_chk.S b/libc/sysdeps/i386/i686/memmove_chk.S
new file mode 100644
index 000000000..23382ea8b
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memmove_chk.S
@@ -0,0 +1,35 @@
+/* Checking memmove for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memmove.S.
+ For libc.a, this is a separate source to avoid
+ memmove bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memmove_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memmove
+END (__memmove_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/mempcpy.S b/libc/sysdeps/i386/i686/mempcpy.S
new file mode 100644
index 000000000..6437e4a5d
--- /dev/null
+++ b/libc/sysdeps/i386/i686/mempcpy.S
@@ -0,0 +1,73 @@
+/* Copy memory block and return pointer to following byte.
+ For Intel 80x86, x>=6.
+ This file is part of the GNU C Library.
+ Copyright (C) 1998,1999,2000,2002,2004,2005 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define RTN PARMS
+#define DEST RTN+RTN_SIZE
+#define SRC DEST+PTR_SIZE
+#define LEN SRC+PTR_SIZE
+
+ .text
+#if defined PIC && !defined NOT_IN_libc
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__mempcpy_chk)
+#endif
+ENTRY (BP_SYM (__mempcpy))
+ ENTER
+
+ movl LEN(%esp), %ecx
+ movl %edi, %eax
+ cfi_register (edi, eax)
+ movl DEST(%esp), %edi
+ CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
+ movl %esi, %edx
+ cfi_register (esi, edx)
+ movl SRC(%esp), %esi
+ CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+ cld
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ xchgl %edi, %eax
+ cfi_restore (edi)
+ movl %edx, %esi
+ cfi_restore (esi)
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+
+ LEAVE
+ RET_PTR
+END (BP_SYM (__mempcpy))
+libc_hidden_def (BP_SYM (__mempcpy))
+weak_alias (BP_SYM (__mempcpy), BP_SYM (mempcpy))
+libc_hidden_builtin_def (mempcpy)
diff --git a/libc/sysdeps/i386/i686/mempcpy_chk.S b/libc/sysdeps/i386/i686/mempcpy_chk.S
new file mode 100644
index 000000000..dc9c6095f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/mempcpy_chk.S
@@ -0,0 +1,35 @@
+/* Checking mempcpy for x86-64.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in mempcpy.S.
+ For libc.a, this is a separate source to avoid
+ mempcpy bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__mempcpy_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp mempcpy
+END (__mempcpy_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memset.S b/libc/sysdeps/i386/i686/memset.S
new file mode 100644
index 000000000..dfa1aa701
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memset.S
@@ -0,0 +1,113 @@
+/* memset/bzero -- set memory area to CH/0
+ Highly optimized version for ix86, x>=6.
+ Copyright (C) 1999,2000,2003,2005,2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
+#define BZERO_P (defined memset)
+
+#define PARMS LINKAGE+4 /* space for 1 saved reg */
+#if BZERO_P
+# define DEST PARMS
+# define LEN DEST+PTR_SIZE
+#else
+# define RTN PARMS
+# define DEST RTN+RTN_SIZE
+# define CHR DEST+PTR_SIZE
+# define LEN CHR+4
+#endif
+
+ .text
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (BP_SYM (memset))
+ ENTER
+
+ cld
+ pushl %edi
+ cfi_adjust_cfa_offset (4)
+ movl DEST(%esp), %edx
+ movl LEN(%esp), %ecx
+ CHECK_BOUNDS_BOTH_WIDE (%edx, DEST(%esp), %ecx)
+#if BZERO_P
+ xorl %eax, %eax /* fill with 0 */
+#else
+ movzbl CHR(%esp), %eax
+#endif
+ jecxz 1f
+ movl %edx, %edi
+ cfi_rel_offset (edi, 0)
+ andl $3, %edx
+ jz 2f /* aligned */
+ jp 3f /* misaligned at 3, store just one byte below */
+ stosb /* misaligned at 1 or 2, store two bytes */
+ decl %ecx
+ jz 1f
+3: stosb
+ decl %ecx
+ jz 1f
+ xorl $1, %edx
+ jnz 2f /* was misaligned at 2 or 3, now aligned */
+ stosb /* was misaligned at 1, store third byte */
+ decl %ecx
+2: movl %ecx, %edx
+ shrl $2, %ecx
+ andl $3, %edx
+#if !BZERO_P
+ imul $0x01010101, %eax
+#endif
+ rep
+ stosl
+ movl %edx, %ecx
+ rep
+ stosb
+
+1:
+#if !BZERO_P
+ movl DEST(%esp), %eax /* start address of destination is result */
+ RETURN_BOUNDED_POINTER (DEST(%esp))
+#endif
+ popl %edi
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (edi)
+
+ LEAVE
+#if BZERO_P
+ ret
+#else
+ RET_PTR
+#endif
+END (BP_SYM (memset))
+libc_hidden_builtin_def (memset)
+
+#if defined PIC && !defined NOT_IN_libc && !BZERO_P
+strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
+ .section .gnu.warning.__memset_zero_constant_len_parameter
+ .string "memset used with constant zero length parameter; this could be due to transposed parameters"
+#endif
diff --git a/libc/sysdeps/i386/i686/memset_chk.S b/libc/sysdeps/i386/i686/memset_chk.S
new file mode 100644
index 000000000..cd93d5ee1
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memset_chk.S
@@ -0,0 +1,35 @@
+/* Checking memset for i686.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef PIC
+ /* For libc.so this is defined in memset.S.
+ For libc.a, this is a separate source to avoid
+ memset bringing in __chk_fail and all routines
+ it calls. */
+ .text
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp memset
+END (__memset_chk)
+#endif
diff --git a/libc/sysdeps/i386/i686/memusage.h b/libc/sysdeps/i386/i686/memusage.h
new file mode 100644
index 000000000..235c3fc72
--- /dev/null
+++ b/libc/sysdeps/i386/i686/memusage.h
@@ -0,0 +1,22 @@
+/* Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define GETSP() ({ register uintptr_t stack_ptr asm ("esp"); stack_ptr; })
+#define GETTIME(low,high) asm ("rdtsc" : "=a" (low), "=d" (high))
+
+#include <sysdeps/generic/memusage.h>
diff --git a/libc/sysdeps/i386/i686/strcmp.S b/libc/sysdeps/i386/i686/strcmp.S
new file mode 100644
index 000000000..8601c1ca0
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strcmp.S
@@ -0,0 +1,72 @@
+/* Highly optimized version for ix86, x>=6.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+#define PARMS LINKAGE /* no space for saved regs */
+#define STR1 PARMS
+#define STR2 STR1+PTR_SIZE
+
+ .text
+ENTRY (BP_SYM (strcmp))
+ ENTER
+
+ movl STR1(%esp), %ecx
+ movl STR2(%esp), %edx
+ CHECK_BOUNDS_LOW (%ecx, STR1(%esp))
+ CHECK_BOUNDS_LOW (%edx, STR2(%esp))
+
+L(oop): movb (%ecx), %al
+ cmpb (%edx), %al
+ jne L(neq)
+ incl %ecx
+ incl %edx
+ testb %al, %al
+ jnz L(oop)
+
+ xorl %eax, %eax
+ /* when strings are equal, pointers rest one beyond
+ the end of the NUL terminators. */
+ CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jbe)
+ CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jbe)
+ LEAVE
+ ret
+
+#ifndef __BOUNDED_POINTERS__
+L(neq): movl $1, %eax
+ movl $-1, %ecx
+ cmovbl %ecx, %eax
+#else
+L(neq): movl $1, %eax
+ ja L(chk)
+ negl %eax
+ /* When strings differ, pointers rest on
+ the unequal characters. */
+L(chk): CHECK_BOUNDS_HIGH (%ecx, STR1(%esp), jb)
+ CHECK_BOUNDS_HIGH (%edx, STR2(%esp), jb)
+#endif
+
+ LEAVE
+ ret
+END (BP_SYM (strcmp))
+libc_hidden_builtin_def (strcmp)
diff --git a/libc/sysdeps/i386/i686/strtok.S b/libc/sysdeps/i386/i686/strtok.S
new file mode 100644
index 000000000..fe225e548
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strtok.S
@@ -0,0 +1,281 @@
+/* strtok (str, delim) -- Return next DELIM separated token from STR.
+ For Intel 80686.
+ Copyright (C) 1998, 2000, 2001, 2005, 2006 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+#include "bp-sym.h"
+#include "bp-asm.h"
+
+/* This file can be used for three variants of the strtok function:
+
+ strtok:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+
+ strtok_r:
+ INPUT PARAMETER:
+ str (sp + 4)
+ delim (sp + 8)
+ save_ptr (sp + 12)
+
+ We do a common implementation here. */
+
+#ifdef USE_AS_STRTOK_R
+# define SAVE_PTR 0(%ecx)
+#else
+ .bss
+ .local save_ptr
+ ASM_TYPE_DIRECTIVE (save_ptr, @object)
+ .size save_ptr, 4
+save_ptr:
+# if __BOUNDED_POINTERS__
+ .space 12
+# else
+ .space 4
+# endif
+
+# ifdef PIC
+# define SAVE_PTR save_ptr@GOTOFF(%ebx)
+# else
+# define SAVE_PTR save_ptr
+# endif
+
+# define FUNCTION strtok
+#endif
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+# define PARMS LINKAGE+256+4 /* space for table and saved PIC register */
+#else
+# define PARMS LINKAGE+256 /* space for table */
+#endif
+#define RTN PARMS
+#define STR RTN+RTN_SIZE
+#define DELIM STR+PTR_SIZE
+#ifdef USE_AS_STRTOK_R
+# define SAVE DELIM+PTR_SIZE
+#endif
+
+ .text
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+0: movl (%esp), %ebx
+ ret
+#endif
+
+ENTRY (BP_SYM (FUNCTION))
+ ENTER
+
+#if !defined USE_AS_STRTOK_R && defined PIC
+ pushl %ebx /* Save PIC register. */
+ cfi_adjust_cfa_offset (4)
+ cfi_rel_offset (ebx, 0)
+ call 0b
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+#endif
+
+ /* First we create a table with flags for all possible characters.
+ For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
+ supported by the C string functions we have 256 characters.
+ Before inserting marks for the stop characters we clear the whole
+ table. */
+ movl %edi, %edx
+ subl $256, %esp
+ cfi_adjust_cfa_offset (256)
+ movl $64, %ecx
+ movl %esp, %edi
+ xorl %eax, %eax
+ cld
+ rep
+ stosl
+
+ /* Note: %ecx = 0 !!! */
+ movl %edx, %edi
+
+ movl STR(%esp), %edx /* Get start of string. */
+
+#ifdef USE_AS_STRTOK_R
+ /* The value is stored in the third argument. */
+ movl SAVE(%esp), %eax
+ movl (%eax), %eax
+#else
+ /* The value is in the local variable defined above. But
+ we have to take care for PIC code. */
+ movl SAVE_PTR, %eax
+#endif
+
+ /* If the pointer is NULL we have to use the stored value of
+ the last run. */
+ cmpl $0, %edx
+ cmove %eax, %edx
+ testl %edx, %edx
+ jz L(returnNULL)
+#if __BOUNDED_POINTERS__
+# ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx /* borrow %ecx for a moment */
+# endif
+ je L(0)
+ /* Save bounds of incoming non-NULL STR into save area. */
+ movl 4+STR(%esp), %eax
+ movl %eax, 4+SAVE_PTR
+ movl 8+STR(%esp), %eax
+ movl %eax, 8+SAVE_PTR
+L(0): CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
+# ifdef USE_AS_STRTOK_R
+ xorl %ecx, %ecx /* restore %ecx to zero */
+# endif
+#endif
+ movl DELIM(%esp), %eax /* Get start of delimiter set. */
+ CHECK_BOUNDS_LOW (%eax, DELIM(%esp))
+
+/* For understanding the following code remember that %ecx == 0 now.
+ Although all the following instruction only modify %cl we always
+ have a correct zero-extended 32-bit value in %ecx. */
+
+L(2): movb (%eax), %cl /* get byte from stopset */
+ testb %cl, %cl /* is NUL char? */
+ jz L(1_1) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 1(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_2) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 2(%eax), %cl /* get byte from stopset */
+ testb $0xff, %cl /* is NUL char? */
+ jz L(1_3) /* yes => start compare loop */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+
+ movb 3(%eax), %cl /* get byte from stopset */
+ addl $4, %eax /* increment stopset pointer */
+ movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
+ testb $0xff, %cl /* is NUL char? */
+ jnz L(2) /* no => process next dword from stopset */
+
+#if __BOUNDED_POINTERS__
+ jmp L(1_0) /* pointer is correct for bounds check */
+L(1_3): incl %eax /* adjust pointer for bounds check */
+L(1_2): incl %eax /* ditto */
+L(1_1): incl %eax /* ditto */
+L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jbe)
+#else
+L(1_3):; L(1_2):; L(1_1): /* fall through */
+#endif
+ leal -4(%edx), %eax /* prepare loop */
+
+ /* We use a neat trick for the following loop. Normally we would
+ have to test for two termination conditions
+ 1. a character in the stopset was found
+ and
+ 2. the end of the string was found
+ As a sign that the character is in the stopset we store its
+ value in the table. The value of NUL is NUL so the loop
+ terminates for NUL in every case. */
+
+L(3): addl $4, %eax /* adjust pointer for full loop round */
+
+ movb (%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(4) /* no => start of token */
+
+ movb 1(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(5) /* no => start of token */
+
+ movb 2(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jz L(6) /* no => start of token */
+
+ movb 3(%eax), %cl /* get byte from string */
+ testb %cl, (%esp,%ecx) /* is it contained in stopset? */
+ jnz L(3) /* yes => start of loop */
+
+ incl %eax /* adjust pointer */
+L(6): incl %eax
+L(5): incl %eax
+
+ /* Now we have to terminate the string. */
+
+L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
+
+L(7): addl $4, %edx /* adjust pointer for full loop round */
+
+ movb (%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(8) /* yes => return */
+
+ movb 1(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(9) /* yes => return */
+
+ movb 2(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ je L(10) /* yes => return */
+
+ movb 3(%edx), %cl /* get byte from string */
+ cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
+ jne L(7) /* no => start loop again */
+
+ incl %edx /* adjust pointer */
+L(10): incl %edx
+L(9): incl %edx
+
+L(8): cmpl %eax, %edx
+ je L(returnNULL) /* There was no token anymore. */
+
+ movb $0, (%edx) /* Terminate string. */
+
+ /* Are we at end of string? */
+ cmpb $0, %cl
+ leal 1(%edx), %ecx
+ cmovne %ecx, %edx
+
+ /* Store the pointer to the next character. */
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ CHECK_BOUNDS_HIGH (%edx, SAVE_PTR, jb)
+ RETURN_BOUNDED_POINTER (SAVE_PTR)
+
+L(epilogue):
+ /* Remove the stopset table. */
+ addl $256, %esp
+ cfi_adjust_cfa_offset (-256)
+#if !defined USE_AS_STRTOK_R && defined PIC
+ popl %ebx
+ cfi_adjust_cfa_offset (-4)
+ cfi_restore (ebx)
+#endif
+ LEAVE
+ RET_PTR
+
+L(returnNULL):
+ xorl %eax, %eax
+#ifdef USE_AS_STRTOK_R
+ movl SAVE(%esp), %ecx
+#endif
+ movl %edx, SAVE_PTR
+ RETURN_NULL_BOUNDED_POINTER
+ jmp L(epilogue)
+
+END (BP_SYM (FUNCTION))
diff --git a/libc/sysdeps/i386/i686/strtok_r.S b/libc/sysdeps/i386/i686/strtok_r.S
new file mode 100644
index 000000000..1c24ca85f
--- /dev/null
+++ b/libc/sysdeps/i386/i686/strtok_r.S
@@ -0,0 +1,5 @@
+#define FUNCTION __strtok_r
+#define USE_AS_STRTOK_R 1
+#include <sysdeps/i386/i686/strtok.S>
+weak_alias (BP_SYM (__strtok_r), BP_SYM (strtok_r))
+strong_alias (BP_SYM (__strtok_r), BP_SYM (__GI___strtok_r))
diff --git a/libc/sysdeps/i386/i686/tst-stack-align.h b/libc/sysdeps/i386/i686/tst-stack-align.h
new file mode 100644
index 000000000..e1894c65e
--- /dev/null
+++ b/libc/sysdeps/i386/i686/tst-stack-align.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdio.h>
+#include <stdint.h>
+#ifndef __SSE__
+#include_next <tst-stack-align.h>
+#else
+#include <xmmintrin.h>
+
+#define TEST_STACK_ALIGN() \
+ ({ \
+ __m128 _m; \
+ double _d = 12.0; \
+ long double _ld = 15.0; \
+ int _ret = 0; \
+ printf ("__m128: %p %zu\n", &_m, __alignof (__m128)); \
+ if ((((uintptr_t) &_m) & (__alignof (__m128) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("double: %g %p %zu\n", _d, &_d, __alignof (double)); \
+ if ((((uintptr_t) &_d) & (__alignof (double) - 1)) != 0) \
+ _ret = 1; \
+ \
+ printf ("ldouble: %Lg %p %zu\n", _ld, &_ld, __alignof (long double)); \
+ if ((((uintptr_t) &_ld) & (__alignof (long double) - 1)) != 0) \
+ _ret = 1; \
+ _ret; \
+ })
+#endif