diff options
author | Ulrich Drepper <drepper@redhat.com> | 1997-09-11 12:09:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1997-09-11 12:09:10 +0000 |
commit | 9a0a462ceb4ab96c909b182f3052de2ef13fbe3a (patch) | |
tree | 59456497b6acefe69aab04fc28c38ea38852ccc7 /sysdeps | |
parent | 26b4d7667169f8db26fd8194b3c498ec58e50f90 (diff) | |
download | glibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.tar.gz glibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.tar.xz glibc-9a0a462ceb4ab96c909b182f3052de2ef13fbe3a.zip |
Update.
1997-09-11 04:36 Ulrich Drepper <drepper@cygnus.com> * db2/db_int.h: Define __set_errno if not yet available. * db2/btree/bt_rec.c: Use __set_errno to set errno value. * db2/clib/getlong.c: Likewise. * db2/db185/db185.c: Likewise. * db2/db185/db185_int.h: Likewise. * db2/dbm/dbm.c: Likewise. * db2/lock/lock_deadlock.c: Likewise. * db2/log/log_archive.c: Likewise. * elf/dl-profile.c: Implement mcount function. * gmon/gmon.c: Use __profil not profil because of namespace pollution. * gmon/mcount.c: Remove BSD kernel code. Use compare&swap instruction if possible to change state variable. Optimize frompc folding. * gmon/sys/gmon.h (struct gmonparam): Change state field to long int. * sysdeps/i386/i486/atomicity.h: New file. * sysdeps/stub/atomicity.h: New file. * sysdeps/mach/hurd/profil.c: Define function as __profil and make profil weak alias. * sysdeps/posix/profil.c: Likewise. * string/bits/string2.h: New file. * include/bits/string2.h: New file. * string/Makefile (routines): Add mempcpy. (tests): Add inl-tester. Remove _D__NO_STRING_INLINES from CFLAGS-* variables. * sysdeps/generic/mempcpy.c: New file. * sysdeps/generic/memccpy.c: Undef function name to enable definition as macro. * sysdeps/generic/memchr.c: Likewise. * sysdeps/generic/memcmp.c: Likewise. * sysdeps/generic/memmem.c: Likewise. * sysdeps/generic/memmove.c: Likewise. * sysdeps/generic/strcat.c: Likewise. * sysdeps/generic/strchr.c: Likewise. * sysdeps/generic/strcmp.c: Likewise. * sysdeps/generic/strcpy.c: Likewise. * sysdeps/generic/strcspn.c: Likewise. * sysdeps/generic/strlen.c: Likewise. * sysdeps/generic/strncat.c: Likewise. * sysdeps/generic/strncmp.c: Likewise. * sysdeps/generic/strncpy.c: Likewise. * sysdeps/generic/strpbrk.c: Likewise. * sysdeps/generic/strrchr.c: Likewise. * sysdeps/generic/strsep.c: Likewise. * sysdeps/generic/strspn.c: Likewise. * sysdeps/generic/strstr.c: Likewise. * sysdeps/generic/strtok.c: Likewise. * sysdeps/generic/strtok_r.c: Likewise. * sysdeps/i386/memset.c: Likewise. * sysdeps/i386/bits/string.h: Correct a few types and constraints. * sysdeps/i386/i486/bits/string.h: Heavy rewrites and optimizations. * string/stratcliff.c: Undefine __USE_STRING_INLINES. * string/tst-strlen.c: Likewise. * string/string.h: Add prototype for mempcpy. Include bits/string2.h header always if optimizing. * intl/dcgettext.c: Don't unconditionally define stpcpy, only if not yet defined. * intl/l10nflist.c: Likewise. * string/tester.c: Add copyright and make little cleanups. * inet/test_ifindex.c: Change type of ni variable to unsigned int. * locale/programs/ld-ctype.c (struct locale_ctype_t): Change type of fields map_collection_max and map_collection_act to size_t. * nss/libnss_files.map: Group entries. * posix/unistd.h: Add prototype for __setpgid and __profil. * sysdeps/generic/crypt.h: Declare __crypt_r. * sysdeps/i386/bits/select.h: Fix fatal bugs, use correct casts now. * sysdeps/i386/fpu/bits/mathinline.h (isgreater, isgreaterequal, isless, islessequal, islessgreater, isunordered): Optimize a bit. * sysdeps/stub/ftruncate.c: Include missing header for prototype. * sysdeps/stub/getdents.c: Likewise. * sysdeps/stub/reboot.c: Likewise. * sysdeps/stub/swapon.c: Likewise. * sysdeps/stub/syscall.c: Likewise. * sysdeps/stub/ualarm.c: Likewise. * sysdeps/stub/usleep.c: Likewise. * sysdeps/unix/sysv/linux/if_index.c: Don't compile or use opensock if SIOGIFINDEX and SIOGIFNAME are not defined. * sysdeps/unix/sysv/linux/net/if.h: Add IFF_PORTSEL and IFF_AUTOMEDIA according to recent kernel changes. 1997-09-10 21:32 Klaus Espenlaub <kespenla@student.informatik.uni-ulm.de> * Makeconfig: Use $(have-initfini) instead of $(elf) to figure out the installed name of the startup code. (common-generated): Add version.mk. * Makefile (distclean-1): Add glibcbug. * Makerules: Replace -lgcc by $(gnulib). * catgets/Makefile (generated): Add xmalloc.o. * csu/Makefile (generated): Replace align.h and end.h by defs.h to match the generated file. * manual/Makefile (mostlyclean): Add stub-manual and stamp.o. (realclean): Changed to remove chapters-incl[12]. * po/Makefile (realclean): New rule to remove the generated .mo files. * time/Makefile: Only include zonefile dependencies if $(no_deps) is not true to avoid make clean failure when directory time doesn't exist yet. (generated): Add tzselect. * stdio/fgets.c (fgets): Add casts to reduce gcc warning noise. * stdio/internals.c (flushbuf): Likewise. * stdio/linewrap.c (lwupdate): Likewise. * stdio/memstream.c (enlarge_buffer): Likewise. * stdio-common/vfscanf.c (_IO_vfscanf): Likewise. * time/tzset.c (compute_change): Likewise. * misc/init-misc.c (__init_misc): Only declare static if HAVE_GNU_LD is defined. * sysdeps/posix/pipestream.c (FUNC): Change to generate ANSI C style functions. * sysdeps/stub/init-posix.c: Likewise. * sysdeps/stub/profil.c: Likewise. * munch-tmpl.c (__libc_init): Convert to ANSI C style declaration to reduce gcc warning noise. * stdio/glue.c (_filbuf, _flsbuf): Likewise. * stdio/obstream.c (grow, seek, input, init_obstream): Likewise. * stdio/vasprintf.c (enlarge_buffer): Likewise. * sysdeps/generic/sysd-stdio.c (__stdio_read, __stdio_write, __stdio_seek, __stdio_close, __stdio_fileno, __stdio_open, __stdio_reopen): Likewise. * sysdeps/posix/defs.c (_cleanup): Likewise. * time/offtime.c (__offtime): Add cast. * posix/getopt.c: Don't use text_set_element if not defined. * configure.in: Provide a check for underscores before user labels that works even when the compiler used for building doesn't work (like when there is no C library). Use the old way if the compiler works. 1997-09-10 05:08 David S. Miller <davem@caip.rutgers.edu> * sysdeps/unix/sysv/linux/sparc/bits/ioctls.h: The TC* ioctls use 'T' not 't' on SparcLinux. * sysdeps/unix/sysv/linux/sparc/bits/termios.h: tcflag_t is 32 bits. * sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S: Add aliases for _longjmp and siglongjmp. 1997-09-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * libio/stdio.h: Add format attributes to the extra printf and scanf like functions. * stdio/stdio.h: Likewise. 1997-09-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r): Print tablename_val, not tablename_len. * nis/nss_nisplus/nisplus-ethers.c (_nss_nisplus_getntohost_r): Use sprintf instead of sprintf, the string always fits. * nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_gethostbyaddr_r): Likewise. * nis/nss_nisplus/nisplus-network.c (_nss_nisplus_getnetbyaddr_r): Likewise. * nis/nss_nisplus/nisplus-proto.c (_nss_nisplus_getprotobynumber_r): Likewise. * nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_getrpcbynumber_r): Likewise. * nis/nss_nisplus/nisplus-service.c (_nss_nisplus_getservbynumber_r): Likewise. * nis/nss_nisplus/nisplus-alias.c (_nss_create_tablename): Use __stpcpy, __stpncpy and __strdup instead of public names. * nis/nss_nisplus/nisplus-ethers.c (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-grp.c (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-hosts.c (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_parse_netgroup): Likewise. * nis/nss_nisplus/nisplus-network.c (_nss_nisplus_parse_netent): Likewise. (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-proto.c (_nss_nisplus_parse_protoent): Likewise. (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-pwd.c (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-rpc.c (_nss_nisplus_parse_rpcent): Likewise. (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-service.c (_nss_nisplus_parse_servent): Likewise. (_nss_create_tablename): Likewise. * nis/nss_nisplus/nisplus-spwd.c (_nss_create_tablename): Likewise. * libc.map: Export __stpcpy and __strdup. 1997-09-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * math/Makefile (CFLAGS-test-float.c, CFLAGS-test-double.c, CFLAGS-test-ldouble.c): Pass -ffloat-store to avoid excessive precision. 1997-09-09 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * include/rpc/auth_des.h: New file. 1997-09-09 Paul Eggert <eggert@twinsun.com> * time/mktime.c (__mktime_internal): Declare sec_requested even if !LEAP_SECONDS_POSSIBLE, since it's needed at the end when checking for time_t overflow. 1997-09-09 22:11 Ulrich Drepper <drepper@cygnus.com> * sysdeps/posix/getcwd.c: Correct test for too small buffer. Reported by Erik Troan <ewt@redhat.com>. * elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>. * elf/dl-open.c: Likewise. 1997-09-07 17:09 Richard Henderson <rth@cygnus.com> * sysdeps/alpha/Makefile: Kill setjmp_aux. * sysdeps/alpha/bits/setjmp.h: Rewrite in terms of an array. * sysdeps/alpha/__longjmp.c: Remove. * sysdeps/alpha/setjmp_aux.c: Remove. * sysdeps/alpha/__longjmp.S: New file. * sysdeps/alpha/bsd-_setjmp.S: Stub out. * sysdeps/alpha/bsd-setjmp.S: Likewise. * sysdeps/alpha/setjmp.S: Do the work; don't call __setjmp_aux. Move _setjmp and setjmp from bsd-*.S. 1997-09-06 20:20 Ulrich Drepper <drepper@cygnus.com> * include/rpc/auth.h: New file. * include/rpc/auth_unix.h: New file. 1997-09-06 Paul Eggert <eggert@twinsun.com> Fix gmtime so that it reports leap seconds when TZ indicates that leap seconds are desired. * time/gmtime.c (<stddef.h>): Remove unnecessary include. (gmtime): Put after gmtime_r, to help the compiler inline. (__tz_convert): New decl. (gmtime_r): Use __tz_convert instead of __offtime, so that leap seconds are handled correctly. * time/localtime.c (<errno.h>, <libc-lock.h>): Remove includes that are now unnecessary. (__tzset_internal, __tz_compute, __tzfile_compute, __use_tzfile, __tzset_lock): Remove extern decls that are now unnecessary. (localtime_internal): Moved to __tz_convert in tzset.c. so that localtime and gmtime can both use it easily. (localtime): Put after localtime_r, to help the compiler inline. (localtime_r): Use __tz_convert instead of localtime_internal. * time/strftime.c (__tz_compute): Remove unused (and now incorrect) decl. * time/tzfile.c (__tzfile_compute): New arg USE_LOCALTIME. * time/tzset.c (<errno.h>): Include. (_tmbuf): New decl. (__tzfile_compute): New function. (tz_compute): Renamed from __tz_compute. No longer extern. Remove redundant call to tzset_internal. (tzset_internal): Renamed from __tzset_internal. No longer extern. (tzset_lock): Renamed from __tzset_lock. No longer extern. (__tz_convert): New function, containing functionality of old localtime_internal function, plus locking and optional UTC. 1997-09-06 Paul Eggert <eggert@twinsun.com> * time/tzfile.c (__tzfile_read): Don't read a file if TZ is the empty string, just use UTC without leap seconds. This is for compatibility with the Olson code. 1997-09-06 Paul Eggert <eggert@twinsun.com> * time/tzset.c (__tzname_max): Lock tz data structures before invoking tzset_internal. * time/tzfile.c: Define compute_tzname_max statically. 1997-09-07 10:57 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * nis/nis_call.c: Remove not longer necessary HAVE_SECURE_RPC ifdefs. * nis/nis_intern.h: Likewise. * nis/nss_nis/nis-publickey.c: Likewise. * nis/nss_nisplus/nisplus-publickey.c: Likewise. * nis/ypclnt.c: Likewise. * sunrpc/auth_des.c: Don't dereference NULL pointer, initialize ad->ad_timediff. * sunrpc/auth_none.c: Don't define our own prototypes, use the one from the header files. * sunrpc/auth_unix.c: Likewise. * sunrpc/clnt_raw.c: Likewise. * sunrpc/clnt_tcp.c: Likewise. * sunrpc/rpc_cmsg.c: Likewise. * sunrpc/key_call.c: Fix signal handling. * sunrpc/openchild.c: Don't use /bin/sh to start /usr/etc/keyenvoy, or we will get a deadlock with NIS+. * sunrpc/rpc/auth.h: Add prototype for xdr_opaque_auth, don't define HAVE_SECURE_RPC. 1997-09-07 15:51 Ulrich Drepper <drepper@cygnus.com> * sysdeps/i386/bits/select.h [__GNUC__] (__FD_ZERO, __FD_SET, __FD_CLR, __FD_ISSET): Use correct casts to address array correctly. Reported by urbanw@cs.umu.se. 1997-09-07 05:07 Ulrich Drepper <drepper@cygnus.com> * elf/dl-close.c: Include <bits/libc-lock.h>, not <libc-lock.h>. * elf/dl-open.c: Likewise. * sysdeps/i386/memset.c: Undefine memset in case the header with the optimized functions is included. Patches by NIIBE Yutaka <gniibe@mri.co.jp>. * sysdeps/i386/bits/string.h [__PIC__] (strcspn, strspn, strpbrk, strsep): Use register for second parameter. * sysdeps/i386/i486/bits/string.h: Likewise. Reported by NIIBE Yutaka <gniibe@mri.co.jp>. 1997-09-03 09:48 Geoff Keating <geoffk@ozemail.com.au> * math/libm-test.c: Change various tolerances to match what the tested routines can actually provide. * math/Makefile: Add new tests. * math/atest-sincos.c: New file. * math/atest-exp.c: New file. * csu/Makefile: Give initfini.s and initfiniS.s their own CFLAGS-* macros so they can be overridden. * sysdeps/powerpc/Makefile [subdir=csu]: Override flags for initfiniS.s to use -fpic instead of -fPIC, because the sed script breaks otherwise. * sysdeps/powerpc/Makefile [build-shared]: Use -fpic not -fPIC for efficiency. * sysdeps/powerpc/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE): Don't use register 0, to let _mcount be in a shared object. * sysdeps/powerpc/dl-machine.h: Use full sentences in comments. Generally clean up. Suppress some code we don't need when relocating ld.so. * sysdeps/powerpc/test-arith.c: Change loop indices to size_t when appropriate to suppress gcc warning. * resolv/res_send.c: Suppress warning. * sunrpc/xdr_sizeof.c: Suppress warning. * FAQ: Add ppc-linux. * manual/maint.texi: Add ppc-linux. Explain that gcc can't build it yet. * sysdeps/unix/sysv/linux/powerpc/profil-counter.h: Correct for current kernels. 1997-08-15 07:45 Geoff Keating <geoffk@ozemail.com.au> * stdlib/fmtmsg.c: Use two parameters for __libc_once_define. * sysdeps/i386/machine-gmon.h: Correct typo. * sysdeps/unix/sysv/linux/powerpc/bits/mman.h: Change to match kernel. * sysdeps/generic/dl-sysdep.c: Add hook for bizzare PPC argument hack. * sysdeps/unix/sysv/linux/powerpc/dl-sysdep.c: Rewrite to use sysdeps/linux/dl-sysdep.c. * sysdeps/powerpc/Makefile [subdir=gmon]: Compile ppc-mcount. * sysdeps/powerpc/machine-gmon.h: Use ppc-mcount. * sysdeps/powerpc/ppc-mcount: New file. The following are mostly changes to allow profiling: * sysdeps/powerpc/add_n.S: Added. * sysdeps/powerpc/add_n.s: Removed. * sysdeps/powerpc/addmul_1.S: Added. * sysdeps/powerpc/addmul_1.s: Removed. * sysdeps/powerpc/bsd-_setjmp.S: Use JUMPTARGET macro. * sysdeps/powerpc/bsd-setjmp.S: Use JUMPTARGET macro. * sysdeps/powerpc/lshift.S: Added. * sysdeps/powerpc/lshift.s: Removed. * sysdeps/powerpc/memset.S: Added. * sysdeps/powerpc/memset.s: Removed. * sysdeps/powerpc/mul_1.S: Added. * sysdeps/powerpc/mul_1.s: Removed. * sysdeps/powerpc/rshift.S: Added. * sysdeps/powerpc/rshift.s: Removed. * sysdeps/powerpc/s_copysign.S: Use ENTRY, END, weak_alias macros. * sysdeps/powerpc/s_fabs.S: Use ENTRY, END, weak_alias macros. * sysdeps/powerpc/setjmp.S: Use JUMPTARGET macro. * sysdeps/powerpc/strchr.S: Added. * sysdeps/powerpc/strchr.s: Removed. * sysdeps/powerpc/strcmp.S: Added. * sysdeps/powerpc/strcmp.s: Removed. * sysdeps/powerpc/strlen.S: Added. * sysdeps/powerpc/strlen.s: Removed. * sysdeps/powerpc/sub_n.S: Added. * sysdeps/powerpc/sub_n.s: Removed. * sysdeps/powerpc/submul_1.S: Added. * sysdeps/powerpc/submul_1.s: Removed. * sysdeps/unix/sysv/linux/powerpc/_exit.S: Removed. * sysdeps/unix/sysv/linux/powerpc/brk.S: Added. * sysdeps/unix/sysv/linux/powerpc/brk.c: Removed. * sysdeps/unix/sysv/linux/powerpc/clone.S: Use new macros. Fix various bugs. Document that it isn't tested. * sysdeps/unix/sysv/linux/powerpc/sigreturn.S: Make look like sysdeps/unix/_exit.S. * sysdeps/unix/sysv/linux/powerpc/socket.S: Use new macros. * sysdeps/unix/sysv/linux/powerpc/syscall.S: Use new macros. * sysdeps/unix/sysv/linux/powerpc/sysdep.h: Define some new macros to make assembler (possibly) more portable, allow profiling, etc.
Diffstat (limited to 'sysdeps')
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 |