summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/alpha/Makefile6
-rw-r--r--sysdeps/alpha/__longjmp.S59
-rw-r--r--sysdeps/alpha/__longjmp.c92
-rw-r--r--sysdeps/alpha/bits/setjmp.h79
-rw-r--r--sysdeps/alpha/bsd-_setjmp.S40
-rw-r--r--sysdeps/alpha/bsd-setjmp.S38
-rw-r--r--sysdeps/alpha/setjmp.S68
-rw-r--r--sysdeps/alpha/setjmp_aux.c76
-rw-r--r--sysdeps/generic/crypt.h2
-rw-r--r--sysdeps/generic/memccpy.c11
-rw-r--r--sysdeps/generic/memchr.c5
-rw-r--r--sysdeps/generic/memcmp.c2
-rw-r--r--sysdeps/generic/memmem.c1
-rw-r--r--sysdeps/generic/memmove.c2
-rw-r--r--sysdeps/generic/mempcpy.c66
-rw-r--r--sysdeps/generic/strcat.c2
-rw-r--r--sysdeps/generic/strchr.c2
-rw-r--r--sysdeps/generic/strcmp.c4
-rw-r--r--sysdeps/generic/strcpy.c2
-rw-r--r--sysdeps/generic/strcspn.c2
-rw-r--r--sysdeps/generic/strlen.c2
-rw-r--r--sysdeps/generic/strncat.c2
-rw-r--r--sysdeps/generic/strncmp.c4
-rw-r--r--sysdeps/generic/strncpy.c1
-rw-r--r--sysdeps/generic/strpbrk.c2
-rw-r--r--sysdeps/generic/strrchr.c4
-rw-r--r--sysdeps/generic/strsep.c2
-rw-r--r--sysdeps/generic/strspn.c1
-rw-r--r--sysdeps/generic/strstr.c2
-rw-r--r--sysdeps/generic/strtok.c2
-rw-r--r--sysdeps/generic/strtok_r.c1
-rw-r--r--sysdeps/generic/sysd-stdio.c33
-rw-r--r--sysdeps/i386/bits/select.h15
-rw-r--r--sysdeps/i386/bits/string.h17
-rw-r--r--sysdeps/i386/fpu/bits/mathinline.h21
-rw-r--r--sysdeps/i386/i486/atomicity.h57
-rw-r--r--sysdeps/i386/i486/bits/string.h850
-rw-r--r--sysdeps/i386/machine-gmon.h4
-rw-r--r--sysdeps/i386/memset.c2
-rw-r--r--sysdeps/mach/hurd/profil.c3
-rw-r--r--sysdeps/posix/defs.c2
-rw-r--r--sysdeps/posix/getcwd.c2
-rw-r--r--sysdeps/posix/pipestream.c20
-rw-r--r--sysdeps/posix/profil.c3
-rw-r--r--sysdeps/posix/sleep.c3
-rw-r--r--sysdeps/posix/stdio_init.c3
-rw-r--r--sysdeps/powerpc/Makefile18
-rw-r--r--sysdeps/powerpc/add_n.S68
-rw-r--r--sysdeps/powerpc/add_n.s68
-rw-r--r--sysdeps/powerpc/addmul_1.S49
-rw-r--r--sysdeps/powerpc/addmul_1.s50
-rw-r--r--sysdeps/powerpc/bsd-_setjmp.S6
-rw-r--r--sysdeps/powerpc/bsd-setjmp.S6
-rw-r--r--sysdeps/powerpc/dl-machine.h152
-rw-r--r--sysdeps/powerpc/lshift.S123
-rw-r--r--sysdeps/powerpc/lshift.s479
-rw-r--r--sysdeps/powerpc/machine-gmon.h (renamed from sysdeps/unix/sysv/linux/powerpc/_exit.S)20
-rw-r--r--sysdeps/powerpc/memset.S199
-rw-r--r--sysdeps/powerpc/memset.s202
-rw-r--r--sysdeps/powerpc/mul_1.S46
-rw-r--r--sysdeps/powerpc/mul_1.s47
-rw-r--r--sysdeps/powerpc/ppc-mcount.S84
-rw-r--r--sysdeps/powerpc/rshift.S56
-rw-r--r--sysdeps/powerpc/rshift.s59
-rw-r--r--sysdeps/powerpc/s_copysign.S40
-rw-r--r--sysdeps/powerpc/s_fabs.S33
-rw-r--r--sysdeps/powerpc/setjmp.S6
-rw-r--r--sysdeps/powerpc/strchr.S111
-rw-r--r--sysdeps/powerpc/strchr.s118
-rw-r--r--sysdeps/powerpc/strcmp.S115
-rw-r--r--sysdeps/powerpc/strcmp.s273
-rw-r--r--sysdeps/powerpc/strlen.S144
-rw-r--r--sysdeps/powerpc/strlen.s144
-rw-r--r--sysdeps/powerpc/sub_n.S68
-rw-r--r--sysdeps/powerpc/sub_n.s69
-rw-r--r--sysdeps/powerpc/submul_1.S52
-rw-r--r--sysdeps/powerpc/submul_1.s52
-rw-r--r--sysdeps/powerpc/test-arith.c15
-rw-r--r--sysdeps/stub/atomicity.h53
-rw-r--r--sysdeps/stub/ftruncate.c1
-rw-r--r--sysdeps/stub/getdents.c1
-rw-r--r--sysdeps/stub/init-posix.c2
-rw-r--r--sysdeps/stub/profil.c3
-rw-r--r--sysdeps/stub/reboot.c1
-rw-r--r--sysdeps/stub/swapon.c1
-rw-r--r--sysdeps/stub/syscall.c1
-rw-r--r--sysdeps/stub/ualarm.c1
-rw-r--r--sysdeps/stub/usleep.c1
-rw-r--r--sysdeps/unix/sysv/linux/if_index.c2
-rw-r--r--sysdeps/unix/sysv/linux/net/if.h5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/mman.h26
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/brk.S (renamed from sysdeps/unix/sysv/linux/powerpc/brk.c)52
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/clone.S29
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/profil-counter.h14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sigreturn.S9
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/socket.S14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/syscall.S8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h111
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/ioctls.h8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/termios.h10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S2
-rw-r--r--sysdeps/vax/strcmp.s85
102 files changed, 2715 insertions, 2314 deletions
diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile
index 5fe8e4ee7f..6cf4a173a6 100644
--- a/sysdeps/alpha/Makefile
+++ b/sysdeps/alpha/Makefile
@@ -21,10 +21,6 @@ ifeq ($(subdir),gmon)
sysdep_routines += _mcount
endif
-ifeq ($(subdir),setjmp)
-sysdep_routines += setjmp_aux
-endif
-
ifeq ($(subdir),gnulib)
sysdep_routines += $(divrem)
endif
@@ -45,6 +41,6 @@ endif
divrem := divl divq reml remq
-# For now, build everything with full IEEE math support.
+# For now, build everything with full IEEE math support.
# TODO: build separate libm and libm-ieee.
sysdep-CFLAGS += -mieee
diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S
new file mode 100644
index 0000000000..34731172e1
--- /dev/null
+++ b/sysdeps/alpha/__longjmp.S
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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. */
+
+#define __ASSEMBLY__
+
+#include <sysdep.h>
+#include <bits/setjmp.h>
+
+
+ENTRY(__longjmp)
+#ifdef PROF
+ ldgp gp, 0(pv)
+ .set noat
+ lda AT, _mcount
+ jsr AT, (AT), _mcount
+ .set at
+ .prologue 1
+#else
+ .prologue 0
+#endif
+
+ mov a1, v0
+ ldq s0, JB_S0*8(a0)
+ ldq s1, JB_S1*8(a0)
+ ldq s2, JB_S2*8(a0)
+ ldq s3, JB_S3*8(a0)
+ ldq s4, JB_S4*8(a0)
+ ldq s5, JB_S5*8(a0)
+ ldq ra, JB_PC*8(a0)
+ ldq fp, JB_FP*8(a0)
+ ldq t0, JB_SP*8(a0)
+ ldt $f2, JB_F2*8(a0)
+ ldt $f3, JB_F3*8(a0)
+ ldt $f4, JB_F4*8(a0)
+ ldt $f5, JB_F5*8(a0)
+ ldt $f6, JB_F6*8(a0)
+ ldt $f7, JB_F7*8(a0)
+ ldt $f8, JB_F8*8(a0)
+ ldt $f9, JB_F9*8(a0)
+ cmoveq v0, 1, v0
+ mov t0, sp
+ ret
+
+END(__longjmp)
diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c
deleted file mode 100644
index 98eba7c513..0000000000
--- a/sysdeps/alpha/__longjmp.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C 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. */
-
-/* Global register vars must come before any function defn. */
-
-register long int
- r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
- r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1 /* XXX */
-register double
- f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
- f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-#include <setjmp.h>
-
-
-/* Jump to the position specified by ENV, causing the
- setjmp call there to return VAL, or 1 if VAL is 0. */
-void
-__longjmp (__jmp_buf env, int val)
-{
- register long int retval asm ("$0");
-
- /* Restore the integer registers. */
- r9 = env[0].__9;
- r10 = env[0].__10;
- r11 = env[0].__11;
- r12 = env[0].__12;
- r13 = env[0].__13;
- r14 = env[0].__14;
-
-#if 1 /* XXX */
- /* Restore the floating point registers. */
- f2 = env[0].__f2;
- f3 = env[0].__f3;
- f4 = env[0].__f4;
- f5 = env[0].__f5;
- f6 = env[0].__f6;
- f7 = env[0].__f7;
- f8 = env[0].__f8;
- f9 = env[0].__f9;
-#endif
-
- /* Set the return PC to that of setjmp's caller. */
- retpc = env[0].__pc;
-
- /* Restore the FP and SP of setjmp's caller. */
- fp = env[0].__fp;
- sp = env[0].__sp;
-
- /* Return VAL (or 1 if VAL is zero) to setjmp's caller.
-
- We use an asm here rather than a normal C return statement
- just in case the compiler wanted to do some stack frobnication
- in the function epilogue. Since we have already restored
- precisely the FP and SP the desired environment needs,
- we must avoid the compiler doing anything with the stack. */
-
-
- asm volatile
- ("cmoveq %1, 1, %0\n\t" /* $0 = val ?: 1; */
- "ret $31, (%2), 1" /* return $0 */
- : "=r" (retval)
- /* The "0" constraint should force VAL into $0. */
- : "0" (val), "r" (retpc));
-
- while (1)
- {
- /* The loop is just to avoid `volatile function does return' warnings.
- The instruction will only be executed once. */
- asm volatile ("");
- }
-}
diff --git a/sysdeps/alpha/bits/setjmp.h b/sysdeps/alpha/bits/setjmp.h
index d461205c06..9aa30463d6 100644
--- a/sysdeps/alpha/bits/setjmp.h
+++ b/sysdeps/alpha/bits/setjmp.h
@@ -17,30 +17,57 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-typedef struct
- {
- /* Integer registers:
- $0 is the return value;
- $1-$8, $22-$25, $28 are call-used;
- $9-$14 we save here;
- $15 is the FP and we save it here;
- $16-$21 are input arguments (call-used);
- $26 is the return PC and we save it here;
- $27 is the procedure value (i.e., the address of __setjmp);
- $29 is the global pointer, which the caller will reconstruct
- from the return address restored in $26;
- $30 is the stack pointer and we save it here;
- $31 is always zero. */
- long int __9, __10, __11, __12, __13, __14;
- long int *__pc, *__fp, *__sp;
+/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
+ We use an array of 'long int' instead, to make writing the
+ assembler easier. Naturally, user code should not depend on
+ either representation. */
-#if 1 /* XXX need predefine for TARGET_FPREGS */
- /* Floating-point registers:
- $f0 is the floating return value;
- $f1, $f10-$f15, $f22-$f30 are call-used;
- $f2-$f9 we save here;
- $f16-$21 are input args (call-used);
- $f31 is always zero. */
- double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9;
-#endif /* Have FP regs. */
- } __jmp_buf[1];
+/*
+ * Integer registers:
+ * $0 is the return value (va);
+ * $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at);
+ * $9-$14 we save here (s0-s5);
+ * $15 is the FP and we save it here (fp or s6);
+ * $16-$21 are input arguments (call-used) (a0-a5);
+ * $26 is the return PC and we save it here (ra);
+ * $27 is the procedure value (i.e., the address of __setjmp) (pv or t12);
+ * $29 is the global pointer, which the caller will reconstruct
+ * from the return address restored in $26 (gp);
+ * $30 is the stack pointer and we save it here (sp);
+ * $31 is always zero (zero).
+ *
+ * Floating-point registers:
+ * $f0 is the floating return value;
+ * $f1, $f10-$f15, $f22-$f30 are call-used;
+ * $f2-$f9 we save here;
+ * $f16-$21 are input args (call-used);
+ * $f31 is always zero.
+ *
+ * Note that even on Alpha hardware that does not have an FPU (there
+ * isn't such a thing currently) it is required to implement the FP
+ * registers.
+ */
+
+#if defined(__USE_MISC) || defined(__ASSEMBLY__)
+#define JB_S0 0
+#define JB_S1 1
+#define JB_S2 2
+#define JB_S3 3
+#define JB_S4 4
+#define JB_S5 5
+#define JB_PC 6
+#define JB_FP 7
+#define JB_SP 8
+#define JB_F2 9
+#define JB_F3 10
+#define JB_F4 11
+#define JB_F5 12
+#define JB_F6 13
+#define JB_F7 14
+#define JB_F8 15
+#define JB_F9 16
+#endif
+
+#ifndef __ASSEMBLY__
+typedef long int __jmp_buf[17];
+#endif
diff --git a/sysdeps/alpha/bsd-_setjmp.S b/sysdeps/alpha/bsd-_setjmp.S
index 07fb0c7637..4e6a2da560 100644
--- a/sysdeps/alpha/bsd-_setjmp.S
+++ b/sysdeps/alpha/bsd-_setjmp.S
@@ -1,39 +1 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. Alpha version.
- Copyright (C) 1994, 1996 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C 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. */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
- We cannot do it in C because it must be a tail-call, so frame-unwinding
- in setjmp doesn't clobber the state restored by longjmp. */
-
-#include <sysdep.h>
-
-ENTRY(_setjmp)
- ldgp $29,0($27)
-#ifdef PROF
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
-#endif
- .prologue 1
- bis $31, $31, $17 /* Pass a second argument of zero. */
- jmp $31, __sigsetjmp /* Call __sigsetjmp. */
- END(_setjmp)
-
-strong_alias_asm(_setjmp, __setjmp)
+/* _setjmp is in setjmp.S */
diff --git a/sysdeps/alpha/bsd-setjmp.S b/sysdeps/alpha/bsd-setjmp.S
index cf5bf189de..1da848d2f1 100644
--- a/sysdeps/alpha/bsd-setjmp.S
+++ b/sysdeps/alpha/bsd-setjmp.S
@@ -1,37 +1 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. Alpha version.
- Copyright (C) 1994, 1996 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C 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. */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
- We cannot do it in C because it must be a tail-call, so frame-unwinding
- in setjmp doesn't clobber the state restored by longjmp. */
-
-#include <sysdep.h>
-
-ENTRY(setjmp)
- ldgp $29, 0($27)
-#ifdef PROF
- .set noat
- lda AT, _mcount
- jsr AT, (AT), _mcount
- .set at
-#endif
- .prologue 1
- bis $31, 1, $17 /* Pass a second argument of one. */
- jmp $31, __sigsetjmp /* Call __sigsetjmp. */
- END(setjmp)
+/* setjmp is in setjmp.S */
diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S
index 4b2e147b15..48fe33b3ec 100644
--- a/sysdeps/alpha/setjmp.S
+++ b/sysdeps/alpha/setjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1994, 1996, 1997 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
@@ -16,13 +16,21 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define __ASSEMBLY__
+
#include <sysdep.h>
+#include <bits/setjmp.h>
+
+ .ent __sigsetjmp
+ .global __sigsetjmp
+__sigsetjmp:
+ ldgp gp, 0(pv)
-/* The function __sigsetjmp_aux saves all the registers, but it can't
- reliably access the stack or frame pointers, so we pass them in as
- extra arguments. */
-ENTRY (__sigsetjmp)
- ldgp $29, 0($27)
+$sigsetjmp_local:
+ subq sp, 16, sp
+ .frame sp, 16, ra, 0
+ stq ra, 0(sp)
+ .mask 0x04000000, -16
#ifdef PROF
.set noat
lda AT, _mcount
@@ -31,8 +39,48 @@ ENTRY (__sigsetjmp)
#endif
.prologue 1
- bis $30, $30, $18 /* Pass SP as 3rd arg. */
- bis $15, $15, $19 /* Pass FP as 4th arg. */
- jmp $31, __sigsetjmp_aux /* Call __sigsetjmp_aux. */
+ stq s0, JB_S0*8(a0)
+ stq s1, JB_S1*8(a0)
+ stq s2, JB_S2*8(a0)
+ stq s3, JB_S3*8(a0)
+ stq s4, JB_S4*8(a0)
+ stq s5, JB_S5*8(a0)
+ stq ra, JB_PC*8(a0)
+ addq sp, 16, t0
+ stq fp, JB_FP*8(a0)
+ stq t0, JB_SP*8(a0)
+ stt $f2, JB_F2*8(a0)
+ stt $f3, JB_F3*8(a0)
+ stt $f4, JB_F4*8(a0)
+ stt $f5, JB_F5*8(a0)
+ stt $f6, JB_F6*8(a0)
+ stt $f7, JB_F7*8(a0)
+ stt $f8, JB_F8*8(a0)
+ stt $f9, JB_F9*8(a0)
+
+ /* Call to C to (potentially) save our signal mask. */
+ jsr ra, __sigjmp_save
+
+ ldq ra, 0(sp)
+ addq sp, 16, sp
+ ret
+
+END(__sigsetjmp)
+
+/* Put these traditional entry points in the same file so that we can
+ elide much of the nonsense in trying to jmp to the real function. */
+
+ENTRY(_setjmp)
+ ldgp gp, 0(pv)
+ mov 0, a1
+ br $sigsetjmp_local
+END(_setjmp)
+
+ENTRY(setjmp)
+ ldgp gp, 0(pv)
+ mov 1, a1
+ br $sigsetjmp_local
+END(setjmp)
- END(__sigsetjmp)
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c
deleted file mode 100644
index fa26975295..0000000000
--- a/sysdeps/alpha/setjmp_aux.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
- published by the Free Software Foundation; either version 2 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C 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. */
-
-/* Global register decls must come before any function defn. */
-
-register long int
- r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
- r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1 /* XXX */
-register double
- f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
- f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-
-#include <setjmp.h>
-
-
-/* Save the current program position in ENV and return 0. */
-int
-__sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp)
-{
- /* Save the integer registers. */
- env[0].__jmpbuf[0].__9 = r9;
- env[0].__jmpbuf[0].__10 = r10;
- env[0].__jmpbuf[0].__11 = r11;
- env[0].__jmpbuf[0].__12 = r12;
- env[0].__jmpbuf[0].__13 = r13;
- env[0].__jmpbuf[0].__14 = r14;
-
-#if 1 /* XXX */
- /* Save the floating point registers. */
- env[0].__jmpbuf[0].__f2 = f2;
- env[0].__jmpbuf[0].__f3 = f3;
- env[0].__jmpbuf[0].__f4 = f4;
- env[0].__jmpbuf[0].__f5 = f5;
- env[0].__jmpbuf[0].__f6 = f6;
- env[0].__jmpbuf[0].__f7 = f7;
- env[0].__jmpbuf[0].__f8 = f8;
- env[0].__jmpbuf[0].__f9 = f9;
-#endif
-
- /* Save the return address of our caller, where longjmp will jump to. */
- env[0].__jmpbuf[0].__pc = retpc;
-
- /* Save the FP and SP of our caller. The __sigsetjmp entry point
- simply puts these in the argument registers for us to fetch. */
- env[0].__jmpbuf[0].__fp = fp;
- env[0].__jmpbuf[0].__sp = sp;
-
- /* Save the signal mask if requested. */
- __sigjmp_save (env, savemask);
-
- retpc = env[0].__jmpbuf[0].__pc; /* restore ra, ugly... */
-
- /* Return to the original caller of __sigsetjmp. */
- return 0;
-}
diff --git a/sysdeps/generic/crypt.h b/sysdeps/generic/crypt.h
index 3f8f960140..c14554c829 100644
--- a/sysdeps/generic/crypt.h
+++ b/sysdeps/generic/crypt.h
@@ -50,6 +50,8 @@ struct crypt_data
int direction, initialized;
};
+extern char *__crypt_r __P ((__const char *__key, __const char *__salt,
+ struct crypt_data *__data));
extern char *crypt_r __P ((__const char *__key, __const char *__salt,
struct crypt_data *__data));
#endif
diff --git a/sysdeps/generic/memccpy.c b/sysdeps/generic/memccpy.c
index 6d85a791c6..44a874a954 100644
--- a/sysdeps/generic/memccpy.c
+++ b/sysdeps/generic/memccpy.c
@@ -18,11 +18,12 @@
#include <string.h>
-/*
- * Copy no more than N bytes of SRC to DEST, stopping when C is found.
- * Return the position in DEST one byte past where C was copied,
- * or NULL if C was not found in the first N bytes of SRC.
- */
+#undef __memccpy
+#undef memccpy
+
+/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
+ Return the position in DEST one byte past where C was copied, or
+ NULL if C was not found in the first N bytes of SRC. */
void *
__memccpy (dest, src, c, n)
void *dest; const void *src;
diff --git a/sysdeps/generic/memchr.c b/sysdeps/generic/memchr.c
index 60276e9942..c8926c7b38 100644
--- a/sysdeps/generic/memchr.c
+++ b/sysdeps/generic/memchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996, 1997 Free Software Foundation, Inc.
Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se) and
commentary by Jim Blandy (jimb@ai.mit.edu);
@@ -47,9 +47,10 @@
#include <sys/types.h>
+#undef memchr
-/* Search no more than N bytes of S for C. */
+/* Search no more than N bytes of S for C. */
__ptr_t
memchr (s, c, n)
const __ptr_t s;
diff --git a/sysdeps/generic/memcmp.c b/sysdeps/generic/memcmp.c
index 9dac13fc91..8fa371192c 100644
--- a/sysdeps/generic/memcmp.c
+++ b/sysdeps/generic/memcmp.c
@@ -34,6 +34,8 @@
#include <string.h>
#endif
+#undef memcmp
+
#ifdef _LIBC
#include <memcopy.h>
diff --git a/sysdeps/generic/memmem.c b/sysdeps/generic/memmem.c
index 8163709686..9e4e342237 100644
--- a/sysdeps/generic/memmem.c
+++ b/sysdeps/generic/memmem.c
@@ -19,6 +19,7 @@
#include <stddef.h>
#include <string.h>
+#undef memmem
/* Return the first occurrence of NEEDLE in HAYSTACK. */
void *
diff --git a/sysdeps/generic/memmove.c b/sysdeps/generic/memmove.c
index f4a900973d..4115aa31c7 100644
--- a/sysdeps/generic/memmove.c
+++ b/sysdeps/generic/memmove.c
@@ -29,12 +29,14 @@
#define a1const
#define a2 src /* Second arg is SRC. */
#define a2const const
+#undef memmove
#endif
#if !defined(RETURN) || !defined(rettype)
#define RETURN(s) return (s) /* Return DEST. */
#define rettype void *
#endif
+
rettype
memmove (a1, a2, len)
a1const void *a1;
diff --git a/sysdeps/generic/mempcpy.c b/sysdeps/generic/mempcpy.c
new file mode 100644
index 0000000000..43873405c5
--- /dev/null
+++ b/sysdeps/generic/mempcpy.c
@@ -0,0 +1,66 @@
+/* Copy memory to memory until the specified number of bytes
+ has been copied, return pointer to following byte.
+ Overlap is NOT handled correctly.
+ Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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 <string.h>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+#undef mempcpy
+
+void *
+__mempcpy (dstpp, srcpp, len)
+ void *dstpp;
+ const void *srcpp;
+ size_t len;
+{
+ unsigned long int dstp = (long int) dstpp;
+ unsigned long int srcp = (long int) srcpp;
+
+ /* Copy from the beginning to the end. */
+
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+ as much as possible. */
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+ /* Copy from SRCP to DSTP taking advantage of the known alignment of
+ DSTP. Number of bytes remaining is put in the third argument,
+ i.e. in LEN. This number may vary from machine to machine. */
+
+ WORD_COPY_FWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_FWD (dstp, srcp, len);
+
+ return (void *) dstp;
+}
+weak_alias (__mempcpy, mempcpy)
diff --git a/sysdeps/generic/strcat.c b/sysdeps/generic/strcat.c
index 05abd01eff..d8dbab2192 100644
--- a/sysdeps/generic/strcat.c
+++ b/sysdeps/generic/strcat.c
@@ -19,6 +19,8 @@
#include <string.h>
#include <memcopy.h>
+#undef strcat
+
/* Append SRC on the end of DEST. */
char *
strcat (dest, src)
diff --git a/sysdeps/generic/strchr.c b/sysdeps/generic/strchr.c
index d9e58a85a7..3663382556 100644
--- a/sysdeps/generic/strchr.c
+++ b/sysdeps/generic/strchr.c
@@ -22,9 +22,9 @@
#include <string.h>
+#undef strchr
/* Find the first occurrence of C in S. */
-
char *
strchr (s, c)
const char *s;
diff --git a/sysdeps/generic/strcmp.c b/sysdeps/generic/strcmp.c
index a8d9db1bc9..62e55f56ab 100644
--- a/sysdeps/generic/strcmp.c
+++ b/sysdeps/generic/strcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 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
@@ -19,6 +19,8 @@
#include <string.h>
#include <memcopy.h>
+#undef strcmp
+
/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
diff --git a/sysdeps/generic/strcpy.c b/sysdeps/generic/strcpy.c
index fc6beb27fd..cb260cf85a 100644
--- a/sysdeps/generic/strcpy.c
+++ b/sysdeps/generic/strcpy.c
@@ -20,6 +20,8 @@
#include <string.h>
#include <memcopy.h>
+#undef strcpy
+
/* Copy SRC to DEST. */
char *
strcpy (dest, src)
diff --git a/sysdeps/generic/strcspn.c b/sysdeps/generic/strcspn.c
index d7d59b250b..3630a13332 100644
--- a/sysdeps/generic/strcspn.c
+++ b/sysdeps/generic/strcspn.c
@@ -29,6 +29,8 @@
# endif
#endif
+#undef strcspn
+
/* Return the length of the maximum initial segment of S
which contains no characters from REJECT. */
size_t
diff --git a/sysdeps/generic/strlen.c b/sysdeps/generic/strlen.c
index 37dc9ed20c..1fb8b1c97c 100644
--- a/sysdeps/generic/strlen.c
+++ b/sysdeps/generic/strlen.c
@@ -20,10 +20,10 @@
#include <string.h>
+#undef strlen
/* Return the length of the null-terminated string STR. Scan for
the null terminator quickly by testing four bytes at a time. */
-
size_t
strlen (str)
const char *str;
diff --git a/sysdeps/generic/strncat.c b/sysdeps/generic/strncat.c
index 1233f8b54b..ae9f5e1be3 100644
--- a/sysdeps/generic/strncat.c
+++ b/sysdeps/generic/strncat.c
@@ -24,6 +24,8 @@
typedef char reg_char;
#endif
+#undef strncat
+
char *
strncat (s1, s2, n)
char *s1;
diff --git a/sysdeps/generic/strncmp.c b/sysdeps/generic/strncmp.c
index eea64389f8..6e5dabebcd 100644
--- a/sysdeps/generic/strncmp.c
+++ b/sysdeps/generic/strncmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 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
@@ -19,6 +19,8 @@
#include <string.h>
#include <memcopy.h>
+#undef strncmp
+
/* Compare no more than N characters of S1 and S2,
returning less than, equal to or greater than zero
if S1 is lexicographically less than, equal to or
diff --git a/sysdeps/generic/strncpy.c b/sysdeps/generic/strncpy.c
index 06f5cec2ed..24c7269b09 100644
--- a/sysdeps/generic/strncpy.c
+++ b/sysdeps/generic/strncpy.c
@@ -19,6 +19,7 @@
#include <string.h>
#include <memcopy.h>
+#undef strncpy
char *
strncpy (s1, s2, n)
diff --git a/sysdeps/generic/strpbrk.c b/sysdeps/generic/strpbrk.c
index 3b533e1b87..a49d2b145b 100644
--- a/sysdeps/generic/strpbrk.c
+++ b/sysdeps/generic/strpbrk.c
@@ -24,6 +24,8 @@
# include <string.h>
#endif
+#undef strpbrk
+
/* Find the first occurrence in S of any character in ACCEPT. */
char *
strpbrk (s, accept)
diff --git a/sysdeps/generic/strrchr.c b/sysdeps/generic/strrchr.c
index db5549b922..98839ea4c4 100644
--- a/sysdeps/generic/strrchr.c
+++ b/sysdeps/generic/strrchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997 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
@@ -18,6 +18,8 @@
#include <string.h>
+#undef strrchr
+
/* Find the last occurrence of C in S. */
char *
strrchr (const char *s, int c)
diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c
index b2c7e90c39..b5ea6ead9d 100644
--- a/sysdeps/generic/strsep.c
+++ b/sysdeps/generic/strsep.c
@@ -18,6 +18,8 @@
#include <string.h>
+#undef strsep
+
char *
__strsep (char **stringp, const char *delim)
{
diff --git a/sysdeps/generic/strspn.c b/sysdeps/generic/strspn.c
index 9d2fe63848..5f64a6f756 100644
--- a/sysdeps/generic/strspn.c
+++ b/sysdeps/generic/strspn.c
@@ -18,6 +18,7 @@
#include <string.h>
+#undef strspn
/* Return the length of the maximum initial segment
of S which contains only characters in ACCEPT. */
diff --git a/sysdeps/generic/strstr.c b/sysdeps/generic/strstr.c
index 85774d3491..03d6c8e5fc 100644
--- a/sysdeps/generic/strstr.c
+++ b/sysdeps/generic/strstr.c
@@ -36,6 +36,8 @@
typedef unsigned chartype;
+#undef strstr
+
char *
strstr (phaystack, pneedle)
const char *phaystack;
diff --git a/sysdeps/generic/strtok.c b/sysdeps/generic/strtok.c
index 5eb0ee6f07..b366653cb3 100644
--- a/sysdeps/generic/strtok.c
+++ b/sysdeps/generic/strtok.c
@@ -21,6 +21,8 @@
static char *olds = NULL;
+#undef strtok
+
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
diff --git a/sysdeps/generic/strtok_r.c b/sysdeps/generic/strtok_r.c
index 3b7d202a6c..44430dae40 100644
--- a/sysdeps/generic/strtok_r.c
+++ b/sysdeps/generic/strtok_r.c
@@ -19,6 +19,7 @@
#include <string.h>
+#undef strtok_r
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the saved pointer in SAVE_PTR is used as
diff --git a/sysdeps/generic/sysd-stdio.c b/sysdeps/generic/sysd-stdio.c
index f5147bb3aa..9818f84c5c 100644
--- a/sysdeps/generic/sysd-stdio.c
+++ b/sysdeps/generic/sysd-stdio.c
@@ -28,10 +28,7 @@
/* Read N bytes into BUF from COOKIE. */
int
-__stdio_read (cookie, buf, n)
- void *cookie;
- register char *buf;
- register size_t n;
+__stdio_read (void *cookie, char *buf, size_t n;)
{
const int fd = (int) cookie;
#if defined (EINTR) && defined (EINTR_REPEAT)
@@ -58,10 +55,7 @@ __stdio_read (cookie, buf, n)
/* Write N bytes from BUF to COOKIE. */
int
-__stdio_write (cookie, buf, n)
- void *cookie;
- register const char *buf;
- register size_t n;
+__stdio_write (void *cookie, const char *buf, size_t n)
{
const int fd = (int) cookie;
register size_t written = 0;
@@ -92,10 +86,7 @@ __stdio_write (cookie, buf, n)
The new file position is stored in *POS.
Returns zero if successful, nonzero if not. */
int
-__stdio_seek (cookie, pos, whence)
- void *cookie;
- fpos_t *pos;
- int whence;
+__stdio_seek (void *cookie, fpos_t *pos, int whence)
{
off_t new;
new = __lseek ((int) cookie, (off_t) *pos, whence);
@@ -108,8 +99,7 @@ __stdio_seek (cookie, pos, whence)
/* Close COOKIE. */
int
-__stdio_close (cookie)
- void *cookie;
+__stdio_close (void *cookie)
{
return __close ((int) cookie);
}
@@ -118,8 +108,7 @@ __stdio_close (cookie)
or -1 for errors. If COOKIE does not relate to any POSIX.1 file
descriptor, this should return -1 with errno set to EOPNOTSUPP. */
int
-__stdio_fileno (cookie)
- void *cookie;
+__stdio_fileno (void *cookie)
{
return (int) cookie;
}
@@ -127,10 +116,7 @@ __stdio_fileno (cookie)
/* Open the given file with the mode given in the __io_mode argument. */
int
-__stdio_open (filename, m, cookieptr)
- const char *filename;
- __io_mode m;
- void **cookieptr;
+__stdio_open (const char *filename, __io_mode m, void **cookieptr)
{
int fd;
int mode;
@@ -164,11 +150,8 @@ __stdio_open (filename, m, cookieptr)
/* Open FILENAME with the mode in M. Use the same magic cookie
already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN. */
int
-__stdio_reopen (filename, m, cookieptr, closefn)
- const char *filename;
- __io_mode m;
- void **cookieptr;
- __io_close_fn closefn;
+__stdio_reopen (const char *filename, __io_mode m, void **cookieptr,
+ __io_close_fn closefn)
{
void *newcookie;
diff --git a/sysdeps/i386/bits/select.h b/sysdeps/i386/bits/select.h
index 8c9a5434b9..edcb562945 100644
--- a/sysdeps/i386/bits/select.h
+++ b/sysdeps/i386/bits/select.h
@@ -24,29 +24,30 @@
#if defined __GNUC__ && __GNUC__ >= 2
# define __FD_ZERO(fdsetp) \
- __asm__ __volatile__ ("cld ; rep ; stosl" \
- : "=m" (*(__fd_set *) (fdsetp)) \
+ __asm__ __volatile__ ("cld; rep; stosl" \
+ : "=m" (((__fd_mask *) \
+ (fdsetp))[__FDELT (__FD_SETSIZE)]) \
: "a" (0), "c" (sizeof (__fd_set) \
/ sizeof (__fd_mask)), \
"D" ((__fd_set *) (fdsetp)) \
:"cx","di")
# define __FD_SET(fd, fdsetp) \
__asm__ __volatile__ ("btsl %1,%0" \
- : "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)]) \
+ : "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \
: "r" (((int) (fd)) % __NFDBITS) \
: "cc")
# define __FD_CLR(fd, fdsetp) \
__asm__ __volatile__ ("btrl %1,%0" \
- : "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)]) \
+ : "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \
: "r" (((int) (fd)) % __NFDBITS) \
: "cc")
# define __FD_ISSET(fd, fdsetp) \
(__extension__ \
- ({unsigned int __result; \
- __asm__ __volatile__ ("btl %1,%2 ; setcb %b0; andl $1,%0" \
+ ({register char __result; \
+ __asm__ __volatile__ ("btl %1,%2 ; setcb %b0" \
: "=q" (__result) \
: "r" (((int) (fd)) % __NFDBITS), \
- "m" (((__fd_set *) (fdsetp))[__FDELT (fd)]) \
+ "m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \
: "cc"); \
__result; }))
diff --git a/sysdeps/i386/bits/string.h b/sysdeps/i386/bits/string.h
index 254db3e7f3..2931684781 100644
--- a/sysdeps/i386/bits/string.h
+++ b/sysdeps/i386/bits/string.h
@@ -41,7 +41,7 @@
__STRING_INLINE void *
__memcpy_c (void *__dest, __const void *__src, size_t __n)
{
- switch (n)
+ switch (__n)
{
case 0:
return __dest;
@@ -102,10 +102,10 @@ __memcpy_c (void *__dest, __const void *__src, size_t __n)
"rep; movsl" \
x \
: /* no outputs */ \
- : "c" (n / 4), "D" (__dest), "S" (__src) \
+ : "c" (__n / 4), "D" (__dest), "S" (__src) \
: "cx", "di", "si", "memory");
- switch (n % 4)
+ switch (__n % 4)
{
case 0:
__COMMON_CODE ("");
@@ -232,8 +232,7 @@ __memset_gg (void *__s, char __c, size_t __n)
{
__asm__ __volatile__
("cld\n\t"
- "rep\n\t"
- "stosb"
+ "rep; stosb"
: /* no output */
: "a" (__c),"D" (__s), "c" (__n)
: "cx", "di", "memory");
@@ -518,7 +517,7 @@ strcspn (__const char *__s, __const char *__reject)
"2:\n\t"
"popl %%ebx"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject)
: "ax", "cx", "di", "cc");
return (__res - 1) - __s;
}
@@ -577,7 +576,7 @@ strspn (__const char *__s, __const char *__accept)
"2:\n\t"
"popl %%ebx"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
: "ax", "cx", "di", "cc");
return (__res - 1) - __s;
}
@@ -639,7 +638,7 @@ strpbrk (__const char *__s, __const char *__accept)
"3:\n\t"
"popl %%ebx"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
: "ax", "cx", "di", "cc");
return __res;
}
@@ -704,7 +703,7 @@ strstr (__const char *__haystack, __const char *__needle)
"2:\n\t"
"popl %%ebx"
: "=a" (__res)
- : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+ : "0" (0), "c" (0xffffffff), "S" (__haystack), "r" (__needle)
: "cx", "di", "si", "cc");
return __res;
}
diff --git a/sysdeps/i386/fpu/bits/mathinline.h b/sysdeps/i386/fpu/bits/mathinline.h
index 17f62a080f..55e9171459 100644
--- a/sysdeps/i386/fpu/bits/mathinline.h
+++ b/sysdeps/i386/fpu/bits/mathinline.h
@@ -28,43 +28,40 @@
These must not be inline functions since we have to be able to handle
all floating-point types. */
# define isgreater(x, y) \
- ({ int __result; \
+ ({ register char __result; \
__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al;" \
- "andl $0x01, %0" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
# define isgreaterequal(x, y) \
- ({ int __result; \
+ ({ register char __result; \
__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al;" \
- "andl $0x01, %0" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
# define isless(x, y) \
- ({ int __result; \
+ ({ register char __result; \
__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x45, %%ah;" \
- "setz %%al; andl $0x01, %0" \
+ "setz %%al" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
# define islessequal(x, y) \
- ({ int __result; \
+ ({ register char __result; \
__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x05, %%ah;" \
- "setz %%al; andl $0x01, %0" \
+ "setz %%al" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
# define islessgreater(x, y) \
- ({ int __result; \
+ ({ register char __result; \
__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al;" \
- "andl $0x01, %0" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
# define isunordered(x, y) \
- ({ int __result; \
- __asm__ ("fucompp; fnstsw; sahf; setp %%al; andl $0x01, %0" \
+ ({ register char __result; \
+ __asm__ ("fucompp; fnstsw; sahf; setp %%al" \
: "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
__result; })
#endif
diff --git a/sysdeps/i386/i486/atomicity.h b/sysdeps/i386/i486/atomicity.h
new file mode 100644
index 0000000000..98a2531365
--- /dev/null
+++ b/sysdeps/i386/i486/atomicity.h
@@ -0,0 +1,57 @@
+/* Low-level functions for atomitc operations. ix86 version, x >= 4.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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. */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H 1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (volatile uint32_t *mem, int val)
+{
+ register int result;
+ __asm__ __volatile__ ("lock; xaddl %0,%1"
+ : "=r" (result) : "0" (val), "m" (*mem) : "memory");
+ return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (volatile uint32_t *mem, int val)
+{
+ __asm__ __volatile__ ("lock; addl %0,%1"
+ : : "ir" (val), "m" (*mem) : "memory");
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (volatile long int *p, long int oldval, long int newval)
+{
+ char ret;
+ long int readval;
+
+ __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+ : "=q" (ret), "=m" (*p), "=a" (readval)
+ : "r" (newval), "m" (*p), "a" (oldval));
+ return ret;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index f141bd50e1..770f5c1e15 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -32,16 +32,19 @@
/* Copy N bytes of SRC to DEST. */
+#define _HAVE_STRING_ARCH_memcpy 1
#define memcpy(dest, src, n) \
(__extension__ (__builtin_constant_p (n) \
? __memcpy_c (dest, src, n) \
: __memcpy_g (dest, src, n)))
#define __memcpy_c(dest, src, n) \
- (((n) % 4 == 0) \
- ? __memcpy_by4 (dest, src, n) \
- : (((n) % 2 == 0) \
- ? __memcpy_by2 (dest, src, n) \
- : __memcpy_g (dest, src, n)))
+ ((n) == 0 \
+ ? (dest) \
+ : (((n) % 4 == 0) \
+ ? __memcpy_by4 (dest, src, n) \
+ : (((n) % 2 == 0) \
+ ? __memcpy_by2 (dest, src, n) \
+ : __memcpy_g (dest, src, n))))
__STRING_INLINE void *
__memcpy_by4 (void *__dest, __const void *__src, size_t __n)
@@ -135,6 +138,7 @@ memmove (void *__dest, __const void *__src, size_t __n)
/* Compare N bytes of S1 and S2. */
+#define _HAVE_STRING_ARCH_memcmp 1
#ifndef __PIC__
/* gcc has problems to spill registers when using PIC. */
__STRING_INLINE int
@@ -157,6 +161,7 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
/* Set N bytes of S to C. */
+#define _HAVE_STRING_ARCH_memset 1
#define memset(s, c, n) \
(__extension__ (__builtin_constant_p (c) \
? (__builtin_constant_p (n) \
@@ -166,17 +171,21 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
? __memset_gc (s, c, n) \
: __memset_gg (s, c, n))))
#define __memset_cc(s, c, n) \
- (((n) % 4 == 0) \
- ? __memset_cc_by4 (s, c, n) \
- : (((n) % 2== 0) \
- ? __memset_cc_by2 (s, c, n) \
- : __memset_cg (s, c, n)))
+ ((n) == 0 \
+ ? (s) \
+ : (((n) % 4 == 0) \
+ ? __memset_cc_by4 (s, c, n) \
+ : (((n) % 2== 0) \
+ ? __memset_cc_by2 (s, c, n) \
+ : __memset_cg (s, c, n))))
#define __memset_gc(s, c, n) \
- (((n) % 4== 0) \
- ? __memset_gc_by4 (s, c, n) \
- : (((n) % 2 == 0) \
- ? __memset_gc_by2 (s, c, n) \
- : __memset_gg (s, c, n)))
+ ((n) == 0 \
+ ? (s) \
+ : (((n) % 4== 0) \
+ ? __memset_gc_by4 (s, c, n) \
+ : (((n) % 2 == 0) \
+ ? __memset_gc_by2 (s, c, n) \
+ : __memset_gg (s, c, n))))
__STRING_INLINE void *
__memset_cc_by4 (void *__s, int __c, size_t __n)
@@ -196,7 +205,7 @@ __memset_cc_by4 (void *__s, int __c, size_t __n)
}
__STRING_INLINE void *
-__memset_cc_by2 (void *__s, char __c, size_t __n)
+__memset_cc_by2 (void *__s, int __c, size_t __n)
{
register void *__tmp = __s;
register int __dummy;
@@ -217,7 +226,7 @@ __memset_cc_by2 (void *__s, char __c, size_t __n)
}
__STRING_INLINE void *
-__memset_gc_by4 (void *__s, char __c, size_t __n)
+__memset_gc_by4 (void *__s, int __c, size_t __n)
{
register void *__tmp = __s;
register int __dummy;
@@ -238,7 +247,7 @@ __memset_gc_by4 (void *__s, char __c, size_t __n)
}
__STRING_INLINE void *
-__memset_gc_by2 (void *__s, char __c, size_t __n)
+__memset_gc_by2 (void *__s, int __c, size_t __n)
{
register void *__tmp = __s;
register int __dummy1, __dummy2;
@@ -263,7 +272,7 @@ __memset_gc_by2 (void *__s, char __c, size_t __n)
}
__STRING_INLINE void *
-__memset_cg (void *__s, char __c, size_t __n)
+__memset_cg (void *__s, int __c, size_t __n)
{
register void *__tmp = __s;
__asm__ __volatile__
@@ -279,7 +288,7 @@ __memset_cg (void *__s, char __c, size_t __n)
}
__STRING_INLINE void *
-__memset_gg (void *__s, char __c, size_t __n)
+__memset_gg (void *__s, int __c, size_t __n)
{
register void *__tmp = __s;
__asm__ __volatile__
@@ -297,6 +306,7 @@ __memset_gg (void *__s, char __c, size_t __n)
/* Search N bytes of S for C. */
+#define _HAVE_STRING_ARCH_memchr 1
__STRING_INLINE void *
memchr (__const void *__s, int __c, size_t __n)
{
@@ -318,16 +328,21 @@ memchr (__const void *__s, int __c, size_t __n)
/* Return the length of S. */
+#define _HAVE_STRING_ARCH_strlen 1
+#define strlen(str) \
+ (__extension__ (__builtin_constant_p (str) \
+ ? sizeof (str) - 1 \
+ : __strlen_g (str)))
__STRING_INLINE size_t
-strlen (__const char *__str)
+__strlen_g (__const char *__str)
{
register char __dummy;
register __const char *__tmp = __str;
__asm__ __volatile__
("1:\n\t"
- "movb (%0),%1\n\t"
+ "movb (%0),%b1\n\t"
"leal 1(%0),%0\n\t"
- "testb %1,%1\n\t"
+ "testb %b1,%b1\n\t"
"jne 1b"
: "=r" (__tmp), "=q" (__dummy)
: "0" (__str)
@@ -337,19 +352,25 @@ strlen (__const char *__str)
/* Copy SRC to DEST. */
+#define _HAVE_STRING_ARCH_strcpy 1
+#define strcpy(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? (char *) memcpy (dest, src, strlen (src) + 1) \
+ : __strcpy_g (dest, src)))
+
__STRING_INLINE char *
-strcpy (char *__dest, __const char *__src)
+__strcpy_g (char *__dest, __const char *__src)
{
register char *__tmp = __dest;
register char __dummy;
__asm__ __volatile__
(
"1:\n\t"
- "movb (%0),%2\n\t"
- "incl %0\n\t"
- "movb %2,(%1)\n\t"
- "incl %1\n\t"
- "testb %2,%2\n\t"
+ "movb (%0),%b2\n\t"
+ "leal 1(%0),%0\n\t"
+ "movb %b2,(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "testb %b2,%b2\n\t"
"jne 1b"
: "=r" (__src), "=r" (__tmp), "=q" (__dummy)
: "0" (__src), "1" (__tmp)
@@ -358,9 +379,233 @@ strcpy (char *__dest, __const char *__src)
}
+#ifdef __USE_GNU
+# define _HAVE_STRING_ARCH_stpcpy 1
+/* Copy SRC to DEST. */
+# define __stpcpy(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? (strlen (src) + 1 <= 8 \
+ ? __stpcpy_small (dest, src, strlen (src) + 1) \
+ : __stpcpy_c (dest, src, strlen (src) + 1)) \
+ : __stpcpy_g (dest, src)))
+# define __stpcpy_c(dest, src, srclen) \
+ ((srclen) % 4 == 0 \
+ ? __mempcpy_by4 (dest, src, srclen) \
+ : ((srclen) % 2 == 0 \
+ ? __mempcpy_by2 (dest, src, srclen) \
+ : __mempcpy_byn (dest, src, srclen)))
+
+/* In glibc itself we use this symbol for namespace reasons. */
+# define stpcpy(dest, src) __stpcpy (dest, src)
+
+__STRING_INLINE char *
+__stpcpy_small (char *__dest, __const char __src[], size_t __srclen)
+{
+ register char *__tmp = __dest;
+ switch (__srclen)
+ {
+ case 7:
+ *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+ case 5:
+ *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+ *((unsigned char *) __tmp) = '\0';
+ return __tmp;
+
+ case 8:
+ *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+ case 4:
+ *((unsigned int *) __tmp) = *((unsigned int *) __src);
+ return __tmp + 3;
+
+ case 6:
+ *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+ case 2:
+ *((unsigned short int *) __tmp) = *((unsigned short int *) __src);
+ return __tmp + 1;
+
+ case 3:
+ *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+ case 1:
+ *((unsigned char *) __tmp) = '\0';
+ return __tmp;
+
+ default:
+ break;
+ }
+ /* This should never happen. */
+ return NULL;
+}
+
+__STRING_INLINE char *
+__mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b"
+ : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+ : "memory", "cc");
+ return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("shrl $1,%3\n\t"
+ "jz 2f\n" /* only a word */
+ "1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b\n"
+ "2:\n\t"
+ "movw (%2),%w0\n\t"
+ "movw %w0,(%1)"
+ : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+ : "memory", "cc");
+ return __tmp + 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
+{
+ register char *__tmp = __dest;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\n\t"
+ "rep; movsl"
+ : "=D" (__tmp)
+ : "c" (__srclen), "0" (__tmp),"S" (__src)
+ : "cx", "di", "si", "memory", "cc");
+ return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__stpcpy_g (char *__dest, __const char *__src)
+{
+ register char *__tmp = __dest;
+ register char __dummy;
+ __asm__ __volatile__
+ (
+ "1:\n\t"
+ "movb (%0),%b2\n\t"
+ "leal 1(%0),%0\n\t"
+ "movb %b2,(%1)\n\t"
+ "leal 1(%1),%1\n\t"
+ "testb %b2,%b2\n\t"
+ "jne 1b"
+ : "=r" (__src), "=r" (__tmp), "=q" (__dummy)
+ : "0" (__src), "1" (__tmp)
+ : "memory", "cc");
+ return __tmp - 1;
+}
+#endif
+
+
/* Copy no more than N characters of SRC to DEST. */
+#define _HAVE_STRING_ARCH_strncpy 1
+#define strncpy(dest, src, n) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? ((strlen (src) + 1 >= ((size_t) (n)) \
+ ? (char *) memcpy (dest, src, n) \
+ : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
+ : __strncpy_gg (dest, src, n)))
+#define __strncpy_cg(dest, src, srclen, n) \
+ (((srclen) % 4 == 0) \
+ ? __strncpy_by4 (dest, src, srclen, n) \
+ : (((srclen) % 2 == 0) \
+ ? __strncpy_by2 (dest, src, srclen, n) \
+ : __strncpy_byn (dest, src, srclen, n)))
+
+__STRING_INLINE char *
+__strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b"
+ : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+ : "memory", "cc");
+ (void) memset (__tmp, '\0', __n - __srclen);
+ return __dest;
+}
+
__STRING_INLINE char *
-strncpy (char *__dest, __const char *__src, size_t __n)
+__strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register char *__tmp = __dest;
+ register int __dummy1, __dummy2;
+ __asm__ __volatile__
+ ("shrl $1,%3\n\t"
+ "jz 2f\n" /* only a word */
+ "1:\n\t"
+ "movl (%2),%0\n\t"
+ "leal 4(%2),%2\n\t"
+ "movl %0,(%1)\n\t"
+ "leal 4(%1),%1\n\t"
+ "decl %3\n\t"
+ "jnz 1b\n"
+ "2:\n\t"
+ "movw (%2),%w0\n\t"
+ "movw %w0,(%1)\n\t"
+ : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+ : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+ : "memory", "cc");
+ (void) memset (__tmp + 2, '\0', __n - __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+ register char *__tmp = __dest;
+ __asm__ __volatile__
+ ("cld\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\n\t"
+ "rep; movsl"
+ : "=D" (__tmp)
+ : "c" (__srclen), "0" (__tmp),"S" (__src)
+ : "cx", "di", "si", "memory", "cc");
+ (void) memset (__tmp, '\0', __n - __srclen);
+ return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_gg (char *__dest, __const char *__src, size_t __n)
{
register char *__tmp = __dest;
register char __dummy;
@@ -390,14 +635,35 @@ strncpy (char *__dest, __const char *__src, size_t __n)
/* Append SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strcat 1
+#define strcat(dest, src) \
+ (__extension__ (__builtin_constant_p (src) \
+ ? __strcat_c (dest, src, strlen (src) + 1) \
+ : __strcat_g (dest, src)))
+
+__STRING_INLINE char *
+__strcat_c (char *__dest, __const char __src[], size_t __srclen)
+{
+ register char *__tmp = __dest - 1;
+ __asm__ __volatile__
+ ("1:\n\t"
+ "incl %0\n\t"
+ "cmpb $0,(%0)\n\t"
+ "jne 1b\n"
+ : "=r" (__tmp)
+ : "0" (__tmp)
+ : "cc");
+ (void) memcpy (__tmp, __src, __srclen);
+ return __dest;
+}
+
__STRING_INLINE char *
-strcat (char *__dest, __const char *__src)
+__strcat_g (char *__dest, __const char *__src)
{
register char *__tmp = __dest - 1;
register char __dummy;
__asm__ __volatile__
- (
- "1:\n\t"
+ ("1:\n\t"
"incl %1\n\t"
"cmpb $0,(%1)\n\t"
"jne 1b\n"
@@ -416,16 +682,23 @@ strcat (char *__dest, __const char *__src)
/* Append no more than N characters from SRC onto DEST. */
+#define _HAVE_STRING_ARCH_strncat 1
+#define strncat(dest, src, n) \
+ (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
+ ? (strlen (src) < ((size_t) (n)) \
+ ? strcat (dest, src) \
+ : (memcpy (strchr (dest, '\0'), src, n), dest)) \
+ : __strncat_g (dest, src, n)))
+
__STRING_INLINE char *
-strncat (char *__dest, __const char *__src, size_t __n)
+__strncat_g (char *__dest, __const char __src[], size_t __n)
{
register char *__tmp = __dest - 1;
register char __dummy;
__asm__ __volatile__
- (
- "1:\n\t"
- "incl %1\n\t"
- "cmpb $0,(%1)\n\t"
+ ("1:\n\t"
+ "cmpb $0,1(%1)\n\t"
+ "leal 1(%1),%1\n\t"
"jne 1b\n"
"2:\n\t"
"decl %3\n\t"
@@ -435,7 +708,8 @@ strncat (char *__dest, __const char *__src, size_t __n)
"movb %b0,(%1)\n\t"
"leal 1(%1),%1\n\t"
"testb %b0,%b0\n\t"
- "jne 2b\n"
+ "jne 2b\n\t"
+ "decl %1\n"
"3:\n\t"
"movb $0,(%1)\n\t"
: "=q" (__dummy), "=r" (__tmp), "=r" (__src), "=r" (__n)
@@ -446,6 +720,7 @@ strncat (char *__dest, __const char *__src, size_t __n)
/* Compare S1 and S2. */
+#define _HAVE_STRING_ARCH_strcmp 1
__STRING_INLINE int
strcmp (__const char *__s1, __const char *__s2)
{
@@ -474,8 +749,16 @@ strcmp (__const char *__s1, __const char *__s2)
/* Compare N characters of S1 and S2. */
+#define _HAVE_STRING_ARCH_strncmp 1
+#define strncmp(s1, s2, n) \
+ (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
+ ? strcmp (s1, s2) \
+ : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
+ ? strcmp (s1, s2) \
+ : __strncmp_g (s1, s2, n))))
+
__STRING_INLINE int
-strncmp (__const char *__s1, __const char *__s2, size_t __n)
+__strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
{
register int __res;
__asm__ __volatile__
@@ -505,18 +788,18 @@ strncmp (__const char *__s1, __const char *__s2, size_t __n)
/* Find the first occurrence of C in S. */
+#define _HAVE_STRING_ARCH_strchr 1
#define strchr(s, c) \
(__extension__ (__builtin_constant_p (c) \
? __strchr_c (s, ((c) & 0xff) << 8) \
: __strchr_g (s, c)))
__STRING_INLINE char *
-__strchr_g (__const char *__s, int __c)
+__strchr_c (__const char *__s, int __c)
{
register char *__res;
__asm__ __volatile__
- ("movb %%al,%%ah\n"
- "1:\n\t"
+ ("1:\n\t"
"movb (%0),%%al\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
@@ -532,11 +815,12 @@ __strchr_g (__const char *__s, int __c)
}
__STRING_INLINE char *
-__strchr_c (__const char *__s, int __c)
+__strchr_g (__const char *__s, int __c)
{
register char *__res;
__asm__ __volatile__
- ("1:\n\t"
+ ("movb %%al,%%ah\n"
+ "1:\n\t"
"movb (%0),%%al\n\t"
"cmpb %%ah,%%al\n\t"
"je 2f\n\t"
@@ -553,18 +837,56 @@ __strchr_c (__const char *__s, int __c)
/* Find the last occurrence of C in S. */
+#define _HAVE_STRING_ARCH_strrchr 1
#define strrchr(s, c) \
(__extension__ (__builtin_constant_p (c) \
? __strrchr_c (s, ((c) & 0xff) << 8) \
: __strrchr_g (s, c)))
+#ifdef __i686__
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "cmovne %%esi,%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=d" (__res)
+ : "0" (1), "S" (__s),"a" (__c)
+ : "ax", "si", "cc");
+ return __res - 1;
+}
+
__STRING_INLINE char *
__strrchr_g (__const char *__s, int __c)
{
register char *__res;
__asm__ __volatile__
- ("cld\n\t"
- "movb %%al,%%ah\n"
+ ("movb %%al,%%ah\n"
+ "cld\n\t"
+ "1:\n\t"
+ "lodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "cmovne %%esi,%0\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=r" (__res)
+ : "0" (1), "S" (__s),"a" (__c)
+ : "ax", "si", "cc");
+ return __res - 1;
+}
+#else
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+ register char *__res;
+ __asm__ __volatile__
+ ("cld\n"
"1:\n\t"
"lodsb\n\t"
"cmpb %%ah,%%al\n\t"
@@ -580,11 +902,12 @@ __strrchr_g (__const char *__s, int __c)
}
__STRING_INLINE char *
-__strrchr_c (__const char *__s, int __c)
+__strrchr_g (__const char *__s, int __c)
{
register char *__res;
__asm__ __volatile__
- ("cld\n\t"
+ ("movb %%al,%%ah\n"
+ "cld\n\t"
"1:\n\t"
"lodsb\n\t"
"cmpb %%ah,%%al\n\t"
@@ -593,66 +916,140 @@ __strrchr_c (__const char *__s, int __c)
"2:\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
- : "=d" (__res)
+ : "=r" (__res)
: "0" (0), "S" (__s),"a" (__c)
: "ax", "si", "cc");
return __res;
}
+#endif
/* Return the length of the initial segment of S which
consists entirely of characters not in REJECT. */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strcspn 1
+#define strcspn(s, reject) \
+ (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
+ ? ((reject)[0] == '\0' \
+ ? strlen (s) \
+ : ((reject)[1] == '\0' \
+ ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
+ : __strcspn_cg (s, reject, strlen (reject)))) \
+ : __strcspn_g (s, reject)))
+
__STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_c1 (__const char *__s, int __reject)
{
register char *__res;
__asm__ __volatile__
- ("push %%ebx\n\t"
- "cld\n\t"
+ ("1:\n\t"
+ "movb (%0),%%al\n\t"
+ "leal 1(%0),%0\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:"
+ : "=r" (__res)
+ : "a" (__reject), "0" (__s)
+ : "ax", "cc");
+ return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
+{
+ register __const char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %%ebx,%1\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
"movl %4,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n"
+ "2:\n\t"
+ "movl %1,%%ebx"
+ : "=S" (__res), "=&m" (__mem)
+ : "c" (__reject_len), "0" (__s), "r" (__reject), "1" (__mem)
+ : "ax", "cx", "di", "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+ register __const char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %%ebx,%1\n\t"
+ "movl %5,%%edi\n\t"
+ "cld\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%ebx\n"
+ "leal -1(%%ecx),%%ebx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"movl %%ebx,%%ecx\n\t"
"repne; scasb\n\t"
"jne 1b\n"
"2:\n\t"
- "popl %%ebx"
- : "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+ "movl %1,%%ebx"
+ : "=S" (__res), "=&m" (__mem)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject), "1" (__mem)
: "ax", "cx", "di", "cc");
return (__res - 1) - __s;
}
#else
__STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
{
- register char *__res;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n"
+ "2:"
+ : "=S" (__res)
+ : "d" (__reject_len), "0" (__s), "b" (__reject)
+ : "ax", "cx", "di", "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+ register __const char *__res;
__asm__ __volatile__
("cld\n\t"
- "movl %4,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
+ "leal -1(%%ecx),%%edx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%ebx,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne; scasb\n\t"
"jne 1b\n"
"2:"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__reject), "D" (__reject)
: "ax", "cx", "dx", "di", "cc");
return (__res - 1) - __s;
}
@@ -661,57 +1058,129 @@ strcspn (__const char *__s, __const char *__reject)
/* Return the length of the initial segment of S which
consists entirely of characters in ACCEPT. */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strspn 1
+#define strspn(s, accept) \
+ (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
+ ? ((accept)[0] == '\0' \
+ ? 0 \
+ : ((accept)[1] == '\0' \
+ ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
+ : __strspn_cg (s, accept, strlen (accept)))) \
+ : __strspn_g (s, accept)))
+
__STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_c1 (__const char *__s, int __accept)
{
register char *__res;
+ /* Please note that __accept never can be '\0'. */
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("1:\n\t"
+ "movb (%0),%%al\n\t"
+ "leal 1(%0),%0\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 1b\n"
+ "2:"
+ : "=r" (__res)
+ : "a" (__accept), "0" (__s)
+ : "ax", "cc");
+ return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
+{
+ register __const char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %%ebx,%1\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "je 1b\n"
+ "2:\n\t"
+ "movl %1,%%ebx"
+ : "=S" (__res), "=m" (__mem)
+ : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+ : "ax", "cx", "di", "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+ register __const char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %%ebx,%1\n\t"
"cld\n\t"
- "movl %4,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%ebx\n"
+ "leal -1(%%ecx),%%ebx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%edx,%%edi\n\t"
"movl %%ebx,%%ecx\n\t"
"repne; scasb\n\t"
"je 1b\n"
"2:\n\t"
- "popl %%ebx"
- : "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ "movl %1,%%ebx"
+ : "=S" (__res), "=m" (__mem)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem),
+ "D" (__accept)
: "ax", "cx", "di", "cc");
return (__res - 1) - __s;
}
#else
__STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
{
- register char *__res;
+ register __const char *__res;
+ __asm__ __volatile__
+ ("cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "je 1b\n"
+ "2:"
+ : "=S" (__res)
+ : "d" (__accept_len), "0" (__s), "b" (__accept), "D" (__accept)
+ : "ax", "cx", "dx", "di", "cc");
+ return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+ register __const char *__res;
__asm__ __volatile__
("cld\n\t"
- "movl %4,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
+ "leal -1(%%ecx),%%edx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%ebx,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne; scasb\n\t"
"je 1b\n"
"2:"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept), "D" (__accept)
: "ax", "cx", "dx", "di", "cc");
return (__res - 1) - __s;
}
@@ -719,24 +1188,63 @@ strspn (__const char *__s, __const char *__accept)
/* Find the first occurrence in S of any character in ACCEPT. */
+#define _HAVE_STRING_ARCH_strpbrk 1
+#define strpbrk(s, accept) \
+ (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
+ ? ((accept)[0] == '\0' \
+ ? NULL \
+ : ((accept)[1] == '\0' \
+ ? strchr (s, (accept)[0]) \
+ : __strpbrk_cg (s, accept, strlen (accept)))) \
+ : __strpbrk_g (s, accept)))
+
#ifdef __PIC__
__STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
{
register char *__res;
+ int __mem;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("movl %%ebx,%1\n\t"
+ "movl %%ecx,%%ebx\n\t"
+ "cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n\t"
+ "decl %0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "xorl %0,%0\n"
+ "3:\n\t"
+ "movl %1,%%ebx"
+ : "=S" (__res), "=m" (__mem)
+ : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+ : "ax", "cx", "di", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+ register char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %%ebx,%1\n\t"
+ "movl %%edx,%%edi\n\t"
"cld\n\t"
- "movl %4,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%ebx\n"
+ "leal -1(%%ecx),%%ebx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%edx,%%edi\n\t"
"movl %%ebx,%%ecx\n\t"
"repne; scasb\n\t"
"jne 1b\n\t"
@@ -745,29 +1253,54 @@ strpbrk (__const char *__s, __const char *__accept)
"2:\n\t"
"xorl %0,%0\n"
"3:\n\t"
- "popl %%ebx"
- : "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ "movl %1,%%ebx"
+ : "=S" (__res), "=m" (__mem)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem)
: "ax", "cx", "di", "cc");
return __res;
}
#else
__STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
{
register char *__res;
__asm__ __volatile__
- ("cld\n\t"
- "movl %4,%%edi\n\t"
+ ("movl %%ebx,%%edi\n\t"
+ "cld\n"
+ "1:\n\t"
+ "lodsb\n\t"
+ "testb %%al,%%al\n\t"
+ "je 2f\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repne; scasb\n\t"
+ "jne 1b\n\t"
+ "decl %0\n\t"
+ "jmp 3f\n"
+ "2:\n\t"
+ "xorl %0,%0\n"
+ "3:"
+ : "=S" (__res)
+ : "d" (__accept_len), "0" (__s), "b" (__accept)
+ : "ax", "cx", "dx", "di", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+ register char *__res;
+ __asm__ __volatile__
+ ("movl %%ebx,%%edi\n\t"
+ "cld\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
+ "leal -1(%%ecx),%%edx\n"
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%ebx,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne; scasb\n\t"
"jne 1b\n\t"
@@ -777,7 +1310,7 @@ strpbrk (__const char *__s, __const char *__accept)
"xorl %0,%0\n"
"3:"
: "=S" (__res)
- : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+ : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept)
: "ax", "cx", "dx", "di", "cc");
return __res;
}
@@ -785,63 +1318,138 @@ strpbrk (__const char *__s, __const char *__accept)
/* Find the first occurrence of NEEDLE in HAYSTACK. */
+#define _HAVE_STRING_ARCH_strstr 1
#ifdef __PIC__
+/* XXX GCC has problems to spill the registers. */
+# define strstr(haystack, needle) \
+ (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
+ ? ((needle)[0] == '\0' \
+ ? haystack \
+ : ((needle)[1] == '\0' \
+ ? strchr (haystack, (needle)[0]) \
+ : strstr (haystack, needle))) \
+ : strstr (haystack, needle)))
+
+# if 0
+/* Please note that this function need not handle NEEDLEs with a
+ length shorter than two. */
__STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+ size_t __needle_len)
{
register char *__res;
+ int __mem;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
- "cld\n\t" \
- "movl %4,%%edi\n\t"
+ ("movl %%ebx,%1\n\t"
+ "movl %%ecx,%%ebx\n"
+ "cld\n" \
+ "1:\n\t"
+ "movl %%edx,%%edi\n\t"
+ "movl %%esi,%%eax\n\t"
+ "movl %%ebx,%%ecx\n\t"
+ "repe; cmpsb\n\t"
+ "je 2f\n\t"
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n"
+ "2:\n\t"
+ "movl %1,%%ebx"
+ : "=a" (__res), "=m" (__mem)
+ : "c" (__needle_len), "S" (__haystack), "d" (__needle), "1" (__mem)
+ : "cx", "di", "si", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+ register char *__res;
+ int __mem;
+ __asm__ __volatile__
+ ("movl %2,%%edi\n\t"
+ "cld\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
+ "movl %%ebx,%1\n\t"
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%ebx\n"
"1:\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%edx,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%ebx,%%ecx\n\t"
"repe; cmpsb\n\t"
"je 2f\n\t" /* also works for empty string, see above */
- "xchgl %%eax,%%esi\n\t"
- "incl %%esi\n\t"
- "cmpb $0,-1(%%eax)\n\t"
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
"jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
+ "xorl %%eax,%%eax\n"
"2:\n\t"
- "popl %%ebx"
- : "=a" (__res)
- : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+ "movl %1,%%ebx"
+ : "=a" (__res), "=&m" (__mem)
+ : "0" (0), "c" (0xffffffff), "S" (__haystack), "d" (__needle), "1" (__mem)
: "cx", "di", "si", "cc");
return __res;
}
+# endif
#else
+# define strstr(haystack, needle) \
+ (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
+ ? ((needle)[0] == '\0' \
+ ? haystack \
+ : ((needle)[1] == '\0' \
+ ? strchr (haystack, (needle)[0]) \
+ : __strstr_cg (haystack, needle, strlen (needle)))) \
+ : __strstr_g (haystack, needle)))
+
__STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+ size_t __needle_len)
{
register char *__res;
__asm__ __volatile__
- ("cld\n\t" \
- "movl %4,%%edi\n\t"
+ ("cld\n" \
+ "1:\n\t"
+ "movl %%ebx,%%edi\n\t"
+ "movl %%esi,%%eax\n\t"
+ "movl %%edx,%%ecx\n\t"
+ "repe; cmpsb\n\t"
+ "je 2f\n\t"
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n"
+ "2:"
+ : "=a" (__res)
+ : "d" (__needle_len), "S" (__haystack), "b" (__needle)
+ : "cx", "dx", "di", "si", "cc");
+ return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+ register char *__res;
+ __asm__ __volatile__
+ ("movl %1,%%edi\n\t"
+ "cld\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx\n"
"1:\n\t"
- "movl %4,%%edi\n\t"
+ "movl %%ebx,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%edx,%%ecx\n\t"
"repe; cmpsb\n\t"
"je 2f\n\t" /* also works for empty string, see above */
- "xchgl %%eax,%%esi\n\t"
- "incl %%esi\n\t"
- "cmpb $0,-1(%%eax)\n\t"
+ "cmpb $0,-1(%%esi)\n\t"
+ "leal 1(%%eax),%%esi\n\t"
"jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
+ "xorl %%eax,%%eax\n"
"2:"
: "=a" (__res)
- : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+ : "0" (0), "c" (0xffffffff), "S" (__haystack), "b" (__needle)
: "cx", "dx", "di", "si", "cc");
return __res;
}
diff --git a/sysdeps/i386/machine-gmon.h b/sysdeps/i386/machine-gmon.h
index 496a57eb84..e1155989d4 100644
--- a/sysdeps/i386/machine-gmon.h
+++ b/sysdeps/i386/machine-gmon.h
@@ -1,4 +1,4 @@
-/* i386-specific implemetation of profiling support.
+/* i386-specific implementation of profiling support.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -36,6 +36,6 @@ void mcount_internal (u_long frompc, u_long selfpc);
void mcount_internal (u_long frompc, u_long selfpc)
-/* Define MCOUNT as empty since we have a the implementation in another
+/* Define MCOUNT as empty since we have the implementation in another
file. */
#define MCOUNT
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
index 454c7385af..0cb6578df6 100644
--- a/sysdeps/i386/memset.c
+++ b/sysdeps/i386/memset.c
@@ -23,6 +23,8 @@
#ifdef __GNUC__
+#undef memset
+
void *
memset (void *dstpp, int c, size_t len)
{
diff --git a/sysdeps/mach/hurd/profil.c b/sysdeps/mach/hurd/profil.c
index d76cc25a3c..365b11bed3 100644
--- a/sysdeps/mach/hurd/profil.c
+++ b/sysdeps/mach/hurd/profil.c
@@ -103,7 +103,7 @@ __profile_frequency (void)
}
int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
{
error_t err;
@@ -132,6 +132,7 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
return err ? __hurd_fail (err) : 0;
}
+weak_alias (__profil, profil)
/* Fetch PC samples. This function must be very careful not to depend
on Hurd threadvar variables. We arrange that by using a special
diff --git a/sysdeps/posix/defs.c b/sysdeps/posix/defs.c
index bc0d34bf15..b25b9b0fea 100644
--- a/sysdeps/posix/defs.c
+++ b/sysdeps/posix/defs.c
@@ -63,7 +63,7 @@ FILE *__stdio_head = &stdstreams[0];
to cause _cleanup to be linked in. */
void
-_cleanup ()
+_cleanup (void)
{
__fcloseall ();
}
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index fa3cf98c74..865bd3fa6a 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -326,7 +326,7 @@ __getcwd (buf, size)
{
size_t namlen = _D_EXACT_NAMLEN (d);
- if ((size_t) (pathp - path) < namlen)
+ if ((size_t) (pathp - path) <= namlen)
{
if (buf != NULL)
{
diff --git a/sysdeps/posix/pipestream.c b/sysdeps/posix/pipestream.c
index 6041f830e7..31348b8976 100644
--- a/sysdeps/posix/pipestream.c
+++ b/sysdeps/posix/pipestream.c
@@ -41,8 +41,8 @@ struct child
These all simply call the corresponding
original function with the original cookie. */
-#define FUNC(type, name, args) \
- static type __CONCAT(child_,name) args __CONCAT(name,decl) \
+#define FUNC(type, name, proto, args) \
+ static type __CONCAT(child_,name) proto \
{ \
struct child *c = (struct child *) cookie; \
{ \
@@ -51,16 +51,12 @@ struct child
} \
}
-#define readdecl void *cookie; register char *buf; register size_t n;
-FUNC (int, read, (cookie, buf, n))
-#define writedecl void *cookie; register const char *buf; register size_t n;
-FUNC (int, write, (cookie, buf, n))
-#define seekdecl void *cookie; fpos_t *pos; int whence;
-FUNC (int, seek, (cookie, pos, whence))
-#define closedecl void *cookie;
-FUNC (int, close, (cookie))
-#define filenodecl void *cookie;
-FUNC (int, fileno, (cookie))
+FUNC (int, read, (void *cookie, char *buf, size_t n), (cookie, buf, n))
+FUNC (int, write, (void *cookie, const char *buf, size_t n), (cookie, buf, n))
+FUNC (int, seek, (void *cookie, fpos_t *pos, int whence),
+ (cookie, pos, whence))
+FUNC (int, close, (void *cookie), (cookie))
+FUNC (int, fileno, (void *cookie), (cookie))
static const __io_functions child_funcs
= { child_read, child_write, child_seek, child_close, child_fileno };
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index a51baf3713..734111efbb 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -60,7 +60,7 @@ profil_count (void *pc)
disable profiling. Returns zero on success, -1 on error. */
int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
{
static struct sigaction act, oact;
static struct itimerval timer, otimer;
@@ -103,5 +103,6 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
timer.it_interval = timer.it_value;
return setitimer (ITIMER_PROF, &timer, &otimer);
}
+weak_alias (__profil, profil)
#endif
diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c
index e6d8de45ad..5933be6835 100644
--- a/sysdeps/posix/sleep.c
+++ b/sysdeps/posix/sleep.c
@@ -25,8 +25,7 @@
/* SIGALRM signal handler for `sleep'. This does nothing but return,
but SIG_IGN isn't supposed to break `pause'. */
static void
-sleep_handler (sig)
- int sig;
+sleep_handler (int sig)
{
return;
}
diff --git a/sysdeps/posix/stdio_init.c b/sysdeps/posix/stdio_init.c
index 6847d1fdc9..4dc7028133 100644
--- a/sysdeps/posix/stdio_init.c
+++ b/sysdeps/posix/stdio_init.c
@@ -26,8 +26,7 @@
If no buffer is allocated, but the bufsize is set,
the bufsize will be used to allocate the buffer. */
void
-__stdio_init_stream (stream)
- FILE *stream;
+__stdio_init_stream (FILE *stream)
{
const int fd = (int) stream->__cookie;
struct stat statb;
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 0a50956640..3e8f22b573 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -11,3 +11,21 @@ tests += test-arith test-arithf
LDLIBS-test-arith = libm
LDLIBS-test-arithf = libm
endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += ppc-mcount
+endif
+
+# On PPC, -fpic works until the GOT contains 2^15 bytes, and possibly
+# more depending on how clever the linker is. Each GOT entry takes 4 bytes,
+# so that's at least 8192 entries. Since libc only uses about 1200 entries,
+# we want to use -fpic, because this generates fewer relocs.
+ifeq (yes,$(build-shared))
+CFLAGS-.os = -fpic -fno-common
+endif
+
+# The initfini generation code doesn't work in the presence of -fPIC, so
+# we use -fpic instead which is much better.
+ifeq ($(subdir),csu)
+CFLAGS-initfini.s = -g0 -fpic
+endif
diff --git a/sysdeps/powerpc/add_n.S b/sysdeps/powerpc/add_n.S
new file mode 100644
index 0000000000..2bd59ae4a7
--- /dev/null
+++ b/sysdeps/powerpc/add_n.S
@@ -0,0 +1,68 @@
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(__mpn_add_n,3,0)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ li %r10,0
+ mtctr %r7
+ bt 31,2f
+
+/* Clear the carry. */
+ addic %r0,%r0,0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ addc %r6,%r6,%r7
+ stw %r6,0(%r3)
+ beq 1f
+
+/* The loop. */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). */
+0: lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ adde %r8,%r9,%r8
+ stw %r8,4(%r3)
+ adde %r6,%r6,%r7
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the carry. */
+1: addze %r3,%r10
+ blr
+END(__mpn_add_n)
diff --git a/sysdeps/powerpc/add_n.s b/sysdeps/powerpc/add_n.s
deleted file mode 100644
index 609f0a502a..0000000000
--- a/sysdeps/powerpc/add_n.s
+++ /dev/null
@@ -1,68 +0,0 @@
- # Add two limb vectors of equal, non-zero length for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- # mp_size_t size)
- # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601. Almost every other
- # possible 2-unrolled inner loop will not be. Also, watch out for the
- # alignment...
-
- .align 3
- .globl __mpn_add_n
- .type __mpn_add_n,@function
-__mpn_add_n:
- # Set up for loop below.
- mtcrf 0x01,%r6
- srwi. %r7,%r6,1
- li %r10,0
- mtctr %r7
- bt 31,2f
-
- # Clear the carry.
- addic %r0,%r0,0
- # Adjust pointers for loop.
- addi %r3,%r3,-4
- addi %r4,%r4,-4
- addi %r5,%r5,-4
- b 0f
-
-2: lwz %r7,0(%r5)
- lwz %r6,0(%r4)
- addc %r6,%r6,%r7
- stw %r6,0(%r3)
- beq 1f
-
- # The loop.
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601).
-0: lwz %r9,4(%r4)
- lwz %r8,4(%r5)
- lwzu %r6,8(%r4)
- lwzu %r7,8(%r5)
- adde %r8,%r9,%r8
- stw %r8,4(%r3)
- adde %r6,%r6,%r7
- stwu %r6,8(%r3)
- bdnz 0b
- # return the carry
-1: addze %r3,%r10
- blr
diff --git a/sysdeps/powerpc/addmul_1.S b/sysdeps/powerpc/addmul_1.S
new file mode 100644
index 0000000000..dc762fcc43
--- /dev/null
+++ b/sysdeps/powerpc/addmul_1.S
@@ -0,0 +1,49 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res+s1*s2 and put result back in res; return carry. */
+ENTRY(__mpn_addmul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ addc %r8,%r7,%r9
+ addi %r3,%r3,-4 /* adjust res_ptr */
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ addc %r8,%r7,%r9
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(__mpn_addmul_1)
diff --git a/sysdeps/powerpc/addmul_1.s b/sysdeps/powerpc/addmul_1.s
deleted file mode 100644
index cf8fd2a555..0000000000
--- a/sysdeps/powerpc/addmul_1.s
+++ /dev/null
@@ -1,50 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- # mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res+s1*s2 and put result back in res; return carry.
-
- .align 2
- .globl __mpn_addmul_1
- .type __mpn_addmul_1,@function
-__mpn_addmul_1:
- mtctr %r5
-
- lwz %r0,0(%r4)
- mullw %r7,%r0,%r6
- mulhwu %r10,%r0,%r6
- lwz %r9,0(%r3)
- addc %r8,%r7,%r9
- addi %r3,%r3,-4 # adjust res_ptr
- bdz Lend
-
-Loop: lwzu %r0,4(%r4)
- stwu %r8,4(%r3)
- mullw %r8,%r0,%r6
- adde %r7,%r8,%r10
- mulhwu %r10,%r0,%r6
- lwz %r9,4(%r3)
- addze %r10,%r10
- addc %r8,%r7,%r9
- bdnz Loop
-
-Lend: stw %r8,4(%r3)
- addze %r3,%r10
- blr
diff --git a/sysdeps/powerpc/bsd-_setjmp.S b/sysdeps/powerpc/bsd-_setjmp.S
index ffd90d5bd2..ef31f841c4 100644
--- a/sysdeps/powerpc/bsd-_setjmp.S
+++ b/sysdeps/powerpc/bsd-_setjmp.S
@@ -25,9 +25,5 @@
ENTRY (_setjmp)
li %r4,0 /* Set second argument to 0. */
-#ifdef PIC
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+ b JUMPTARGET(__sigsetjmp)
END (_setjmp)
diff --git a/sysdeps/powerpc/bsd-setjmp.S b/sysdeps/powerpc/bsd-setjmp.S
index f02d7815ed..d26b3fc93e 100644
--- a/sysdeps/powerpc/bsd-setjmp.S
+++ b/sysdeps/powerpc/bsd-setjmp.S
@@ -25,11 +25,7 @@
ENTRY (__setjmp)
li %r4,1 /* Set second argument to 1. */
-#ifdef PIC
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+ b JUMPTARGET(__sigsetjmp)
END (__setjmp)
.globl setjmp
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 917e4f7970..771b711a14 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -149,33 +149,34 @@ elf_machine_load_address (void)
#define elf_machine_relplt elf_machine_rela
/* This code is used in dl-runtime.c to call the `fixup' function
- and then redirect to the address it returns. It is called
- from code built in the PLT by elf_machine_runtime_setup. */
+ and then redirect to the address it returns. It is called
+ from code built in the PLT by elf_machine_runtime_setup. */
#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
.section \".text\"
.align 2
.globl _dl_runtime_resolve
.type _dl_runtime_resolve,@function
_dl_runtime_resolve:
- # We need to save the registers used to pass parameters.
- # We build a stack frame to put them in.
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
stwu 1,-48(1)
- mflr 0
+ stw 0,12(1)
stw 3,16(1)
stw 4,20(1)
- stw 0,52(1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+ mr 3,12
stw 5,24(1)
- # We also need to save some of the condition register fields.
- mfcr 0
+ mr 4,11
stw 6,28(1)
+ mflr 0
+ # We also need to save some of the condition register fields.
stw 7,32(1)
+ stw 0,52(1)
stw 8,36(1)
+ mfcr 0
stw 9,40(1)
stw 10,44(1)
- stw 0,12(1)
- # The code that calls this has put parameters for `fixup' in r12 and r11.
- mr 3,12
- mr 4,11
+ stw 0,8(1)
bl fixup@local
# 'fixup' returns the address we want to branch to.
mtctr 3
@@ -184,20 +185,21 @@ _dl_runtime_resolve:
lwz 10,44(1)
lwz 9,40(1)
mtlr 0
- lwz 0,12(1)
lwz 8,36(1)
+ lwz 0,8(1)
lwz 7,32(1)
lwz 6,28(1)
mtcrf 0xFF,0
lwz 5,24(1)
lwz 4,20(1)
lwz 3,16(1)
+ lwz 0,12(1)
# ...unwind the stack frame, and jump to the PLT entry we updated.
addi 1,1,48
bctr
0:
.size _dl_runtime_resolve,0b-_dl_runtime_resolve
- # undo '.section text'.
+ # Undo '.section text'.
.previous
");
@@ -213,20 +215,20 @@ asm ("\
.type _start,@function
_start:
# We start with the following on the stack, from top:
- # argc (4 bytes)
- # arguments for program (terminated by NULL)
- # environment variables (terminated by NULL)
- # arguments for the program loader
+ # argc (4 bytes);
+ # arguments for program (terminated by NULL);
+ # environment variables (terminated by NULL);
+ # arguments for the program loader.
# FIXME: perhaps this should do the same trick as elf/start.c?
# Call _dl_start with one parameter pointing at argc
- mr 3,1
+ mr 3,1
# (we have to frob the stack pointer a bit to allow room for
# _dl_start to save the link register)
- li 4,0
+ li 4,0
addi 1,1,-16
- stw 4,0(1)
- bl _dl_start@local
+ stw 4,0(1)
+ bl _dl_start@local
# Now, we do our main work of calling initialisation procedures.
# The ELF ABI doesn't say anything about parameters for these,
@@ -234,70 +236,72 @@ _start:
# Changing these is strongly discouraged (not least because argc is
# passed by value!).
- # put our GOT pointer in r31
- bl _GLOBAL_OFFSET_TABLE_-4@local
+ # Put our GOT pointer in r31,
+ bl _GLOBAL_OFFSET_TABLE_-4@local
mflr 31
- # the address of _start in r30
- mr 30,3
- # &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28
- lwz 28,_dl_default_scope@got(31)
- lwz 29,_dl_argc@got(31)
- lwz 27,_dl_argv@got(31)
+ # the address of _start in r30,
+ mr 30,3
+ # &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28.
+ lwz 28,_dl_default_scope@got(31)
+ lwz 29,_dl_argc@got(31)
+ lwz 27,_dl_argv@got(31)
0:
- # call initfunc = _dl_init_next(_dl_default_scope[2])
- lwz 3,8(28)
- bl _dl_init_next@plt
- # if initfunc is NULL, we exit the loop
- mr. 0,3
- beq 1f
+ # Set initfunc = _dl_init_next(_dl_default_scope[2])
+ lwz 3,8(28)
+ bl _dl_init_next@plt
+ # If initfunc is NULL, we exit the loop; otherwise,
+ cmpwi 3,0
+ beq 1f
# call initfunc(_dl_argc, _dl_argv, _dl_argv+_dl_argc+1)
- mtlr 0
- lwz 3,0(29)
- lwz 4,0(27)
+ mtlr 3
+ lwz 3,0(29)
+ lwz 4,0(27)
slwi 5,3,2
- add 5,4,5
+ add 5,4,5
addi 5,5,4
blrl
# and loop.
- b 0b
+ b 0b
1:
# Now, to conform to the ELF ABI, we have to:
- # pass argv (actually _dl_argv) in r4
- lwz 4,0(27)
- # pass argc (actually _dl_argc) in r3
- lwz 3,0(29)
- # pass envp (actually _dl_argv+_dl_argc+1) in r5
+ # Pass argc (actually _dl_argc) in r3;
+ lwz 3,0(29)
+ # pass argv (actually _dl_argv) in r4;
+ lwz 4,0(27)
+ # pass envp (actually _dl_argv+_dl_argc+1) in r5;
slwi 5,3,2
- add 5,4,5
- addi 5,5,4
- # pass the auxilary vector in r6. This is passed just after _envp.
- addi 6,5,-4
+ add 6,4,5
+ addi 5,6,4
+ # pass the auxilary vector in r6. This is passed to us just after _envp.
2: lwzu 0,4(6)
- cmpwi 1,0,0
- bne 2b
+ cmpwi 0,0,0
+ bne 2b
addi 6,6,4
- # pass a termination function pointer (in this case _dl_fini) in r7
- lwz 7,_dl_fini@got(31)
- # now, call the start function in r30...
+ # Pass a termination function pointer (in this case _dl_fini) in r7.
+ lwz 7,_dl_fini@got(31)
+ # Now, call the start function in r30...
mtctr 30
- # pass the stack pointer in r1 (so far so good), pointing to a NULL value
- # (this lets our startup code distinguish between a program linked statically,
+ lwz 26,_dl_starting_up@got(31)
+ # Pass the stack pointer in r1 (so far so good), pointing to a NULL value.
+ # (This lets our startup code distinguish between a program linked statically,
# which linux will call with argc on top of the stack which will hopefully
# never be zero, and a dynamically linked program which will always have
# a NULL on the top of the stack).
# Take the opportunity to clear LR, so anyone who accidentally returns
- # from _start gets SEGV.
- li 0,0
- stw 0,0(1)
- mtlr 0
- # and also clear _dl_starting_up
- lwz 26,_dl_starting_up@got(31)
- stw 0,0(26)
- # go do it!
+ # from _start gets SEGV. Also clear the next few words of the stack.
+ li 31,0
+ stw 31,0(1)
+ mtlr 31
+ stw 31,4(1)
+ stw 31,8(1)
+ stw 31,12(1)
+ # Clear _dl_starting_up.
+ stw 31,0(26)
+ # Go do it!
bctr
0:
.size _start,0b-_start
- # undo '.section text'.
+ # Undo '.section text'.
.previous
");
@@ -346,7 +350,7 @@ static ElfW(Addr) _dl_preferred_address = 1
/* We require the address of the PLT entry returned from fixup, not
the first word of the PLT entry. */
-#define ELF_FIXUP_RETURN_VALUE(map, result) (&(result))
+#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
@@ -396,7 +400,7 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
{
if (map->l_info[DT_JMPREL])
{
- int i;
+ Elf32_Word i;
/* Fill in the PLT. Its initial contents are directed to a
function earlier in the PLT which arranges for the dynamic
linker to be called back. */
@@ -516,10 +520,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
{
#ifndef RTLD_BOOTSTRAP
const Elf32_Sym *const refsym = sym;
+ extern char **_dl_argv;
#endif
Elf32_Word loadbase, finaladdr;
const int rinfo = ELF32_R_TYPE (reloc->r_info);
- extern char **_dl_argv;
if (rinfo == R_PPC_NONE)
return;
@@ -551,9 +555,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+ reloc->r_addend);
}
- /* This is an if/else if chain because GCC 2.7.2.[012] turns case
- statements into non-PIC table lookups. When a later version
- comes out that fixes this, this should be changed. */
+ /* This is still an if/else if chain because GCC uses the GOT to find
+ the table for table-based switch statements, and we haven't set it
+ up yet. */
if (rinfo == R_PPC_UADDR32 ||
rinfo == R_PPC_GLOB_DAT ||
rinfo == R_PPC_ADDR32 ||
@@ -561,6 +565,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
{
*reloc_addr = finaladdr;
}
+#ifndef RTLD_BOOTSTRAP
else if (rinfo == R_PPC_ADDR16_LO)
{
*(Elf32_Half*) reloc_addr = finaladdr;
@@ -573,7 +578,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
{
*(Elf32_Half*) reloc_addr = (finaladdr + 0x8000) >> 16;
}
-#ifndef RTLD_BOOTSTRAP
else if (rinfo == R_PPC_REL24)
{
Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
@@ -693,12 +697,14 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
#endif
}
+#ifndef RTLD_BOOTSTRAP
if (rinfo == R_PPC_ADDR16_LO ||
rinfo == R_PPC_ADDR16_HI ||
rinfo == R_PPC_ADDR16_HA ||
rinfo == R_PPC_REL24 ||
rinfo == R_PPC_ADDR24)
MODIFIED_CODE_NOQUEUE (reloc_addr);
+#endif
}
#define ELF_MACHINE_NO_REL 1
diff --git a/sysdeps/powerpc/lshift.S b/sysdeps/powerpc/lshift.S
new file mode 100644
index 0000000000..b1487a1c17
--- /dev/null
+++ b/sysdeps/powerpc/lshift.S
@@ -0,0 +1,123 @@
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN(__mpn_lshift,3,0)
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+0: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz L(end2)
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz 0b
+
+L(end1):slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr %r9
+ bltl- %cr0,L(boom) # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+L(end2):slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr %r5; \
+0: lwzu %r10,-4(%r4); \
+ slwi %r9,%r11,n; \
+ inslwi %r9,%r10,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdz- L(end2); \
+ lwzu %r11,-4(%r4); \
+ slwi %r9,%r10,n; \
+ inslwi %r9,%r11,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdnz 0b; \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END(__mpn_lshift)
diff --git a/sysdeps/powerpc/lshift.s b/sysdeps/powerpc/lshift.s
deleted file mode 100644
index 9612a3dbec..0000000000
--- a/sysdeps/powerpc/lshift.s
+++ /dev/null
@@ -1,479 +0,0 @@
- # Shift a limb left, low level routine.
- # Copyright (C) 1996, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
- # unsigned int cnt)
-
- .align 3
- .globl __mpn_lshift
- .type __mpn_lshift,@function
-__mpn_lshift:
- mtctr %r5 # copy size into CTR
- cmplwi %cr0,%r5,16 # is size < 16
- slwi %r0,%r5,2
- add %r7,%r3,%r0 # make r7 point at end of res
- add %r4,%r4,%r0 # make r4 point at end of s1
- lwzu %r11,-4(%r4) # load first s1 limb
- subfic %r8,%r6,32
- srw %r3,%r11,%r8 # compute function return value
- bge %cr0,Lbig # branch if size >= 16
-
- bdz Lend1
-
-Loop: lwzu %r10,-4(%r4)
- slw %r9,%r11,%r6
- srw %r12,%r10,%r8
- or %r9,%r9,%r12
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slw %r9,%r10,%r6
- srw %r12,%r11,%r8
- or %r9,%r9,%r12
- stwu %r9,-4(%r7)
- bdnz Loop
- b Lend1
-
- # Guaranteed not to succeed.
-LBoom: tweq %r0,%r0
-
- # We imitate a case statement, by using (yuk!) fixed-length code chunks,
- # of size 4*12 bytes. We have to do this (or something) to make this PIC.
-Lbig: mflr %r9
- bltl %cr0,LBoom # Never taken, only used to set LR.
- slwi %r10,%r6,4
- mflr %r12
- add %r10,%r12,%r10
- slwi %r8,%r6,5
- add %r10,%r8,%r10
- mtctr %r10
- addi %r5,%r5,-1
- mtlr %r9
- bctr
-
-Lend1: slw %r0,%r11,%r6
- stw %r0,-4(%r7)
- blr
-
- mtctr %r5
-Loop1: lwzu %r10,-4(%r4)
- slwi %r9,%r11,1
- inslwi %r9,%r10,1,31
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,1
- inslwi %r9,%r11,1,31
- stwu %r9,-4(%r7)
- bdnz Loop1
- b Lend1
-
- mtctr %r5
-Loop2: lwzu %r10,-4(%r4)
- slwi %r9,%r11,2
- inslwi %r9,%r10,2,30
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,2
- inslwi %r9,%r11,2,30
- stwu %r9,-4(%r7)
- bdnz Loop2
- b Lend1
-
- mtctr %r5
-Loop3: lwzu %r10,-4(%r4)
- slwi %r9,%r11,3
- inslwi %r9,%r10,3,29
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,3
- inslwi %r9,%r11,3,29
- stwu %r9,-4(%r7)
- bdnz Loop3
- b Lend1
-
- mtctr %r5
-Loop4: lwzu %r10,-4(%r4)
- slwi %r9,%r11,4
- inslwi %r9,%r10,4,28
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,4
- inslwi %r9,%r11,4,28
- stwu %r9,-4(%r7)
- bdnz Loop4
- b Lend1
-
- mtctr %r5
-Loop5: lwzu %r10,-4(%r4)
- slwi %r9,%r11,5
- inslwi %r9,%r10,5,27
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,5
- inslwi %r9,%r11,5,27
- stwu %r9,-4(%r7)
- bdnz Loop5
- b Lend1
-
- mtctr %r5
-Loop6: lwzu %r10,-4(%r4)
- slwi %r9,%r11,6
- inslwi %r9,%r10,6,26
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,6
- inslwi %r9,%r11,6,26
- stwu %r9,-4(%r7)
- bdnz Loop6
- b Lend1
-
- mtctr %r5
-Loop7: lwzu %r10,-4(%r4)
- slwi %r9,%r11,7
- inslwi %r9,%r10,7,25
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,7
- inslwi %r9,%r11,7,25
- stwu %r9,-4(%r7)
- bdnz Loop7
- b Lend1
-
- mtctr %r5
-Loop8: lwzu %r10,-4(%r4)
- slwi %r9,%r11,8
- inslwi %r9,%r10,8,24
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,8
- inslwi %r9,%r11,8,24
- stwu %r9,-4(%r7)
- bdnz Loop8
- b Lend1
-
- mtctr %r5
-Loop9: lwzu %r10,-4(%r4)
- slwi %r9,%r11,9
- inslwi %r9,%r10,9,23
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,9
- inslwi %r9,%r11,9,23
- stwu %r9,-4(%r7)
- bdnz Loop9
- b Lend1
-
- mtctr %r5
-Loop10: lwzu %r10,-4(%r4)
- slwi %r9,%r11,10
- inslwi %r9,%r10,10,22
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,10
- inslwi %r9,%r11,10,22
- stwu %r9,-4(%r7)
- bdnz Loop10
- b Lend1
-
- mtctr %r5
-Loop11: lwzu %r10,-4(%r4)
- slwi %r9,%r11,11
- inslwi %r9,%r10,11,21
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,11
- inslwi %r9,%r11,11,21
- stwu %r9,-4(%r7)
- bdnz Loop11
- b Lend1
-
- mtctr %r5
-Loop12: lwzu %r10,-4(%r4)
- slwi %r9,%r11,12
- inslwi %r9,%r10,12,20
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,12
- inslwi %r9,%r11,12,20
- stwu %r9,-4(%r7)
- bdnz Loop12
- b Lend1
-
- mtctr %r5
-Loop13: lwzu %r10,-4(%r4)
- slwi %r9,%r11,13
- inslwi %r9,%r10,13,19
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,13
- inslwi %r9,%r11,13,19
- stwu %r9,-4(%r7)
- bdnz Loop13
- b Lend1
-
- mtctr %r5
-Loop14: lwzu %r10,-4(%r4)
- slwi %r9,%r11,14
- inslwi %r9,%r10,14,18
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,14
- inslwi %r9,%r11,14,18
- stwu %r9,-4(%r7)
- bdnz Loop14
- b Lend1
-
- mtctr %r5
-Loop15: lwzu %r10,-4(%r4)
- slwi %r9,%r11,15
- inslwi %r9,%r10,15,17
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,15
- inslwi %r9,%r11,15,17
- stwu %r9,-4(%r7)
- bdnz Loop15
- b Lend1
-
- mtctr %r5
-Loop16: lwzu %r10,-4(%r4)
- slwi %r9,%r11,16
- inslwi %r9,%r10,16,16
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,16
- inslwi %r9,%r11,16,16
- stwu %r9,-4(%r7)
- bdnz Loop16
- b Lend1
-
- mtctr %r5
-Loop17: lwzu %r10,-4(%r4)
- slwi %r9,%r11,17
- inslwi %r9,%r10,17,15
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,17
- inslwi %r9,%r11,17,15
- stwu %r9,-4(%r7)
- bdnz Loop17
- b Lend1
-
- mtctr %r5
-Loop18: lwzu %r10,-4(%r4)
- slwi %r9,%r11,18
- inslwi %r9,%r10,18,14
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,18
- inslwi %r9,%r11,18,14
- stwu %r9,-4(%r7)
- bdnz Loop18
- b Lend1
-
- mtctr %r5
-Loop19: lwzu %r10,-4(%r4)
- slwi %r9,%r11,19
- inslwi %r9,%r10,19,13
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,19
- inslwi %r9,%r11,19,13
- stwu %r9,-4(%r7)
- bdnz Loop19
- b Lend1
-
- mtctr %r5
-Loop20: lwzu %r10,-4(%r4)
- slwi %r9,%r11,20
- inslwi %r9,%r10,20,12
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,20
- inslwi %r9,%r11,20,12
- stwu %r9,-4(%r7)
- bdnz Loop20
- b Lend1
-
- mtctr %r5
-Loop21: lwzu %r10,-4(%r4)
- slwi %r9,%r11,21
- inslwi %r9,%r10,21,11
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,21
- inslwi %r9,%r11,21,11
- stwu %r9,-4(%r7)
- bdnz Loop21
- b Lend1
-
- mtctr %r5
-Loop22: lwzu %r10,-4(%r4)
- slwi %r9,%r11,22
- inslwi %r9,%r10,22,10
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,22
- inslwi %r9,%r11,22,10
- stwu %r9,-4(%r7)
- bdnz Loop22
- b Lend1
-
- mtctr %r5
-Loop23: lwzu %r10,-4(%r4)
- slwi %r9,%r11,23
- inslwi %r9,%r10,23,9
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,23
- inslwi %r9,%r11,23,9
- stwu %r9,-4(%r7)
- bdnz Loop23
- b Lend1
-
- mtctr %r5
-Loop24: lwzu %r10,-4(%r4)
- slwi %r9,%r11,24
- inslwi %r9,%r10,24,8
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,24
- inslwi %r9,%r11,24,8
- stwu %r9,-4(%r7)
- bdnz Loop24
- b Lend1
-
- mtctr %r5
-Loop25: lwzu %r10,-4(%r4)
- slwi %r9,%r11,25
- inslwi %r9,%r10,25,7
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,25
- inslwi %r9,%r11,25,7
- stwu %r9,-4(%r7)
- bdnz Loop25
- b Lend1
-
- mtctr %r5
-Loop26: lwzu %r10,-4(%r4)
- slwi %r9,%r11,26
- inslwi %r9,%r10,26,6
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,26
- inslwi %r9,%r11,26,6
- stwu %r9,-4(%r7)
- bdnz Loop26
- b Lend1
-
- mtctr %r5
-Loop27: lwzu %r10,-4(%r4)
- slwi %r9,%r11,27
- inslwi %r9,%r10,27,5
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,27
- inslwi %r9,%r11,27,5
- stwu %r9,-4(%r7)
- bdnz Loop27
- b Lend1
-
- mtctr %r5
-Loop28: lwzu %r10,-4(%r4)
- slwi %r9,%r11,28
- inslwi %r9,%r10,28,4
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,28
- inslwi %r9,%r11,28,4
- stwu %r9,-4(%r7)
- bdnz Loop28
- b Lend1
-
- mtctr %r5
-Loop29: lwzu %r10,-4(%r4)
- slwi %r9,%r11,29
- inslwi %r9,%r10,29,3
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,29
- inslwi %r9,%r11,29,3
- stwu %r9,-4(%r7)
- bdnz Loop29
- b Lend1
-
- mtctr %r5
-Loop30: lwzu %r10,-4(%r4)
- slwi %r9,%r11,30
- inslwi %r9,%r10,30,2
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,30
- inslwi %r9,%r11,30,2
- stwu %r9,-4(%r7)
- bdnz Loop30
- b Lend1
-
- mtctr %r5
-Loop31: lwzu %r10,-4(%r4)
- slwi %r9,%r11,31
- inslwi %r9,%r10,31,1
- stwu %r9,-4(%r7)
- bdz Lend2
- lwzu %r11,-4(%r4)
- slwi %r9,%r10,31
- inslwi %r9,%r11,31,1
- stwu %r9,-4(%r7)
- bdnz Loop31
- b Lend1
-
-Lend2: slw %r0,%r10,%r6
- stw %r0,-4(%r7)
- blr
diff --git a/sysdeps/unix/sysv/linux/powerpc/_exit.S b/sysdeps/powerpc/machine-gmon.h
index a1ca375d54..ba53807308 100644
--- a/sysdeps/unix/sysv/linux/powerpc/_exit.S
+++ b/sysdeps/powerpc/machine-gmon.h
@@ -1,5 +1,7 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* PowerPC-specific implementation of profiling support.
+ 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 Library General Public License as
@@ -16,11 +18,15 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <sysdep.h>
+/* We need a special version of the `mcount' function because it has
+ to preserve more registers than your usual function. */
-/* The 'exit' syscall does not return. */
+void __mcount_internal (unsigned long frompc, unsigned long selfpc);
- .text
-ENTRY(_exit)
- DO_CALL (SYS_ify (exit))
-PSEUDO_END (_exit)
+#define _MCOUNT_DECL(frompc, selfpc) \
+void __mcount_internal (unsigned long frompc, unsigned long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+ file. */
+#define MCOUNT
diff --git a/sysdeps/powerpc/memset.S b/sysdeps/powerpc/memset.S
new file mode 100644
index 0000000000..6ac32ddc99
--- /dev/null
+++ b/sysdeps/powerpc/memset.S
@@ -0,0 +1,199 @@
+/* Optimized memset implementation for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+EALIGN(memset,5,1)
+/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+ Returns 's'.
+
+ The memset is done in three sizes: byte (8 bits), word (32 bits),
+ cache line (256 bits). There is a special case for setting cache lines
+ to 0, to take advantage of the dcbz instruction.
+ r6: current address we are storing at
+ r7: number of bytes we are setting now (when aligning) */
+
+/* take care of case for size <= 4 */
+ cmplwi %cr1,%r5,4
+ andi. %r7,%r3,3
+ mr %r6,%r3
+ ble- %cr1,L(small)
+/* align to word boundary */
+ cmplwi %cr5,%r5,31
+ rlwimi %r4,%r4,8,16,23
+ beq+ L(aligned) # 8th instruction from .align
+ mtcrf 0x01,%r3
+ subfic %r7,%r7,4
+ add %r6,%r6,%r7
+ sub %r5,%r5,%r7
+ bf+ 31,0f
+ stb %r4,0(%r3)
+ bt 30,L(aligned)
+0: sth %r4,-2(%r6) # 16th instruction from .align
+/* take care of case for size < 31 */
+L(aligned):
+ mtcrf 0x01,%r5
+ rlwimi %r4,%r4,16,0,15
+ ble %cr5,L(medium)
+/* align to cache line boundary... */
+ andi. %r7,%r6,0x1C
+ subfic %r7,%r7,0x20
+ beq L(caligned)
+ mtcrf 0x01,%r7
+ add %r6,%r6,%r7
+ sub %r5,%r5,%r7
+ cmplwi %cr1,%r7,0x10
+ mr %r8,%r6
+ bf 28,1f
+ stw %r4,-4(%r8)
+ stwu %r4,-8(%r8)
+1: blt %cr1,2f
+ stw %r4,-4(%r8) # 32nd instruction from .align
+ stw %r4,-8(%r8)
+ stw %r4,-12(%r8)
+ stwu %r4,-16(%r8)
+2: bf 29,L(caligned)
+ stw %r4,-4(%r8)
+/* now aligned to a cache line. */
+L(caligned):
+ cmplwi %cr1,%r4,0
+ clrrwi. %r7,%r5,5
+ mtcrf 0x01,%r5 # 40th instruction from .align
+ beq %cr1,L(zloopstart) # special case for clearing memory using dcbz
+ srwi %r0,%r7,5
+ mtctr %r0
+ beq L(medium) # we may not actually get to do a full line
+ clrlwi. %r5,%r5,27
+ add %r6,%r6,%r7
+0: li %r8,-0x40
+ bdz L(cloopdone) # 48th instruction from .align
+
+3: dcbz %r8,%r6
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stw %r4,-16(%r6)
+ nop # let 601 fetch last 4 instructions of loop
+ stw %r4,-20(%r6)
+ stw %r4,-24(%r6) # 56th instruction from .align
+ nop # let 601 fetch first 8 instructions of loop
+ stw %r4,-28(%r6)
+ stwu %r4,-32(%r6)
+ bdnz 3b
+L(cloopdone):
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stw %r4,-16(%r6) # 64th instruction from .align
+ stw %r4,-20(%r6)
+ cmplwi %cr1,%r5,16
+ stw %r4,-24(%r6)
+ stw %r4,-28(%r6)
+ stwu %r4,-32(%r6)
+ beqlr
+ add %r6,%r6,%r7
+ b L(medium_tail2) # 72nd instruction from .align
+
+ .align 5
+ nop
+/* Clear lines of memory in 128-byte chunks. */
+L(zloopstart):
+ clrlwi %r5,%r5,27
+ mtcrf 0x02,%r7
+ srwi. %r0,%r7,7
+ mtctr %r0
+ li %r7,0x20
+ li %r8,-0x40
+ cmplwi %cr1,%r5,16 # 8
+ bf 26,0f
+ dcbz 0,%r6
+ addi %r6,%r6,0x20
+0: li %r9,-0x20
+ bf 25,1f
+ dcbz 0,%r6
+ dcbz %r7,%r6
+ addi %r6,%r6,0x40 # 16
+1: cmplwi %cr5,%r5,0
+ beq L(medium)
+L(zloop):
+ dcbz 0,%r6
+ dcbz %r7,%r6
+ addi %r6,%r6,0x80
+ dcbz %r8,%r6
+ dcbz %r9,%r6
+ bdnz L(zloop)
+ beqlr %cr5
+ b L(medium_tail2)
+
+ .align 5
+L(small):
+/* Memset of 4 bytes or less. */
+ cmplwi %cr5,%r5,1
+ cmplwi %cr1,%r5,3
+ bltlr %cr5
+ stb %r4,0(%r6)
+ beqlr %cr5
+ nop
+ stb %r4,1(%r6)
+ bltlr %cr1
+ stb %r4,2(%r6)
+ beqlr %cr1
+ nop
+ stb %r4,3(%r6)
+ blr
+
+/* Memset of 0-31 bytes. */
+ .align 5
+L(medium):
+ cmplwi %cr1,%r5,16
+L(medium_tail2):
+ add %r6,%r6,%r5
+L(medium_tail):
+ bt- 31,L(medium_31t)
+ bt- 30,L(medium_30t)
+L(medium_30f):
+ bt- 29,L(medium_29t)
+L(medium_29f):
+ bge- %cr1,L(medium_27t)
+ bflr- 28
+ stw %r4,-4(%r6) # 8th instruction from .align
+ stw %r4,-8(%r6)
+ blr
+
+L(medium_31t):
+ stbu %r4,-1(%r6)
+ bf- 30,L(medium_30f)
+L(medium_30t):
+ sthu %r4,-2(%r6)
+ bf- 29,L(medium_29f)
+L(medium_29t):
+ stwu %r4,-4(%r6)
+ blt- %cr1,L(medium_27f) # 16th instruction from .align
+L(medium_27t):
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ stw %r4,-12(%r6)
+ stwu %r4,-16(%r6)
+L(medium_27f):
+ bflr- 28
+L(medium_28t):
+ stw %r4,-4(%r6)
+ stw %r4,-8(%r6)
+ blr
+END(memset)
diff --git a/sysdeps/powerpc/memset.s b/sysdeps/powerpc/memset.s
deleted file mode 100644
index 4c8bf8c6b4..0000000000
--- a/sysdeps/powerpc/memset.s
+++ /dev/null
@@ -1,202 +0,0 @@
- # Optimized memset implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- .section ".text"
- .align 5
- nop
-
- .globl memset
- .type memset,@function
-memset:
- # __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
- # Returns 's'.
-
- # The memset is done in three sizes: byte (8 bits), word (32 bits),
- # cache line (256 bits). There is a special case for setting cache lines
- # to 0, to take advantage of the dcbz instruction.
- # r6: current address we are storing at
- # r7: number of bytes we are setting now (when aligning)
-
- # take care of case for size <= 4
- cmplwi %cr1,%r5,4
- andi. %r7,%r3,3
- mr %r6,%r3
- ble- %cr1,small
- # align to word boundary
- cmplwi %cr5,%r5,31
- rlwimi %r4,%r4,8,16,23
- beq+ aligned # 8th instruction from .align
- mtcrf 0x01,%r3
- subfic %r7,%r7,4
- add %r6,%r6,%r7
- sub %r5,%r5,%r7
- bf+ 31,0f
- stb %r4,0(%r3)
- bt 30,aligned
-0: sth %r4,-2(%r6) # 16th instruction from .align
- # take care of case for size < 31
-aligned:
- mtcrf 0x01,%r5
- rlwimi %r4,%r4,16,0,15
- ble %cr5,medium
- # align to cache line boundary...
- andi. %r7,%r6,0x1C
- subfic %r7,%r7,0x20
- beq caligned
- mtcrf 0x01,%r7
- add %r6,%r6,%r7
- sub %r5,%r5,%r7
- cmplwi %cr1,%r7,0x10
- mr %r8,%r6
- bf 28,1f
- stw %r4,-4(%r8)
- stwu %r4,-8(%r8)
-1: blt %cr1,2f
- stw %r4,-4(%r8) # 32nd instruction from .align
- stw %r4,-8(%r8)
- stw %r4,-12(%r8)
- stwu %r4,-16(%r8)
-2: bf 29,caligned
- stw %r4,-4(%r8)
- # now aligned to a cache line.
-caligned:
- cmplwi %cr1,%r4,0
- clrrwi. %r7,%r5,5
- mtcrf 0x01,%r5 # 40th instruction from .align
- beq %cr1,zloopstart # special case for clearing memory using dcbz
- srwi %r0,%r7,5
- mtctr %r0
- beq medium # we may not actually get to do a full line
- clrlwi. %r5,%r5,27
- add %r6,%r6,%r7
-0: li %r8,-0x40
- bdz cloopdone # 48th instruction from .align
-
-cloop: dcbz %r8,%r6
- stw %r4,-4(%r6)
- stw %r4,-8(%r6)
- stw %r4,-12(%r6)
- stw %r4,-16(%r6)
- nop # let 601 fetch last 4 instructions of loop
- stw %r4,-20(%r6)
- stw %r4,-24(%r6) # 56th instruction from .align
- nop # let 601 fetch first 8 instructions of loop
- stw %r4,-28(%r6)
- stwu %r4,-32(%r6)
- bdnz cloop
-cloopdone:
- stw %r4,-4(%r6)
- stw %r4,-8(%r6)
- stw %r4,-12(%r6)
- stw %r4,-16(%r6) # 64th instruction from .align
- stw %r4,-20(%r6)
- cmplwi %cr1,%r5,16
- stw %r4,-24(%r6)
- stw %r4,-28(%r6)
- stwu %r4,-32(%r6)
- beqlr
- add %r6,%r6,%r7
- b medium_tail2 # 72nd instruction from .align
-
- .align 5
- nop
-# clear lines of memory in 128-byte chunks.
-zloopstart:
- clrlwi %r5,%r5,27
- mtcrf 0x02,%r7
- srwi. %r0,%r7,7
- mtctr %r0
- li %r7,0x20
- li %r8,-0x40
- cmplwi %cr1,%r5,16 # 8
- bf 26,0f
- dcbz 0,%r6
- addi %r6,%r6,0x20
-0: li %r9,-0x20
- bf 25,1f
- dcbz 0,%r6
- dcbz %r7,%r6
- addi %r6,%r6,0x40 # 16
-1: cmplwi %cr5,%r5,0
- beq medium
-zloop:
- dcbz 0,%r6
- dcbz %r7,%r6
- addi %r6,%r6,0x80
- dcbz %r8,%r6
- dcbz %r9,%r6
- bdnz zloop
- beqlr %cr5
- b medium_tail2
-
- .align 5
-small:
- # Memset of 4 bytes or less.
- cmplwi %cr5,%r5,1
- cmplwi %cr1,%r5,3
- bltlr %cr5
- stb %r4,0(%r6)
- beqlr %cr5
- nop
- stb %r4,1(%r6)
- bltlr %cr1
- stb %r4,2(%r6)
- beqlr %cr1
- nop
- stb %r4,3(%r6)
- blr
-
-# memset of 0-31 bytes
- .align 5
-medium:
- cmplwi %cr1,%r5,16
-medium_tail2:
- add %r6,%r6,%r5
-medium_tail:
- bt- 31,medium_31t
- bt- 30,medium_30t
-medium_30f:
- bt- 29,medium_29t
-medium_29f:
- bge- %cr1,medium_27t
- bflr- 28
- stw %r4,-4(%r6) # 8th instruction from .align
- stw %r4,-8(%r6)
- blr
-
-medium_31t:
- stbu %r4,-1(%r6)
- bf- 30,medium_30f
-medium_30t:
- sthu %r4,-2(%r6)
- bf- 29,medium_29f
-medium_29t:
- stwu %r4,-4(%r6)
- blt- %cr1,medium_27f # 16th instruction from .align
-medium_27t:
- stw %r4,-4(%r6)
- stw %r4,-8(%r6)
- stw %r4,-12(%r6)
- stwu %r4,-16(%r6)
-medium_27f:
- bflr- 28
-medium_28t:
- stw %r4,-4(%r6)
- stw %r4,-8(%r6)
- blr
diff --git a/sysdeps/powerpc/mul_1.S b/sysdeps/powerpc/mul_1.S
new file mode 100644
index 0000000000..d48bd8fa19
--- /dev/null
+++ b/sysdeps/powerpc/mul_1.S
@@ -0,0 +1,46 @@
+/* Multiply a limb vector by a limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate s1*s2 and put result in res_ptr; return carry. */
+
+ENTRY(__mpn_mul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ addi %r3,%r3,-4 # adjust res_ptr
+ addic %r5,%r5,0 # clear cy with dummy insn
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r7,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ bdnz 0b
+
+1: stw %r7,4(%r3)
+ addze %r3,%r10
+ blr
+END(__mpn_mul_1)
diff --git a/sysdeps/powerpc/mul_1.s b/sysdeps/powerpc/mul_1.s
deleted file mode 100644
index d6eb623bd4..0000000000
--- a/sysdeps/powerpc/mul_1.s
+++ /dev/null
@@ -1,47 +0,0 @@
- # Multiply a limb vector by a limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- # mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate s1*s2 and put result in res_ptr; return carry.
-
- .align 2
- .globl __mpn_mul_1
- .type __mpn_mul_1,@function
-
-__mpn_mul_1:
- mtctr %r5
-
- lwz %r0,0(%r4)
- mullw %r7,%r0,%r6
- mulhwu %r10,%r0,%r6
- addi %r3,%r3,-4 # adjust res_ptr
- addic %r5,%r5,0 # clear cy with dummy insn
- bdz Lend
-
-Loop: lwzu %r0,4(%r4)
- stwu %r7,4(%r3)
- mullw %r8,%r0,%r6
- adde %r7,%r8,%r10
- mulhwu %r10,%r0,%r6
- bdnz Loop
-
-Lend: stw %r7,4(%r3)
- addze %r3,%r10
- blr
diff --git a/sysdeps/powerpc/ppc-mcount.S b/sysdeps/powerpc/ppc-mcount.S
new file mode 100644
index 0000000000..06f1fcda12
--- /dev/null
+++ b/sysdeps/powerpc/ppc-mcount.S
@@ -0,0 +1,84 @@
+/* PowerPC-specific implementation of profiling support.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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. */
+
+/* This would be bad. */
+#ifdef PROF
+#undef PROF
+#endif
+
+#include <sysdep.h>
+
+/* We do profiling as described in the SYSV ELF ABI, _mcount is called
+ with the address of a data word in r0 (that is different for every
+ routine, initialised to 0, and otherwise unused). The caller has put
+ the address the caller will return to in the usual place on the stack,
+ 4(%r1). _mcount is responsible for ensuring that when it returns no
+ argument-passing registers are disturbed, and that the LR is set back
+ to (what the caller sees as) 4(%r1).
+
+ This is intended so that the following code can be inserted at the
+ front of any routine without changing the routine:
+
+ .data
+ .align 2
+ 0: .long 0
+ .previous
+ mflr %r0
+ lis %r11,0b@ha
+ stw %r0,4(%r1)
+ addi %r0,%r11,0b@l
+ bl _mcount
+*/
+
+ENTRY(_mcount)
+ stwu %r1,-48(%r1)
+/* We need to save the parameter-passing registers. */
+ stw %r3, 12(%r1)
+ stw %r4, 16(%r1)
+ stw %r5, 20(%r1)
+ stw %r6, 24(%r1)
+ mflr %r4
+ lwz %r3, 52(%r1)
+ mfcr %r5
+ stw %r7, 28(%r1)
+ stw %r8, 32(%r1)
+ stw %r9, 36(%r1)
+ stw %r10,40(%r1)
+ stw %r4, 44(%r1)
+ stw %r5, 8(%r1)
+ bl JUMPTARGET(__mcount_internal)
+ /* Restore the registers... */
+ lwz %r6, 8(%r1)
+ lwz %r0, 44(%r1)
+ lwz %r3, 12(%r1)
+ mtctr %r0
+ lwz %r4, 16(%r1)
+ mtcrf 0xff,%r6
+ lwz %r5, 20(%r1)
+ lwz %r6, 24(%r1)
+ lwz %r0, 52(%r1)
+ lwz %r7, 28(%r1)
+ lwz %r8, 32(%r1)
+ mtlr %r0
+ lwz %r9, 36(%r1)
+ lwz %r10,40(%r1)
+ /* ...unwind the stack frame, and return to your usual programming. */
+ addi %r1,%r1,48
+ bctr
+END(_mcount)
diff --git a/sysdeps/powerpc/rshift.S b/sysdeps/powerpc/rshift.S
new file mode 100644
index 0000000000..eb1f562bed
--- /dev/null
+++ b/sysdeps/powerpc/rshift.S
@@ -0,0 +1,56 @@
+/* Shift a limb right, low level routine.
+ Copyright (C) 1995, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* INPUT PARAMETERS
+ res_ptr r3
+ s1_ptr r4
+ size r5
+ cnt r6 */
+
+ENTRY(__mpn_rshift)
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz 1f
+
+0: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz 2f
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz 0b
+
+1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+2: srw 0,10,6
+ stw 0,4(7)
+ blr
+END(__mpn_rshift)
diff --git a/sysdeps/powerpc/rshift.s b/sysdeps/powerpc/rshift.s
deleted file mode 100644
index 20f09ad86a..0000000000
--- a/sysdeps/powerpc/rshift.s
+++ /dev/null
@@ -1,59 +0,0 @@
-# PowerPC-32 __mpn_rshift --
-
-# Copyright (C) 1995 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 Library General Public License as published by
-# the Free Software Foundation; either version 2 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 Library General Public
-# License for more details.
-
-# You should have received a copy of the GNU Library 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.
-
-
-# INPUT PARAMETERS
-# res_ptr r3
-# s1_ptr r4
-# size r5
-# cnt r6
-
- .align 3
- .globl __mpn_rshift
- .type __mpn_rshift,@function
-__mpn_rshift:
- mtctr 5 # copy size into CTR
- addi 7,3,-4 # move adjusted res_ptr to free return reg
- subfic 8,6,32
- lwz 11,0(4) # load first s1 limb
- slw 3,11,8 # compute function return value
- bdz Lend1
-
-Loop: lwzu 10,4(4)
- srw 9,11,6
- slw 12,10,8
- or 9,9,12
- stwu 9,4(7)
- bdz Lend2
- lwzu 11,4(4)
- srw 9,10,6
- slw 12,11,8
- or 9,9,12
- stwu 9,4(7)
- bdnz Loop
-
-Lend1: srw 0,11,6
- stw 0,4(7)
- blr
-
-Lend2: srw 0,10,6
- stw 0,4(7)
- blr
diff --git a/sysdeps/powerpc/s_copysign.S b/sysdeps/powerpc/s_copysign.S
index adc7df226a..6d5ba82592 100644
--- a/sysdeps/powerpc/s_copysign.S
+++ b/sysdeps/powerpc/s_copysign.S
@@ -1,17 +1,17 @@
/* Copy a sign bit between floating-point values.
Copyright (C) 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -20,15 +20,12 @@
/* This has been coded in assembler because GCC makes such a mess of it
when it's coded in C. */
- .section ".text"
- .align 2
- .globl __copysign
- .type __copysign,@function
-__copysign:
+#include <sysdep.h>
+
+ENTRY(__copysign)
/* double [f1] copysign (double [f1] x, double [f2] y);
copysign(x,y) returns a value with the magnitude of x and
with the sign bit of y. */
-
stwu %r1,-16(%r1)
stfd %f2,8(%r1)
lwz %r3,8(%r1)
@@ -39,22 +36,15 @@ __copysign:
blr
0: fnabs %f1,%f1
blr
-0:
- .size __copysign,0b-__copysign
-
- .globl copysign
- .globl copysignf
- .globl __copysignf
- .weak copysign
- .weak copysignf
- .set copysign,__copysign
+ END (__copysign)
+
+weak_alias(__copysign,copysign)
+
/* It turns out that it's safe to use this code even for single-precision. */
- .set __copysignf,__copysign
- .set copysignf,__copysign
+weak_alias(__copysign,copysignf)
+strong_alias(__copysign,__copysignf)
+
#ifdef NO_LONG_DOUBLE
- .globl copysignl
- .globl __copysignl
- .weak copysignl
- .set __copysignl,__copysign
- .set copysignl,__copysign
+weak_alias(__copysign,copysignl)
+strong_alias(__copysign,__copysignl)
#endif
diff --git a/sysdeps/powerpc/s_fabs.S b/sysdeps/powerpc/s_fabs.S
index a52733568d..3c6374b0aa 100644
--- a/sysdeps/powerpc/s_fabs.S
+++ b/sysdeps/powerpc/s_fabs.S
@@ -1,42 +1,37 @@
/* Floating-point absolute value. PowerPC version.
Copyright (C) 1997 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 Library General Public License as
published by the Free Software Foundation; either version 2 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
Library General Public License for more details.
-
+
You should have received a copy of the GNU Library General Public
License along with the GNU C 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. */
- .section ".text"
- .align 2
- .globl __fabs
- .type __fabs,@function
-__fabs:
+#include <sysdep.h>
+
+ENTRY(__fabs)
/* double [f1] fabs (double [f1] x); */
fabs %f1,%f1
blr
-0:
- .size __fabs,0b-__fabs
+END(__fabs)
+
+weak_alias(__fabs,fabs)
- .globl fabs,fabsf,__fabsf
- .weak fabs,fabsf
- .set fabs,__fabs
/* It turns out that it's safe to use this code even for single-precision. */
- .set __fabsf,__fabs
- .set fabsf,__fabs
+strong_alias(__fabs,__fabsf)
+weak_alias(__fabs,fabsf)
+
#ifdef NO_LONG_DOUBLE
- .globl fabsl,__fabsl
- .weak fabsl
- .set __fabsl,__fabs
- .set fabsl,__fabs
+weak_alias(__fabs,__fabsl)
+weak_alias(__fabs,fabsl)
#endif
diff --git a/sysdeps/powerpc/setjmp.S b/sysdeps/powerpc/setjmp.S
index ddfea7eed3..8fa863f161 100644
--- a/sysdeps/powerpc/setjmp.S
+++ b/sysdeps/powerpc/setjmp.S
@@ -62,9 +62,5 @@ ENTRY (__sigsetjmp)
stfd %f30,((JB_FPRS+16*2)*4)(3)
stw %r31,((JB_GPRS+17)*4)(3)
stfd %f31,((JB_FPRS+17*2)*4)(3)
-#ifdef PIC
- b __sigjmp_save@plt
-#else
- b __sigjmp_save
-#endif
+ b JUMPTARGET(__sigjmp_save)
END (__sigsetjmp)
diff --git a/sysdeps/powerpc/strchr.S b/sysdeps/powerpc/strchr.S
new file mode 100644
index 0000000000..156d4d155c
--- /dev/null
+++ b/sysdeps/powerpc/strchr.S
@@ -0,0 +1,111 @@
+/* Optimized strchr implementation for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* See strlen.s for comments on how this works. */
+
+/* char * [r3] strchr (const char *s [r3] , int c [r4] )
+
+ r0: a temporary
+ r3: our return result.
+ r4: byte we're looking for, spread over the whole word
+ r5: the current word
+ r6: the constant 0xfefefeff (-0x01010101)
+ r7: the constant 0x7f7f7f7f
+ r8: pointer to the current word.
+ r9: a temporary
+ r10: the number of bits we should ignore in the first word
+ r11: a mask with the bits to ignore set to 0
+ r12: a temporary */
+ENTRY(strchr)
+ rlwimi %r4,%r4,8,16,23
+ li %r11,-1
+ rlwimi %r4,%r4,16,0,15
+ lis %r6,0xfeff
+ lis %r7,0x7f7f
+ clrrwi %r8,%r3,2
+ addi %r7,%r7,0x7f7f
+ addi %r6,%r6,0xfffffeff
+ rlwinm %r10,%r3,3,27,28
+/* Test the first (partial?) word. */
+ lwz %r5,0(%r8)
+ srw %r11,%r11,%r10
+ orc %r5,%r5,%r11
+ add %r0,%r6,%r5
+ nor %r9,%r7,%r5
+ and. %r0,%r0,%r9
+ xor %r12,%r4,%r5
+ orc %r12,%r12,%r11
+ b L(loopentry)
+
+/* The loop. */
+
+L(loop):lwzu %r5,4(%r8)
+ and. %r0,%r0,%r9
+/* Test for 0. */
+ add %r0,%r6,%r5
+ nor %r9,%r7,%r5
+ bne L(foundit)
+ and. %r0,%r0,%r9
+/* Start test for the bytes we're looking for. */
+ xor %r12,%r4,%r5
+L(loopentry):
+ add %r0,%r6,%r12
+ nor %r9,%r7,%r12
+ beq L(loop)
+/* There is a zero byte in the word, but may also be a matching byte (either
+ before or after the zero byte). In fact, we may be looking for a
+ zero byte, in which case we return a match. We guess that this hasn't
+ happened, though. */
+L(missed):
+ and. %r0,%r0,%r9
+ li %r3,0
+ beqlr
+/* It did happen. Decide which one was first...
+ I'm not sure if this is actually faster than a sequence of
+ rotates, compares, and branches (we use it anyway because it's shorter). */
+ and %r6,%r7,%r5
+ or %r11,%r7,%r5
+ and %r0,%r7,%r12
+ or %r10,%r7,%r12
+ add %r6,%r6,%r7
+ add %r0,%r0,%r7
+ nor %r5,%r11,%r6
+ nor %r9,%r10,%r0
+ cmplw %r5,%r9
+ bgtlr
+ cntlzw %r4,%r9
+ srwi %r4,%r4,3
+ add %r3,%r8,%r4
+ blr
+
+L(foundit):
+ and %r0,%r7,%r12
+ or %r10,%r7,%r12
+ add %r0,%r0,%r7
+ nor %r9,%r10,%r0
+ cntlzw %r4,%r9
+ subi %r8,%r8,4
+ srwi %r4,%r4,3
+ add %r3,%r8,%r4
+ blr
+END(strchr)
+
+weak_alias(strchr,index)
diff --git a/sysdeps/powerpc/strchr.s b/sysdeps/powerpc/strchr.s
deleted file mode 100644
index c1df66f8dc..0000000000
--- a/sysdeps/powerpc/strchr.s
+++ /dev/null
@@ -1,118 +0,0 @@
- # Optimized strchr implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # See strlen.s for comments on how this works.
-
- .section ".text"
- .align 2
- .globl strchr
- .type strchr,@function
-strchr:
- # char * [r3] strchr (const char *s [r3] , int c [r4] )
-
- # r0: a temporary
- # r3: our return result.
- # r4: byte we're looking for, spread over the whole word
- # r5: the current word
- # r6: the constant 0xfefefeff (-0x01010101)
- # r7: the constant 0x7f7f7f7f
- # r8: pointer to the current word.
- # r9: a temporary
- # r10: the number of bits we should ignore in the first word
- # r11: a mask with the bits to ignore set to 0
- # r12: a temporary
-
- rlwimi %r4,%r4,8,16,23
- li %r11,-1
- rlwimi %r4,%r4,16,0,15
- lis %r6,0xfeff
- lis %r7,0x7f7f
- clrrwi %r8,%r3,2
- addi %r7,%r7,0x7f7f
- addi %r6,%r6,0xfffffeff
- rlwinm %r10,%r3,3,27,28
- # Test the first (partial?) word.
- lwz %r5,0(%r8)
- srw %r11,%r11,%r10
- orc %r5,%r5,%r11
- add %r0,%r6,%r5
- nor %r9,%r7,%r5
- and. %r0,%r0,%r9
- xor %r12,%r4,%r5
- orc %r12,%r12,%r11
- b loopentry
-
- # The loop.
-
-loop: lwzu %r5,4(%r8)
- and. %r0,%r0,%r9
- # Test for 0
- add %r0,%r6,%r5
- nor %r9,%r7,%r5
- bne foundit
- and. %r0,%r0,%r9
- # Start test for the bytes we're looking for
- xor %r12,%r4,%r5
-loopentry:
- add %r0,%r6,%r12
- nor %r9,%r7,%r12
- beq loop
- # There is a zero byte in the word, but may also be a matching byte (either
- # before or after the zero byte). In fact, we may be looking for a
- # zero byte, in which case we return a match. We guess that this hasn't
- # happened, though.
-missed:
- and. %r0,%r0,%r9
- li %r3,0
- beqlr
- # It did happen. Decide which one was first...
- # I'm not sure if this is actually faster than a sequence of
- # rotates, compares, and branches (we use it anyway because it's shorter).
- and %r6,%r7,%r5
- or %r11,%r7,%r5
- and %r0,%r7,%r12
- or %r10,%r7,%r12
- add %r6,%r6,%r7
- add %r0,%r0,%r7
- nor %r5,%r11,%r6
- nor %r9,%r10,%r0
- cmplw %r5,%r9
- bgtlr
- cntlzw %r4,%r9
- srwi %r4,%r4,3
- add %r3,%r8,%r4
- blr
-
-foundit:
- and %r0,%r7,%r12
- or %r10,%r7,%r12
- add %r0,%r0,%r7
- nor %r9,%r10,%r0
- cntlzw %r4,%r9
- subi %r8,%r8,4
- srwi %r4,%r4,3
- add %r3,%r8,%r4
- blr
-
-0:
- .size strchr,0b-strchr
-
- .globl index
- .weak index
- .set index,strchr
diff --git a/sysdeps/powerpc/strcmp.S b/sysdeps/powerpc/strcmp.S
new file mode 100644
index 0000000000..9f4d134419
--- /dev/null
+++ b/sysdeps/powerpc/strcmp.S
@@ -0,0 +1,115 @@
+/* Optimized strcmp implementation for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* See strlen.s for comments on how the end-of-string testing works. */
+
+EALIGN(strcmp,4,0)
+/* int [r3] strcmp (const char *p1 [r3], const char *p2 [r4]) */
+
+/* General register assignments:
+ r0: temporary
+ r3: pointer to previous word in s1
+ r4: pointer to previous word in s2
+ r5: current word from s1
+ r6: current word from s2
+ r7: 0xfefefeff
+ r8: 0x7f7f7f7f
+ r9: ~(word in s1 | 0x7f7f7f7f) */
+
+/* Register assignments in the prologue:
+ r10: low 2 bits of p2-p1
+ r11: mask to orc with r5/r6 */
+
+ or %r0,%r4,%r3
+ clrlwi. %r0,%r0,30
+ lis %r7,0xfeff
+ bne L(unaligned)
+
+ lwz %r5,0(%r3)
+ lwz %r6,0(%r4)
+ lis %r8,0x7f7f
+ addi %r7,%r7,-0x101
+ addi %r8,%r8,0x7f7f
+ b 1f
+
+0: lwzu %r5,4(%r3)
+ bne %cr1,L(different)
+ lwzu %r6,4(%r4)
+1: add %r0,%r7,%r5
+ nor %r9,%r8,%r5
+ and. %r0,%r0,%r9
+ cmpw %cr1,%r5,%r6
+ beq+ 0b
+L(endstring):
+/* OK. We've hit the end of the string. We need to be careful that
+ we don't compare two strings as different because of gunk beyond
+ the end of the strings... */
+ and %r0,%r8,%r5
+ beq %cr1,L(equal)
+ add %r0,%r0,%r8
+ xor. %r10,%r5,%r6
+ andc %r9,%r9,%r0
+ blt- L(highbit)
+ cntlzw %r10,%r10
+ cntlzw %r9,%r9
+ addi %r9,%r9,7
+ cmpw %cr1,%r9,%r10
+ sub %r3,%r5,%r6
+ bgelr+ %cr1
+L(equal):
+ li %r3,0
+ blr
+
+L(different):
+ lwz %r5,-4(%r3)
+ xor. %r10,%r5,%r6
+ sub %r3,%r5,%r6
+ bgelr+
+L(highbit):
+ mr %r3,%r6
+ blr
+
+
+/* Oh well. In this case, we just do a byte-by-byte comparison. */
+ .align 4
+L(unaligned):
+ lbz %r5,0(%r3)
+ lbz %r6,0(%r4)
+ b 1f
+
+0: lbzu %r5,1(%r3)
+ bne- 4f
+ lbzu %r6,1(%r4)
+1: cmpwi %cr1,%r5,0
+ beq- %cr1,3f
+ cmpw %r5,%r6
+ bne- 3f
+ lbzu %r5,1(%r3)
+ lbzu %r6,1(%r4)
+ cmpwi %cr1,%r5,0
+ cmpw %r5,%r6
+ bne+ %cr1,0b
+3: sub %r3,%r5,%r6
+ blr
+4: lbz %r5,-1(%r3)
+ sub %r3,%r5,%r6
+ blr
+END(strcmp)
diff --git a/sysdeps/powerpc/strcmp.s b/sysdeps/powerpc/strcmp.s
deleted file mode 100644
index f901b82ab1..0000000000
--- a/sysdeps/powerpc/strcmp.s
+++ /dev/null
@@ -1,273 +0,0 @@
- # Optimized strcmp implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # See strlen.s for comments on how the end-of-string testing works.
-
- .section ".text"
- .align 3
- .globl strcmp
- .type strcmp,@function
-strcmp:
- # int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])
-
- # General register assignments:
- # r0: temporary
- # r3: pointer to previous word in s1
- # r4: pointer to previous word in s2
- # r5: current first word in s1
- # r6: current first word in s2 (after re-alignment)
- # r7: 0xfefefeff
- # r8: 0x7f7f7f7f
- # r9: ~(word in s1 | 0x7f7f7f7f)
-
- # Register assignments in the prologue:
- # r10: low 2 bits of p2-p1
- # r11: mask to orc with r5/r6
-
- subf. %r10,%r4,%r3
- beq- equal
- andi. %r10,%r10,3
- cmpi %cr1,%r10,2
- beq- %cr1,align2
- lis %r7,0xfeff
- lis %r8,0x7f7f
- addi %r8,%r8,0x7f7f
- addi %r7,%r7,0xfffffeff
- bgt- %cr1,align3
-strcmp3:
- rlwinm %r0,%r3,3,27,28
- li %r11,-1
- srw %r11,%r11,%r0
- clrrwi %r3,%r3,2
- clrrwi %r4,%r4,2
- lwz %r5,0(%r3)
- lwz %r6,0(%r4)
- bne- align1
-
- # The loop, case when both strings are aligned the same.
- # on entry, cr1.eq must be 1.
- # r10: second word in s1
- # r11: second word in s2 OR mask to orc with first two words.
-align0:
- andi. %r0,%r3,4
- orc %r5,%r5,%r11
- orc %r6,%r6,%r11
- beq+ a0start
- add %r0,%r7,%r5
- nor %r9,%r8,%r5
- and. %r0,%r0,%r9
- cmplw %cr1,%r5,%r6
- subi %r3,%r3,4
- bne- endstringeq
- subi %r4,%r4,4
- bne- %cr1,difference
-
-loopalign0:
- lwzu %r5,8(%r3)
- bne- %cr1,difference2
- lwzu %r6,8(%r4)
-a0start:
- add %r0,%r7,%r5
- nor %r9,%r8,%r5
- and. %r0,%r0,%r9
- cmplw %cr1,%r5,%r6
- lwz %r10,4(%r3)
- bne- endstringeq
- add %r0,%r7,%r10
- bne- %cr1,difference
- nor %r9,%r8,%r10
- lwz %r11,4(%r4)
- and. %r0,%r0,%r9
- cmplw %cr1,%r10,%r11
- beq+ loopalign0
-
- mr %r5,%r10
- mr %r6,%r11
-
- # fall through to...
-
-endstringeq:
- # (like 'endstring', but an equality code is in cr1)
- beq %cr1,equal
-endstring:
- # OK. We've hit the end of the string. We need to be careful that
- # we don't compare two strings as different because of gunk beyond
- # the end of the strings. We do it like this...
- and %r0,%r8,%r5
- add %r0,%r0,%r8
- xor. %r10,%r5,%r6
- andc %r9,%r9,%r0
- cntlzw %r10,%r10
- cntlzw %r9,%r9
- addi %r9,%r9,7
- cmpw %cr1,%r9,%r10
- blt %cr1,equal
- sub %r3,%r5,%r6
- bgelr+
- mr %r3,%r6
- blr
-equal: li %r3,0
- blr
-
- # The loop, case when s2 is aligned 1 char behind s1.
- # r10: current word in s2 (before re-alignment)
-
-align1:
- cmpwi %cr1,%r0,0
- orc %r5,%r5,%r11
- bne %cr1,align1_123
- # When s1 is aligned to a word boundary, the startup processing is special.
- slwi. %r6,%r6,24
- bne+ a1entry_0
- nor %r9,%r8,%r5
- b endstring
-
-align1_123:
- # Otherwise (s1 not aligned to a word boundary):
- mr %r10,%r6
- add %r0,%r7,%r5
- nor %r9,%r8,%r5
- and. %r0,%r0,%r9
- srwi %r6,%r6,8
- orc %r6,%r6,%r11
- cmplw %cr1,%r5,%r6
- bne- endstringeq
- bne- %cr1,difference
-
-loopalign1:
- slwi. %r6,%r10,24
- bne- %cr1,a1difference
- lwzu %r5,4(%r3)
- beq- endstring1
-a1entry_0:
- lwzu %r10,4(%r4)
-a1entry_123:
- add %r0,%r7,%r5
- nor %r9,%r8,%r5
- and. %r0,%r0,%r9
- rlwimi %r6,%r10,24,8,31
- cmplw %cr1,%r5,%r6
- beq+ loopalign1
- b endstringeq
-
-endstring1:
- srwi %r3,%r5,24
- blr
-
-a1difference:
- lbz %r6,-1(%r4)
- slwi %r6,%r6,24
- rlwimi %r6,%r10,24,8,31
-
- # fall through to...
-
-difference:
- # The idea here is that we could just return '%r5 - %r6', except
- # that the result might overflow. Overflow can only happen when %r5
- # and %r6 have different signs (thus the xor), in which case we want to
- # return negative iff %r6 has its high bit set so %r5 < %r6.
- # A branch-free implementation of this is
- # xor %r0,%r5,%r6
- # rlwinm %r0,%r0,1,31,31
- # rlwnm %r5,%r5,%r0,1,31
- # rlwnm %r6,%r6,%r0,1,31
- # sub %r3,%r5,%r6
- # blr
- # but this is usually more expensive.
- xor. %r0,%r5,%r6
- sub %r3,%r5,%r6
- bgelr+
- mr %r3,%r6
- blr
-
-difference2:
- # As for 'difference', but use registers r10 and r11 instead of r5 and r6.
- xor. %r0,%r10,%r11
- sub %r3,%r10,%r11
- bgelr+
- mr %r3,%r11
- blr
-
- # For the case when s2 is aligned 3 chars behind s1, we switch
- # s1 and s2...
- # r10: used by 'align2' (see below)
- # r11: used by 'align2' (see below)
- # r12: saved link register
- # cr0.eq: must be left as 1.
-
-align3: mflr %r12
- mr %r0,%r3
- mr %r3,%r4
- mr %r4,%r0
- bl strcmp3
- mtlr %r12
- neg %r3,%r3
- blr
-
- # The loop, case when s2 and s1's alignments differ by 2
- # This is the ugly case...
- # FIXME: on a 601, the loop takes 7 cycles instead of the 6 you'd expect,
- # because there are too many branches. This loop should probably be
- # coded like the align1 case.
-
-a2even: lhz %r5,0(%r3)
- lhz %r6,0(%r4)
- b a2entry
-
-align2:
- andi. %r0,%r3,1
- beq+ a2even
- subi %r3,%r3,1
- subi %r4,%r4,1
- lbz %r5,1(%r3)
- lbz %r6,1(%r4)
- cmpwi %cr0,%r5,0
- cmpw %cr1,%r5,%r6
- beq- align2end2
- lhzu %r5,2(%r3)
- beq+ %cr1,a2entry1
- lbz %r5,-1(%r3)
- sub %r3,%r5,%r6
- blr
-
-loopalign2:
- cmpw %cr1,%r5,%r6
- beq- align2end2
- lhzu %r5,2(%r3)
- bne- %cr1,align2different
-a2entry1:
- lhzu %r6,2(%r4)
-a2entry:
- cmpwi %cr5,%r5,0x00ff
- andi. %r0,%r5,0x00ff
- bgt+ %cr5,loopalign2
-
-align2end:
- andi. %r3,%r6,0xff00
- neg %r3,%r3
- blr
-
-align2different:
- lhzu %r5,-2(%r3)
-align2end2:
- sub %r3,%r5,%r6
- blr
-
-0:
- .size strcmp,0b-strcmp
diff --git a/sysdeps/powerpc/strlen.S b/sysdeps/powerpc/strlen.S
new file mode 100644
index 0000000000..dc6660b8fc
--- /dev/null
+++ b/sysdeps/powerpc/strlen.S
@@ -0,0 +1,144 @@
+/* Optimized strlen implementation for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* The algorithm here uses the following techniques:
+
+ 1) Given a word 'x', we can test to see if it contains any 0 bytes
+ by subtracting 0x01010101, and seeing if any of the high bits of each
+ byte changed from 0 to 1. This works because the least significant
+ 0 byte must have had no incoming carry (otherwise it's not the least
+ significant), so it is 0x00 - 0x01 == 0xff. For all other
+ byte values, either they have the high bit set initially, or when
+ 1 is subtracted you get a value in the range 0x00-0x7f, none of which
+ have their high bit set. The expression here is
+ (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+ there were no 0x00 bytes in the word.
+
+ 2) Given a word 'x', we can test to see _which_ byte was zero by
+ calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+ This produces 0x80 in each byte that was zero, and 0x00 in all
+ the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
+ byte, and the '| x' part ensures that bytes with the high bit set
+ produce 0x00. The addition will carry into the high bit of each byte
+ iff that byte had one of its low 7 bits set. We can then just see
+ which was the most significant bit set and divide by 8 to find how
+ many to add to the index.
+ This is from the book 'The PowerPC Compiler Writer's Guide',
+ by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+
+ We deal with strings not aligned to a word boundary by taking the
+ first word and ensuring that bytes not part of the string
+ are treated as nonzero. To allow for memory latency, we unroll the
+ loop a few times, being careful to ensure that we do not read ahead
+ across cache line boundaries.
+
+ Questions to answer:
+ 1) How long are strings passed to strlen? If they're often really long,
+ we should probably use cache management instructions and/or unroll the
+ loop more. If they're often quite short, it might be better to use
+ fact (2) in the inner loop than have to recalculate it.
+ 2) How popular are bytes with the high bit set? If they are very rare,
+ on some processors it might be useful to use the simpler expression
+ ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
+ ALU), but this fails when any character has its high bit set. */
+
+/* Some notes on register usage: Under the SVR4 ABI, we can use registers
+ 0 and 3 through 12 (so long as we don't call any procedures) without
+ saving them. We can also use registers 14 through 31 if we save them.
+ We can't use r1 (it's the stack pointer), r2 nor r13 because the user
+ program may expect them to hold their usual value if we get sent
+ a signal. Integer parameters are passed in r3 through r10.
+ We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
+ them, the others we must save. */
+
+ENTRY(strlen)
+/* On entry, r3 points to the string, and it's left that way.
+ We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
+ r4 is used to keep the current index into the string; r5 holds
+ the number of padding bits we prepend to the string to make it
+ start at a word boundary. r8 holds the 'current' word.
+ r9-12 are temporaries. r0 is used as a temporary and for discarded
+ results. */
+ clrrwi %r4,%r3,2
+ lis %r7,0x7f7f
+ rlwinm %r5,%r3,3,27,28
+ lwz %r8,0(%r4)
+ li %r9,-1
+ addi %r7,%r7,0x7f7f
+/* That's the setup done, now do the first pair of words.
+ We make an exception and use method (2) on the first two words, to reduce
+ overhead. */
+ srw %r9,%r9,%r5
+ and %r0,%r7,%r8
+ or %r10,%r7,%r8
+ add %r0,%r0,%r7
+ nor %r0,%r10,%r0
+ and. %r8,%r0,%r9
+ mtcrf 0x01,%r3
+ bne L(done0)
+ lis %r6,0xfeff
+ addi %r6,%r6,-0x101
+/* Are we now aligned to a doubleword boundary? */
+ bt 29,L(loop)
+
+/* Handle second word of pair. */
+ lwzu %r8,4(%r4)
+ and %r0,%r7,%r8
+ or %r10,%r7,%r8
+ add %r0,%r0,%r7
+ nor. %r8,%r10,%r0
+ bne L(done0)
+
+/* The loop. */
+
+L(loop):
+ lwz %r8,4(%r4)
+ lwzu %r9,8(%r4)
+ add %r0,%r6,%r8
+ nor %r10,%r7,%r8
+ and. %r0,%r0,%r10
+ add %r11,%r6,%r9
+ nor %r12,%r7,%r9
+ bne L(done1)
+ and. %r0,%r11,%r12
+ beq L(loop)
+
+ and %r0,%r7,%r9
+ add %r0,%r0,%r7
+ andc %r8,%r12,%r0
+ b L(done0)
+
+L(done1):
+ and %r0,%r7,%r8
+ subi %r4,%r4,4
+ add %r0,%r0,%r7
+ andc %r8,%r10,%r0
+
+/* When we get to here, r4 points to the first word in the string that
+ contains a zero byte, and the most significant set bit in r8 is in that
+ byte. */
+L(done0):
+ cntlzw %r11,%r8
+ subf %r0,%r3,%r4
+ srwi %r11,%r11,3
+ add %r3,%r0,%r11
+ blr
+END(strlen)
diff --git a/sysdeps/powerpc/strlen.s b/sysdeps/powerpc/strlen.s
deleted file mode 100644
index ea809772eb..0000000000
--- a/sysdeps/powerpc/strlen.s
+++ /dev/null
@@ -1,144 +0,0 @@
- # Optimized strlen implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # The algorithm here uses the following techniques:
- #
- # 1) Given a word 'x', we can test to see if it contains any 0 bytes
- # by subtracting 0x01010101, and seeing if any of the high bits of each
- # byte changed from 0 to 1. This works because the least significant
- # 0 byte must have had no incoming carry (otherwise it's not the least
- # significant), so it is 0x00 - 0x01 == 0xff. For all other
- # byte values, either they have the high bit set initially, or when
- # 1 is subtracted you get a value in the range 0x00-0x7f, none of which
- # have their high bit set. The expression here is
- # (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
- # there were no 0x00 bytes in the word.
- #
- # 2) Given a word 'x', we can test to see _which_ byte was zero by
- # calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
- # This produces 0x80 in each byte that was zero, and 0x00 in all
- # the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
- # byte, and the '| x' part ensures that bytes with the high bit set
- # produce 0x00. The addition will carry into the high bit of each byte
- # iff that byte had one of its low 7 bits set. We can then just see
- # which was the most significant bit set and divide by 8 to find how
- # many to add to the index.
- # This is from the book 'The PowerPC Compiler Writer's Guide',
- # by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
- #
- # We deal with strings not aligned to a word boundary by taking the
- # first word and ensuring that bytes not part of the string
- # are treated as nonzero. To allow for memory latency, we unroll the
- # loop a few times, being careful to ensure that we do not read ahead
- # across cache line boundaries.
- #
- # Questions to answer:
- # 1) How long are strings passed to strlen? If they're often really long,
- # we should probably use cache management instructions and/or unroll the
- # loop more. If they're often quite short, it might be better to use
- # fact (2) in the inner loop than have to recalculate it.
- # 2) How popular are bytes with the high bit set? If they are very rare,
- # on some processors it might be useful to use the simpler expression
- # ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
- # ALU), but this fails when any character has its high bit set.
-
- # Some notes on register usage: Under the SVR4 ABI, we can use registers
- # 0 and 3 through 12 (so long as we don't call any procedures) without
- # saving them. We can also use registers 14 through 31 if we save them.
- # We can't use r1 (it's the stack pointer), r2 nor r13 because the user
- # program may expect them to hold their usual value if we get sent
- # a signal. Integer parameters are passed in r3 through r10.
- # We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
- # them, the others we must save.
-
- .section ".text"
- .align 2
- .globl strlen
- .type strlen,@function
-strlen:
- # On entry, r3 points to the string, and it's left that way.
- # We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
- # r4 is used to keep the current index into the string; r5 holds
- # the number of padding bits we prepend to the string to make it
- # start at a word boundary. r8 holds the 'current' word.
- # r9-12 are temporaries. r0 is used as a temporary and for discarded
- # results.
- clrrwi %r4,%r3,2
- lis %r7,0x7f7f
- rlwinm %r5,%r3,3,27,28
- lwz %r8,0(%r4)
- li %r9,-1
- addi %r7,%r7,0x7f7f
- # That's the setup done, now do the first pair of words.
- # We make an exception and use method (2) on the first two words, to reduce
- # overhead.
- srw %r9,%r9,%r5
- and %r0,%r7,%r8
- or %r10,%r7,%r8
- add %r0,%r0,%r7
- nor %r0,%r10,%r0
- and. %r8,%r0,%r9
- mtcrf 0x01,%r3
- bne done0
- lis %r6,0xfeff
- addi %r6,%r6,-0x101
- # Are we now aligned to a doubleword boundary?
- bt 29,loop
-
- # Handle second word of pair.
- lwzu %r8,4(%r4)
- and %r0,%r7,%r8
- or %r10,%r7,%r8
- add %r0,%r0,%r7
- nor. %r8,%r10,%r0
- bne done0
-
- # The loop.
-
-loop: lwz %r8,4(%r4)
- lwzu %r9,8(%r4)
- add %r0,%r6,%r8
- nor %r10,%r7,%r8
- and. %r0,%r0,%r10
- add %r11,%r6,%r9
- nor %r12,%r7,%r9
- bne done1
- and. %r0,%r11,%r12
- beq loop
-
- and %r0,%r7,%r9
- add %r0,%r0,%r7
- andc %r8,%r12,%r0
- b done0
-
-done1: and %r0,%r7,%r8
- subi %r4,%r4,4
- add %r0,%r0,%r7
- andc %r8,%r10,%r0
-
- # When we get to here, r4 points to the first word in the string that
- # contains a zero byte, and the most significant set bit in r8 is in that
- # byte.
-done0: cntlzw %r11,%r8
- subf %r0,%r3,%r4
- srwi %r11,%r11,3
- add %r3,%r0,%r11
- blr
-0:
- .size strlen,0b-strlen
diff --git a/sysdeps/powerpc/sub_n.S b/sysdeps/powerpc/sub_n.S
new file mode 100644
index 0000000000..7af577d835
--- /dev/null
+++ b/sysdeps/powerpc/sub_n.S
@@ -0,0 +1,68 @@
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(__mpn_sub_n,3,1)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ mtctr %r7
+ bt 31,2f
+
+/* Set the carry (clear the borrow). */
+ subfc %r0,%r0,%r0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ subfc %r6,%r7,%r6
+ stw %r6,0(%r3)
+ beq 1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). This turns
+ out to be important. */
+0:
+ lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ subfe %r8,%r8,%r9
+ stw %r8,4(%r3)
+ subfe %r6,%r7,%r6
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the borrow. */
+1: subfe %r3,%r3,%r3
+ neg %r3,%r3
+ blr
+END(__mpn_sub_n)
diff --git a/sysdeps/powerpc/sub_n.s b/sysdeps/powerpc/sub_n.s
deleted file mode 100644
index 8711bf9a40..0000000000
--- a/sysdeps/powerpc/sub_n.s
+++ /dev/null
@@ -1,69 +0,0 @@
- # Subtract two limb vectors of equal, non-zero length for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- # mp_size_t size)
- # Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601. Almost every other
- # possible 2-unrolled inner loop will not be. Also, watch out for the
- # alignment...
-
- .align 3
- .globl __mpn_sub_n
- .type __mpn_sub_n,@function
- nop
-__mpn_sub_n:
- # Set up for loop below.
- mtcrf 0x01,%r6
- srwi. %r7,%r6,1
- mtctr %r7
- bt 31,2f
-
- # Set the carry (clear the borrow).
- subfc %r0,%r0,%r0
- # Adjust pointers for loop.
- addi %r3,%r3,-4
- addi %r4,%r4,-4
- addi %r5,%r5,-4
- b 0f
-
-2: lwz %r7,0(%r5)
- lwz %r6,0(%r4)
- subfc %r6,%r7,%r6
- stw %r6,0(%r3)
- beq 1f
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601). This turns
- # out to be important.
-0:
- lwz %r9,4(%r4)
- lwz %r8,4(%r5)
- lwzu %r6,8(%r4)
- lwzu %r7,8(%r5)
- subfe %r8,%r8,%r9
- stw %r8,4(%r3)
- subfe %r6,%r7,%r6
- stwu %r6,8(%r3)
- bdnz 0b
- # return the borrow
-1: subfe %r3,%r3,%r3
- neg %r3,%r3
- blr
diff --git a/sysdeps/powerpc/submul_1.S b/sysdeps/powerpc/submul_1.S
new file mode 100644
index 0000000000..80da8ec8c1
--- /dev/null
+++ b/sysdeps/powerpc/submul_1.S
@@ -0,0 +1,52 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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>
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res-s1*s2 and put result back in res; return carry. */
+
+ENTRY(__mpn_submul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(__mpn_submul_1)
diff --git a/sysdeps/powerpc/submul_1.s b/sysdeps/powerpc/submul_1.s
deleted file mode 100644
index 999430d744..0000000000
--- a/sysdeps/powerpc/submul_1.s
+++ /dev/null
@@ -1,52 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C 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.
-
- # mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- # mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res-s1*s2 and put result back in res; return carry.
-
- .align 2
- .globl __mpn_submul_1
- .type __mpn_submul_1,@function
-__mpn_submul_1:
- mtctr %r5
-
- lwz %r0,0(%r4)
- mullw %r7,%r0,%r6
- mulhwu %r10,%r0,%r6
- lwz %r9,0(%r3)
- subf %r8,%r7,%r9
- addc %r7,%r7,%r8 # invert cy (r7 is junk)
- addi %r3,%r3,-4 # adjust res_ptr
- bdz Lend
-
-Loop: lwzu %r0,4(%r4)
- stwu %r8,4(%r3)
- mullw %r8,%r0,%r6
- adde %r7,%r8,%r10
- mulhwu %r10,%r0,%r6
- lwz %r9,4(%r3)
- addze %r10,%r10
- subf %r8,%r7,%r9
- addc %r7,%r7,%r8 # invert cy (r7 is junk)
- bdnz Loop
-
-Lend: stw %r8,4(%r3)
- addze %r3,%r10
- blr
diff --git a/sysdeps/powerpc/test-arith.c b/sysdeps/powerpc/test-arith.c
index c846b0d0ec..9e1be88098 100644
--- a/sysdeps/powerpc/test-arith.c
+++ b/sysdeps/powerpc/test-arith.c
@@ -226,7 +226,7 @@ check_result(int line, const char *rm, tocheck_t expected, tocheck_t actual)
if (memcmp(&expected, &actual, sizeof(tocheck_t)) != 0)
{
unsigned char *ex, *ac;
- int i;
+ size_t i;
printf("%s:%d:round %s:result failed\n"
" expected result 0x", __FILE__, line, rm);
@@ -323,7 +323,7 @@ check_excepts(int line, const char *rm, int expected, int actual)
expected = expected & ~excepts_missing | FE_INVALID_SNAN;
if ((expected & all_exceptions) != actual)
{
- int i;
+ size_t i;
printf("%s:%d:round %s:exceptions failed\n"
" expected exceptions ", __FILE__, line,rm);
for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
@@ -419,7 +419,7 @@ static const optest_t optests[] = {
{__LINE__,B_NEG, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
{__LINE__,B_NEG, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 1,P_Z,P_Z1 },
{__LINE__,B_NEG, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-
+
/* Absolute value. */
{__LINE__,B_ABS, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
{__LINE__,B_ABS, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
@@ -433,7 +433,7 @@ static const optest_t optests[] = {
{__LINE__,B_ABS, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
{__LINE__,B_ABS, 0,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
{__LINE__,B_ABS, 1,P_Z,P_Z1, 0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-
+
/* Square root. */
{__LINE__,B_SQRT, 0,P_Z,P_Z, 0,0,0, R_ALL, 0, 0,P_Z,P_Z },
{__LINE__,B_SQRT, 1,P_Z,P_Z, 0,0,0, R_ALL, 0, 1,P_Z,P_Z },
@@ -459,7 +459,8 @@ static const optest_t optests[] = {
static void
check_op(void)
{
- int i, j;
+ size_t i;
+ int j;
tocheck_t r, a, b, x;
int raised;
@@ -497,7 +498,7 @@ static void
fail_xr(int line, const char *rm, tocheck_t x, tocheck_t r, tocheck_t xx,
int xflag)
{
- int i;
+ size_t i;
unsigned char *cx, *cr, *cxx;
printf("%s:%d:round %s:fail\n with x=0x", __FILE__, line,rm);
@@ -539,7 +540,7 @@ check_sqrt(tocheck_t a)
r0 = delta(r1,-1); r2 = delta(r1,1);
switch (1 << j)
{
- case R_NEAREST:
+ case R_NEAREST:
x0 = r0 * r0 - a; x2 = r2 * r2 - a;
ok = fabs(x0) >= fabs(x1) && fabs(x1) <= fabs(x2);
break;
diff --git a/sysdeps/stub/atomicity.h b/sysdeps/stub/atomicity.h
new file mode 100644
index 0000000000..3916eebbcf
--- /dev/null
+++ b/sysdeps/stub/atomicity.h
@@ -0,0 +1,53 @@
+/* Low-level functions for atomitc operations. ix86 version, x >= 4.
+ Copyright (C) 1997 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 Library General Public License as
+ published by the Free Software Foundation; either version 2 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C 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. */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H 1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (uint32_t *mem, int val)
+{
+ int result = *mem;
+ *mem += val;
+ return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (uint32_t *mem, int val)
+{
+ *mem += val;
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (long int *p, long int oldval, long int newval)
+{
+ if (*p != oldval)
+ return 0;
+
+ *p = newval;
+ return 1;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/stub/ftruncate.c b/sysdeps/stub/ftruncate.c
index b70bbc1746..c84ed4ab1b 100644
--- a/sysdeps/stub/ftruncate.c
+++ b/sysdeps/stub/ftruncate.c
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <errno.h>
+#include <unistd.h>
/* Truncate the file FD refers to to LENGTH bytes. */
int
diff --git a/sysdeps/stub/getdents.c b/sysdeps/stub/getdents.c
index a773347f50..652eda2bc7 100644
--- a/sysdeps/stub/getdents.c
+++ b/sysdeps/stub/getdents.c
@@ -19,6 +19,7 @@
#include <stddef.h>
#include <errno.h>
#include <sys/types.h>
+#include <dirent.h>
ssize_t
__getdirentries (fd, buf, nbytes, basep)
diff --git a/sysdeps/stub/init-posix.c b/sysdeps/stub/init-posix.c
index 0d632d6fb6..8e37bb6861 100644
--- a/sysdeps/stub/init-posix.c
+++ b/sysdeps/stub/init-posix.c
@@ -19,7 +19,7 @@
#ifndef HAVE_GNU_LD
void
-__init_posix ()
+__init_posix (void)
{
return;
}
diff --git a/sysdeps/stub/profil.c b/sysdeps/stub/profil.c
index a0ae3324e9..9613108e3a 100644
--- a/sysdeps/stub/profil.c
+++ b/sysdeps/stub/profil.c
@@ -28,7 +28,7 @@
disable profiling. Returns zero on success, -1 on error. */
int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
{
if (scale == 0)
/* Disable profiling. */
@@ -37,4 +37,5 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
__set_errno (ENOSYS);
return -1;
}
+weak_alias (__profil, profil)
stub_warning (profil)
diff --git a/sysdeps/stub/reboot.c b/sysdeps/stub/reboot.c
index ae4465d1d9..8139aee83f 100644
--- a/sysdeps/stub/reboot.c
+++ b/sysdeps/stub/reboot.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <unistd.h>
+#include <sys/reboot.h>
/* Reboot the system. */
int
diff --git a/sysdeps/stub/swapon.c b/sysdeps/stub/swapon.c
index d580a9a732..cbaa1c2fe3 100644
--- a/sysdeps/stub/swapon.c
+++ b/sysdeps/stub/swapon.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <unistd.h>
+#include <sys/swap.h>
/* Make the block special device PATH available to the system for swapping.
This call is restricted to the super-user. */
diff --git a/sysdeps/stub/syscall.c b/sysdeps/stub/syscall.c
index 183ffc2893..4903b409b5 100644
--- a/sysdeps/stub/syscall.c
+++ b/sysdeps/stub/syscall.c
@@ -18,6 +18,7 @@
#include <sysdep.h>
#include <errno.h>
+#include <unistd.h>
/* Do system call CALLNO, passing it the remaining arguments.
This only makes sense in certain operating systems. */
diff --git a/sysdeps/stub/ualarm.c b/sysdeps/stub/ualarm.c
index d8e0b0aff8..5972e240eb 100644
--- a/sysdeps/stub/ualarm.c
+++ b/sysdeps/stub/ualarm.c
@@ -17,6 +17,7 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
+#include <unistd.h>
/* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds.
If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go
diff --git a/sysdeps/stub/usleep.c b/sysdeps/stub/usleep.c
index 412461b4f9..7ee41b63fa 100644
--- a/sysdeps/stub/usleep.c
+++ b/sysdeps/stub/usleep.c
@@ -17,6 +17,7 @@
Boston, MA 02111-1307, USA. */
#include <errno.h>
+#include <unistd.h>
/* Sleep USECONDS microseconds, or until a previously set timer goes off. */
unsigned int
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index c0ffbcedf6..36863db486 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -26,6 +26,7 @@
#include <bits/libc-lock.h>
/* Try to get a socket to talk to the kernel. */
+#if defined SIOGIFINDEX || defined SIOGIFNAME
static int
opensock (void)
{
@@ -63,6 +64,7 @@ opensock (void)
__libc_lock_unlock (lock);
return fd;
}
+#endif
unsigned int
if_nametoindex (const char *ifname)
diff --git a/sysdeps/unix/sysv/linux/net/if.h b/sysdeps/unix/sysv/linux/net/if.h
index 01e9f00943..f4c1a48579 100644
--- a/sysdeps/unix/sysv/linux/net/if.h
+++ b/sysdeps/unix/sysv/linux/net/if.h
@@ -42,7 +42,10 @@ enum
IFF_MASTER = 0x400, /* Master of a load balancer. */
IFF_SLAVE = 0x800, /* Slave of a load balancer. */
- IFF_MULTICAST = 0x1000 /* Supports multicast. */
+ IFF_MULTICAST = 0x1000, /* Supports multicast. */
+
+ IFF_PORTSEL = 0x2000, /* Can set media type. */
+ IFF_AUTOMEDIA = 0x4000 /* Auto media select active. */
};
/* The ifaddr structure contains information about one address of an
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
index da5ad0eb45..6d240c4b7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
@@ -1,4 +1,4 @@
-/* Definitions for POSIX memory map inerface. Linux/MIPS version.
+/* Definitions for POSIX memory map inerface. Linux/PowerPC version.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -46,26 +46,15 @@
#define MAP_FIXED 0x010 /* Interpret addr exactly. */
#ifdef __USE_MISC
# define MAP_FILE 0x000
-# define MAP_ANONYMOUS 0x800 /* Don't use a file. */
+# define MAP_ANONYMOUS 0x020 /* Don't use a file. */
# define MAP_ANON MAP_ANONYMOUS
#endif
-/* Not used by Linux, but here to make sure we don't clash with ABI
- defines. */
-#ifdef __USE_MISC
-# define MAP_RENAME 0x020 /* Assign page to file. */
-# define MAP_AUTOGROW 0x040 /* File may grow by writing. */
-# define MAP_LOCAL 0x080 /* Copy on fork/sproc. */
-# define MAP_AUTORSRV 0x100 /* Logical swap reserved on demand. */
-#endif
-
/* These are Linux-specific. */
#ifdef __USE_MISC
-# define MAP_GROWSDOWN 0x1000 /* Stack-like segment. */
-# define MAP_DENYWRITE 0x2000 /* ETXTBSY */
-# define MAP_EXECUTABLE 0x4000 /* Mark it as an executable. */
-# define MAP_LOCKED 0x8000 /* Lock the mapping. */
-# define MAP_NORESERVE 0x0400 /* Don't check for reservations. */
+# define MAP_GROWSDOWN 0x0100 /* Stack-like segment. */
+# define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+# define MAP_EXECUTABLE 0x1000 /* Mark it as an executable. */
#endif
/* Flags to `msync'. */
@@ -74,10 +63,11 @@
#define MS_INVALIDATE 2 /* Invalidate the caches. */
/* Flags for `mlockall'. */
-#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
-#define MCL_FUTURE 2 /* Lock all additions to address
+#define MCL_CURRENT 0x2000 /* Lock all currently mapped pages. */
+#define MCL_FUTURE 0x4000 /* Lock all additions to address
space. */
+
/* Flags for `mremap'. */
#ifdef __USE_GNU
# define MREMAP_MAYMOVE 1
diff --git a/sysdeps/unix/sysv/linux/powerpc/brk.c b/sysdeps/unix/sysv/linux/powerpc/brk.S
index e9826bd098..f4a3f3bcec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/brk.c
+++ b/sysdeps/unix/sysv/linux/powerpc/brk.S
@@ -18,30 +18,32 @@
Boston, MA 02111-1307, USA. */
#include <sysdep.h>
-#include <errno.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
+
+ .comm __curbrk,4,4
+ .section ".text"
+ENTRY(__brk)
+ stwu %r1,-16(%r1)
+ stw %r3,8(%r1)
+ DO_CALL(SYS_ify(brk))
+ lwz %r6,8(%r1)
+#ifdef PIC
+ mflr %r4
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr %r5
+ lwz %r5,__curbrk@got(%r5)
+ mtlr %r4
+ stw %r3,0(%r5)
+#else
+ stw %r3,__curbrk@sdarel(%r13)
+#endif
+ cmplw %r6,%r3
+ addi %r1,%r1,16
+ li %r3,0
+ blelr+
+ li %r3,ENOMEM
+ b JUMPTARGET(__syscall_error)
+END (__brk)
-void *__curbrk;
-
-int
-__brk (void *addr)
-{
- register void *syscall_arg asm ("r3") = addr;
- register int syscall_number asm ("r0") = SYS_ify (brk);
- register void *newbrk asm ("r3");
- asm ("sc"
- : "=r" (newbrk)
- : "r" (syscall_arg), "r" (syscall_number)
- : "r4","r5","r6","r7","r8","r9","r10","r11","r12",
- "ctr", "mq", "cr0", "cr1", "cr6", "cr7");
-
- __curbrk = newbrk;
-
- if (newbrk < addr)
- {
- __set_errno (ENOMEM);
- return -1;
- }
-
- return 0;
-}
weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/powerpc/clone.S b/sysdeps/unix/sysv/linux/powerpc/clone.S
index cca63fe0bc..6209922b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/clone.S
@@ -30,13 +30,12 @@
ENTRY(__clone)
/* Set up stack frame, save registers. */
stwu %r1,-32(%r1)
- stw %r31,16(%r1)
- stw %r30,20(%r1)
-
/* Check for child_stack == NULL || fn == NULL. */
cmpwi %cr0,%r4,0
- beq- %cr0,badargs
+ stw %r31,16(%r1)
cmpwi %cr1,%r3,0
+ stw %r30,20(%r1)
+ beq- %cr0,badargs
beq- %cr1,badargs
/* Set up stack frame for child. */
@@ -45,7 +44,7 @@ ENTRY(__clone)
li %r0,0
stw %r0,0(%r4)
- /* Save new stack, fn, args across syscall. */
+ /* Save fn, args across syscall. */
mr %r30,%r3 /* Function in r30. */
mr %r31,%r6 /* Arguments in r31. */
@@ -70,21 +69,15 @@ child:
mr %r3,%r31
blrl
/* Call _exit with result from procedure. */
-#ifdef PIC
- b _exit@plt
-#else
- b _exit
-#endif
+ b JUMPTARGET(_exit)
badargs:
- li 3,-EINVAL
+ li %r3,EINVAL
error:
-#ifdef PIC
- b __syscall_error@plt
-#else
- b __syscall_error
-#endif
-
-PSEUDO_END (__clone)
+ lwz %r31,16(%r1)
+ lwz %r30,20(%r1)
+ addi %r1,%r1,32
+ b JUMPTARGET(__syscall_error)
+END (__clone)
weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
index fed0913574..4be6f11270 100644
--- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
@@ -17,10 +17,18 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <signal.h>
+#include <sys/ptrace.h>
+
+/* You can also do this by using
+ void
+ profil_counter (int signo, struct pt_regs *pt)
+ {
+ profil_count ((void *) pt->nip);
+ }
+ */
void
-profil_counter (int signo, struct sigcontext sc)
+profil_counter (int signo, void **regs)
{
- profil_count ((void *) sc.regs->nip);
+ profil_count (regs[PT_NIP]);
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
index 748c26761f..9b9413e2f3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
+++ b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
@@ -18,9 +18,6 @@
#include <sysdep.h>
-/* The 'sigreturn' syscall does not return. */
-
- .text
-ENTRY(__sigreturn)
- DO_CALL(SYS_ify(sigreturn))
-PSEUDO_END (__sigreturn)
+PSEUDO (__sigreturn, sigreturn, 1)
+ /* Shouldn't get here. */
+PSEUDO_END(__sigreturn)
diff --git a/sysdeps/unix/sysv/linux/powerpc/socket.S b/sysdeps/unix/sysv/linux/powerpc/socket.S
index 904bca4dc3..681f7e6445 100644
--- a/sysdeps/unix/sysv/linux/powerpc/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/socket.S
@@ -71,17 +71,11 @@ ENTRY(P(__,socket))
#if NARGS >= 9
#error too many arguments!
#endif
- li %r3,P(SOCKOP_,socket)
- addi %r4,%r1,stackblock
+ li %r3,P(SOCKOP_,socket)
+ addi %r4,%r1,stackblock
DO_CALL(SYS_ify(socketcall))
- addi %r1,%r1,48
- bnslr
-#ifdef PIC
- b __syscall_error@plt
-#else
- b __syscall_error
-#endif
-
+ addi %r1,%r1,48
+ PSEUDO_RET
PSEUDO_END (P(__,socket))
weak_alias (P(__,socket), socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
index 2cb548245b..4d55076907 100644
--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
@@ -18,7 +18,6 @@
#include <sysdep.h>
- .text
ENTRY (syscall)
mr %r0,%r3
mr %r3,%r4
@@ -27,10 +26,5 @@ ENTRY (syscall)
mr %r6,%r7
mr %r7,%r8
sc
- bnslr
-#ifdef PIC
- b __syscall_error@plt
-#else
- b __syscall_error
-#endif
+ PSEUDO_RET
PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 577809acb8..944793d56f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -31,32 +31,113 @@
#ifdef ASSEMBLER
-#define ENTRY(name) \
- .globl name; \
- .type name,@function; \
- .align 2; \
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a the return address being on the stack
+ to locate our caller and so it can restore it; so store one just
+ for its benefit. */
+#ifdef PIC
+#define CALL_MCOUNT \
+ .pushsection; \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ stw %r0,4(%r1); \
+ bl _GLOBAL_OFFSET_TABLE_@local-4; \
+ mflr %r11; \
+ lwz %r0,0b@got(%r11); \
+ bl JUMPTARGET(_mcount);
+#else /* PIC */
+#define CALL_MCOUNT \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ lis %r11,0b@ha; \
+ stw %r0,4(%r1); \
+ addi %r0,%r11,0b@l; \
+ bl JUMPTARGET(_mcount);
+#endif /* PIC */
+#else /* PROF */
+#define CALL_MCOUNT /* Do nothing. */
+#endif /* PROF */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#ifdef PROF
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT \
+ b 0f; \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ 0:
+#else /* PROF */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
C_LABEL(name)
+#endif
+
+#undef END
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
#define DO_CALL(syscall) \
li 0,syscall; \
sc
#ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
#define PSEUDO(name, syscall_name, args) \
.section ".text"; \
ENTRY (name) \
- DO_CALL (SYS_ify (syscall_name)); \
+ DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET \
bnslr; \
- b __syscall_error@plt
-#else
-#define PSEUDO(name, syscall_name, args) \
- .section ".text"; \
- ENTRY (name) \
- DO_CALL (SYS_ify (syscall_name)); \
- bnslr; \
- b __syscall_error
-#endif
+ b JUMPTARGET(__syscall_error)
+#define ret PSEUDO_RET
+
+#undef PSEUDO_END
+#define PSEUDO_END(name) \
+ END (name)
-#define ret /* Nothing (should be 'blr', but never reached). */
+/* Local labels stripped out by the linker. */
+#define L(x) .L##x
#endif /* ASSEMBLER */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
index 8a14f99f43..46867d8e41 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
@@ -33,10 +33,10 @@
#undef TCSETS
#undef TCSETSW
#undef TCSETSF
-#define TCGETS _IOR ('t', 19, struct __kernel_termios)
-#define TCSETS _IOW ('t', 20, struct __kernel_termios)
-#define TCSETSW _IOW ('t', 21, struct __kernel_termios)
-#define TCSETSF _IOW ('t', 22, struct __kernel_termios)
+#define TCGETS _IOR ('T', 8, struct __kernel_termios)
+#define TCSETS _IOW ('T', 9, struct __kernel_termios)
+#define TCSETSW _IOW ('T', 10, struct __kernel_termios)
+#define TCSETSF _IOW ('T', 11, struct __kernel_termios)
#include <linux/sockios.h>
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
index bf7aa1480f..54ac773b70 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
@@ -20,9 +20,9 @@
#ifndef _SPARC_TERMBITS_H
#define _SPARC_TERMBITS_H 1
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned long tcflag_t;
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
#define NCCS 17
struct termios
@@ -31,11 +31,11 @@ struct termios
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
+ cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
#ifdef __KERNEL__
#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
- cc_t _x_cc[2]; /* We need them to hold vmin/vtime */
+ cc_t _x_cc[2]; /* We need them to hold vmin/vtime */
#endif
};
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
index c4563776b6..bcc134e09c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -44,3 +44,5 @@ ENTRY(longjmp)
END(longjmp)
strong_alias(longjmp, __longjmp)
+eak_alias(longjmp, _longjmp)
+weak_alias(longjmp, siglongjmp)
diff --git a/sysdeps/vax/strcmp.s b/sysdeps/vax/strcmp.s
new file mode 100644
index 0000000000..c9c5b479ae
--- /dev/null
+++ b/sysdeps/vax/strcmp.s
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+ .asciz "@(#)strcmp.s 5.6 (Berkeley) 6/1/90"
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Compare string s1 lexicographically to string s2.
+ * Return:
+ * 0 s1 == s2
+ * > 0 s1 > s2
+ * < 0 s2 < s2
+ *
+ * strcmp(s1, s2)
+ * char *s1, *s2;
+ */
+#include "DEFS.h"
+
+ENTRY(strcmp, 0)
+ movl 4(ap),r1 # r1 = s1
+ movl 8(ap),r3 # r3 = s2
+ subb3 (r3),(r1),r0 # quick check for first char different
+ beql 1f # have to keep checking
+ cvtbl r0,r0
+ ret
+1:
+ clrl r5 # calculate min bytes to next page boundary
+ subb3 r1,$255,r5 # r5 = (bytes - 1) to end of page for s1
+ subb3 r3,$255,r0 # r0 = (bytes - 1) to end of page for s2
+ cmpb r0,r5 # r5 = min(r0, r5);
+ bgtru 2f
+ movb r0,r5
+2:
+ incl r5 # r5 = min bytes to next page boundary
+ cmpc3 r5,(r1),(r3) # compare strings
+ bneq 3f
+ subl2 r5,r1 # check if found null yet
+ locc $0,r5,(r1)
+ beql 1b # not yet done, continue checking
+ subl2 r0,r3
+ mnegb (r3),r0 # r0 = '\0' - *s2
+ cvtbl r0,r0
+ ret
+3:
+ subl2 r0,r5 # check for null in matching string
+ subl2 r5,r1
+ locc $0,r5,(r1)
+ bneq 4f
+ subb3 (r3),(r1),r0 # r0 = *s1 - *s2
+ cvtbl r0,r0
+ ret
+4:
+ clrl r0 # both the same to null
+ ret