diff options
author | Roland McGrath <roland@gnu.org> | 1996-03-19 20:21:54 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-03-19 20:21:54 +0000 |
commit | b20e47cb14ec8edccab7c722743a731e67280702 (patch) | |
tree | 2606832a6d914c9c629494cb47b8a87b1d95f40a /sysdeps | |
parent | e384537164e04d46fe1749899715abd72d33c54e (diff) | |
download | glibc-b20e47cb14ec8edccab7c722743a731e67280702.tar.gz glibc-b20e47cb14ec8edccab7c722743a731e67280702.tar.xz glibc-b20e47cb14ec8edccab7c722743a731e67280702.zip |
Tue Mar 19 14:18:42 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/bsd/pause.c: Moved to sysdeps/unix/common/pause.c. Mon Mar 4 20:17:28 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/adjtime.c: Use INT_MAX instead of LONG_MAX. * sysdeps/unix/sysv/Makefile (sysdep_routines): Don't add s_getdents. * sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Don't add mount, umount. * sysdeps/alpha/__math.h (atan, cabs): New functions. * sysdeps/unix/sysv/linux/alpha/sigsuspend.S: new file (syscall expects set-value, not pointer to it). Sun Feb 25 22:36:10 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/alpha/profil-counter.h: New file. * gmon/gmon.c (__bb_head): new variable. (write_hist, write_call_graph, write_bb_counts): new functions. (_mcleanup): modified to call above functions instead of directly writing out gmon.out. * gmon/sys/gmon.h (struct __bb): New type. (struct gmonhdr): Type removed. (struct gmonparam): New member `log_hashfraction'. (GMONVERSION): Macro removed. * gmon/sys/gmon_out.h, gmon/bb_exit_func.c, sysdeps/generic/bb_init_func.c, sysdeps/alpha/bb_init_func.S: new files. * gmon/Makefile (headers): Add sys/gmon_out.h. (routines): Add bb_init_func, bb_exit_func. * gmon/mcount.c: Avoid integer division. Wed Feb 21 23:56:41 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/alpha/setjmp.S: switched order in which sp and fp are passed to match what __sigsetjmp_aux() expects. Tue Feb 20 11:33:46 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/alpha/syscalls.list (select, bind, connect, getpeername, getsockname, listen, recv, recvfrom, recvmsg, send, sendmsg, sendto, setsockopt, shutdown, socketpair): added to override same-name assembly file in the parent directory. * stdlib/stdlib.h: add include of sys/types.h in front of random etc declarations to ensure int32_t is declared. * stdlib/random.c, stdlib/random_r.c: replaced "long int" by int32_t where 32 bit integers are required. Also change LONG_MAX into 0x7fffffff since the intent is to turn off the sign bit in a 32 bit integer. * time/offtime.c (__offtime): Use Paul Eggert's code to deal with very large values for "days" (e.g., 64 bit values). Mon Feb 19 22:22:12 1996 David Mosberger-Tang <davidm@azstarnet.com> * stdlib/stdlib.h (__random, __random_r, random_r, struct random_data): use int32_t instead of `long int'. Sat Feb 17 11:29:29 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/alpha/ioperm.c: new file. * sysdeps/alpha/ffs.S: new file. * sysdeps/alpha/fabs.c: File removed. * time/tzfile.c (__tzfile_read): counter variable is i, *not* num_transitions! * time/offtime.c: make capable of dealing with very large (64 bit) time_t values. Use old algorithm until a year is reached that is an integer multiple of 400, then use DAYS_PER_400_YEARS to do the remainder in a single division. * sysdeps/generic/ffs.c (ffs): fix variable declarations to be unsigned int, not unsigned long. * string/test-ffs.c (main): add test case with all upper bits set. * stdlib/tst-strtol.c: add tests cases for machines where sizeof(long)==8. * stdlib/testrand.c (main): disallow rand() to return negative integers. * stdlib/testmb.c (main): fix format to use %lx instead of %x. * stdlib/stdlib.h: on 64 bit machines, declare struct random_data, __random(), __random_r, and random_r to return "int" instead of "long int". * stdlib/random_r.c: 64 bit machines use "int" instead of "long int". Similarly, use INT_MAX instead of LONG_MAX. * stdlib/random.c: on 64 bit machines, randtbl[] and __random[] need to operate on "int" instead of "long int". * locale/locfile-hash.c (compute_hashval): make shifted constant a long to avoid loosing bits on 64 bit machines. * dirent/tst-seekdir.c (main): fix confusing comment; print a line to mark point where directory is rewound. Fri Feb 16 15:01:49 1996 David Mosberger-Tang <davidm@azstarnet.com> * time/strftime.c (strftime): any hour > 11 is PM (not > 12!). Wed Feb 14 00:21:17 1996 David Mosberger-Tang <davidm@azstarnet.com> * sysdeps/unix/sysv/linux/alpha/Makefile, sysdeps/unix/sysv/linux/alpha/brk.S, sysdeps/unix/sysv/linux/alpha/fpu_control.c, sysdeps/unix/sysv/linux/alpha/fpu_control.h, sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S, sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S, sysdeps/unix/sysv/linux/alpha/pipe.S, sysdeps/unix/sysv/linux/alpha/setfpucw.c, sysdeps/unix/sysv/linux/alpha/sigprocmask.c, sysdeps/unix/sysv/linux/alpha/speed.c, sysdeps/unix/sysv/linux/alpha/start.S, sysdeps/unix/sysv/linux/alpha/syscall.S, sysdeps/unix/sysv/linux/alpha/syscalls.list, sysdeps/unix/sysv/linux/alpha/alpha/regdef.h, sysdeps/unix/sysv/linux/alpha/sysdep.S, sysdeps/unix/sysv/linux/alpha/sysdep.h: New files. * sysdeps/alpha/setjmp_aux.c (__sigsetjmp_aux): restore return address register before returning (gcc 2.7.1 doesn't do it, presumably because $26 is declared as a global variable). * sysdeps/unix/sysv/linux/sys/mman.h: msync was missing "flags" argument. * sysdeps/unix/alarm.c (alarm): do roundup using test & increment instead of multiplication. * sysdeps/posix/sleep.c (sleep): initialize sa_mask to mask of currently blocked signals instead of the empty mask to ensure that execution of alarm handler occurs with none of the currently blocked signals enabled. * sysdeps/unix/alpha/sysdep.h: new file (adapted from OSF/1 version). * sysdeps/unix/bsd/osf/alpha/sysdep.h: include sysdeps/unix/alpha/sysdep.h and removed definitions now in that file. * sysdeps/alpha/divrem.S, sysdeps/alpha/htonl.S, sysdeps/alpha/htons.S, sysdeps/alpha/machine-gmon.h, sysdeps/alpha/_mcount.S, sysdeps/alpha/ntohl.s, sysdeps/alpha/ntohs.s, sysdeps/alpha/strlen.S: New files. * sysdeps/alpha/divl.S, sysdeps/alpha/divlu.S, sysdeps/alpha/divq.S, sysdeps/alpha/divqu.S, sysdeps/alpha/divrem.m4, sysdeps/alpha/macros.m4, sysdeps/alpha/reml.S, sysdeps/alpha/remlu.S, sysdeps/alpha/remq.S, sysdeps/alpha/remqu.S, sysdeps/alpha/strlen.c: Removed. * sysdeps/generic/sbrk.c (__sbrk): argument is of type ptrdiff_t, not int. * sysdeps/alpha/__longjmp.c (__longjmp): moved dummy while loop to end of function to avoid a jump across NOPs. * sysdeps/alpha/Makefile (sysdep_routines): Removed all rules pertaining to integer division/remainder routines since new code doesn't require them. * sunrpc/xdr_mem.c, sunrpc/xdr_stdio.c: Use 4 instead of sizeof(long) where 32 bit quantities are consumed/stored. Various other minor 64-bit cleanups (casting). * sunrpc/xdr.c (xdr_int): test for sizeof(int)==4 to determine whether xdr_long or xdr_short should be used to encode an int. Notice that an xdr_long is 4 bytes independent of the architecture (otherwise no Alpha could interoperate with existing NFS servers, for example). Ditto for enums. * sunrpc/svc_udp.c (svcudp_recv): changed test from 4*sizeof(u_long) to 16 since it really wants 16 bytes. * sunrpc/svc.c (maskp): changed from u_long* to u_int32*. * sunrpc/rpc_cmsg.c (xdr_callmsg), sunrpc/svc_authux.c: increment "buf" pointer by casting it to a char* first since a long* may be 8 bytes or more and oa->oa_length may be any multiple of 4. * sunrpc/rpc/xdr.h (IXDR_GET_LONG, IXDR_PUT_LONG): change casts to u_int32_t (instead of u_long). * sunrpc/clnt_udp.c (clntudp_call): replaced sizeof(u_long) by 4 since it really is testing for 32 bits. Fixed casts to use u_int32 instead of u_long. * sunrpc/xdr_rec.c: Likewise. * sunrpc/clnt_tcp.c (clnttcp_call): replaced u_long by u_int32. * sunrpc/rpc/auth.h: Likewise. * limits.h (LONG_MAX, LONG_MIN, ULONG_MAX): use 64 bit values for Alpha. Tue Mar 19 13:27:49 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> * sysdeps/i386/fpu/__math.h: New file. Contributed by John C. Bowman <bowman@hagar.ph.utexas.edu>. Sun Mar 17 00:28:16 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/posix/clock.c: Don't multiply the return value by CLOCKS_PER_SEC or CLK_TCK. * sysdeps/mach/hurd/getcwd.c: Fail with ENOENT if a parent directory scan finds no match. * posix/unistd.h (setpgrp): Declare no-arg version unless __FAVOR_BSD. * misc/bsd-compat.c (setpgrp): New function, two arg version. * sysdeps/stub/setpgid.c: Remove setpgrp alias. * sysdeps/mach/hurd/setpgid.c: Likewise. * sysdeps/unix/sysv/sysv4/setpgid.c: Likewise. * sysdeps/unix/common/syscalls.list (setpgid): Remove setpgrp alias. * sysdeps/unix/sysv/irix4/syscalls.list: Likewise. * sysdeps/unix/sysv/linux/setpgrp.c: Obsolete file removed. * posix/setpgrp.c (setpgrp): New file. * posix/Makefile (routines): Add setpgrp. Tue Feb 6 12:46:29 1996 David Mosberger-Tang <davidm@azstarnet.com> * libc-symbols.h (weak_alias, weak_symbol): added definitions for ECOFF (HAVE_ECOFF).
Diffstat (limited to 'sysdeps')
65 files changed, 2734 insertions, 777 deletions
diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile index 8573ca811c..4bb1f299e1 100644 --- a/sysdeps/alpha/Makefile +++ b/sysdeps/alpha/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. # Contributed by Brendan Kehoe (brendan@zen.org). # The GNU C Library is free software; you can redistribute it and/or @@ -16,79 +16,16 @@ # not, write to the Free Software Foundation, Inc., 675 Mass Ave, # Cambridge, MA 02139, USA. +ifeq ($(subdir),gmon) +sysdep_routines := bb_init_func _mcount +endif + ifeq ($(subdir),setjmp) sysdep_routines := $(sysdep_routines) setjmp_aux endif ifeq ($(subdir),gnulib) -routines = $(divrem) +routines = $(divrem) endif # gnulib -# We distribute these files, even though they are generated, -# so as to avoid the need for a functioning m4 to build the library. divrem := divl divlu divq divqu reml remlu remq remqu - -+divrem-NAME-divl := divl -+divrem-NAME-divlu := divlu -+divrem-NAME-divq := divq -+divrem-NAME-divqu := divqu -+divrem-NAME-reml := reml -+divrem-NAME-remlu := remlu -+divrem-NAME-remq := remq -+divrem-NAME-remqu := remqu -+divrem-NAME = $(+divrem-NAME-$(basename $(notdir $@))) - -+divrem-OP-divl := divl -+divrem-OP-divlu := divlu -+divrem-OP-divq := divq -+divrem-OP-divqu := divqu -+divrem-OP-reml := reml -+divrem-OP-remlu := remlu -+divrem-OP-remq := remq -+divrem-OP-remqu := remqu -+divrem-BASEOP-divl := div -+divrem-BASEOP-divlu := div -+divrem-BASEOP-divq := div -+divrem-BASEOP-divqu := div -+divrem-BASEOP-reml := rem -+divrem-BASEOP-remlu := rem -+divrem-BASEOP-remq := rem -+divrem-BASEOP-remqu := rem -+divrem-S-divl := true -+divrem-S-divlu := false -+divrem-S-divq := true -+divrem-S-divqu := false -+divrem-S-reml := true -+divrem-S-remlu := false -+divrem-S-remq := true -+divrem-S-remqu := false -+divrem-SIZE-divl := l -+divrem-SIZE-divlu := l -+divrem-SIZE-divq := q -+divrem-SIZE-divqu := q -+divrem-SIZE-reml := l -+divrem-SIZE-remlu := l -+divrem-SIZE-remq := q -+divrem-SIZE-remqu := q -+divrem-MODE-divl := l -+divrem-MODE-divlu := lu -+divrem-MODE-divq := q -+divrem-MODE-divqu := qu -+divrem-MODE-reml := l -+divrem-MODE-remlu := lu -+divrem-MODE-remq := q -+divrem-MODE-remqu := qu - -$(divrem:%=$(sysdep_dir)/alpha/%.S): $(sysdep_dir)/alpha/divrem.m4 $(sysdep_dir)/alpha/DEFS.h $(sysdep_dir)/alpha/macros.m4 - (echo "define(OP,\`$(+divrem-NAME)')\ - define(BASEOP,\`$(+divrem-BASEOP-$(+divrem-NAME))')\ - define(MODE,\`$(+divrem-MODE-$(+divrem-NAME))')\ - define(SIZE,\`$(+divrem-SIZE-$(+divrem-NAME))')\ - define(SIGNED,\`$(+divrem-S-$(+divrem-NAME))')\ - define(SYSDEP_DIR, \`$(sysdep_dir)/alpha')\ - /* This file is generated from divrem.m4; DO NOT EDIT! */"; \ - cat $<) | $(M4) > $@-tmp -# Make it unwritable so noone will edit it by mistake. - -chmod a-w $@-tmp - mv -f $@-tmp $@ - test ! -d CVS || cvs commit -m'Regenerated from $<' $@ diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c index f3f35eec9c..65b6804bd3 100644 --- a/sysdeps/alpha/__longjmp.c +++ b/sysdeps/alpha/__longjmp.c @@ -38,6 +38,8 @@ register double 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; @@ -73,18 +75,18 @@ __longjmp (__jmp_buf env, int val) 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. */ - - register long int retval asm ("$0"); - - 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)); + asm volatile (""); } } diff --git a/sysdeps/alpha/__math.h b/sysdeps/alpha/__math.h index 5461fca2ac..9aea9d7097 100644 --- a/sysdeps/alpha/__math.h +++ b/sysdeps/alpha/__math.h @@ -1,5 +1,7 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. +/* Inline math functions for Alpha. +Copyright (C) 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. +Contributed by David Mosberger-Tang. 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 @@ -32,4 +34,20 @@ fabs (double __x) return __x; } +extern __inline double +atan (double __x) +{ + extern double __atan2 (double, double); + return __atan2 (__x, 1.0); +} + +#ifdef __USE_MISC +extern __inline double +cabs (struct __cabs_complex __z) +{ + extern double __hypot (double, double); + return __hypot(__z.__x, __z.__y); +} +#endif + #endif diff --git a/sysdeps/alpha/_mcount.S b/sysdeps/alpha/_mcount.S new file mode 100644 index 0000000000..2d6e2ed532 --- /dev/null +++ b/sysdeps/alpha/_mcount.S @@ -0,0 +1,112 @@ +/* Machine-specific calling sequence for `mcount' profiling function. alpha +Copyright (C) 1995 Free Software Foundation, Inc. +Contributed by David Mosberger (davidm@cs.arizona.edu). +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Assembly stub to invoke _mcount(). Compiler generated code calls +this stub after executing a function's prologue and without saving any +registers. It is therefore necessary to preserve a0..a5 as they may +contain function arguments. To work correctly with frame- less +functions, it is also necessary to preserve ra. Finally, division +routines are invoked with a special calling convention and the +compiler treats those calls as if they were instructions. In +particular, it doesn't save any of the temporary registers (caller +saved registers). It is therefore necessary to preserve all +caller-saved registers as well + +Upon entering _mcount, register $at holds the return address and ra +holds the return address of the function's caller (selfpc and frompc, +respectively in gmon.c language...). */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +# include <regdef.h> +#endif + +#undef ret /* discard `ret' as defined in sysdep.h */ + + .set noat + .set noreorder + +ENTRY(_mcount) + subq sp, 0xb0, sp + stq a0, 0x00(sp) + mov ra, a0 # a0 = caller-pc + stq a1, 0x08(sp) + mov $at, a1 # a1 = self-pc + stq $at, 0x10(sp) + + stq a2, 0x18(sp) + stq a3, 0x20(sp) + stq a4, 0x28(sp) + stq a5, 0x30(sp) + stq ra, 0x38(sp) + stq gp, 0x40(sp) + + br gp, 1f +1: ldgp gp, 0(gp) + + stq t0, 0x48(sp) + stq t1, 0x50(sp) + stq t2, 0x58(sp) + stq t3, 0x60(sp) + stq t4, 0x68(sp) + stq t5, 0x70(sp) + stq t6, 0x78(sp) + + lda pv, __mcount + + stq t7, 0x80(sp) + stq t8, 0x88(sp) + stq t9, 0x90(sp) + stq t10, 0x98(sp) + stq t11, 0xa0(sp) + stq v0, 0xa8(sp) + + jsr ra, (pv), __mcount + + ldq a0, 0x00(sp) + ldq a1, 0x08(sp) + ldq $at, 0x10(sp) # restore self-pc + ldq a2, 0x18(sp) + ldq a3, 0x20(sp) + ldq a4, 0x28(sp) + ldq a5, 0x30(sp) + ldq ra, 0x38(sp) + ldq gp, 0x40(sp) + mov $at, pv # make pv point to return address + ldq t0, 0x48(sp) # this is important under OSF/1 to + ldq t1, 0x50(sp) # ensure that the code that we return + ldq t2, 0x58(sp) # can correctly compute its gp + ldq t3, 0x60(sp) + ldq t4, 0x68(sp) + ldq t5, 0x70(sp) + ldq t6, 0x78(sp) + ldq t7, 0x80(sp) + ldq t8, 0x88(sp) + ldq t9, 0x90(sp) + ldq t10, 0x98(sp) + ldq t11, 0xa0(sp) + ldq v0, 0xa8(sp) + + addq sp, 0xb0, sp + ret zero,($at),1 + + .end _mcount diff --git a/sysdeps/alpha/bb_init_func.S b/sysdeps/alpha/bb_init_func.S new file mode 100644 index 0000000000..9bf985ccc0 --- /dev/null +++ b/sysdeps/alpha/bb_init_func.S @@ -0,0 +1,85 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __bb_init_func is invoked at the beginning of each function, before +any registers have been saved. It is therefore safe to use any +caller-saved (call-used) registers (except for argument registers +a1-a5). */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +# include <regdef.h> +#endif + +/* + * These offsets should match with "struct bb" declared in gcc/libgcc2.c. + */ +#define ZERO_WORD 0x00 +#define NEXT 0x20 + + .set noat + .set noreorder + +ENTRY(__bb_init_func) + ldq t0, ZERO_WORD(a0) /* t0 <- blocks->zero_word */ + beq t0, init /* not initialized yet -> */ + ret + + +init: subq sp, 0x38, sp + stq pv, 0x30(sp) + br pv, 1f +1: ldgp gp, 0(pv) + + lda t1, __bb_head + lda t3, _gmonparam + ldq t2, 0(t1) + ldl t3, 0(t3) /* t3 = _gmonparam.state */ + ldi t0, 1 + stq t0, ZERO_WORD(a0) /* blocks->zero_word = 1 */ + stq t2, NEXT(a0) /* blocks->next = __bb_head */ + stq a0, 0(t1) + bne t2, leave + beq t3, leave /* t3 == GMON_PROF_ON? yes -> */ + + /* also need to initialize destructor: */ + stq ra, 0x00(sp) + lda a0, __bb_exit_func + stq a1, 0x08(sp) + lda pv, atexit + stq a2, 0x10(sp) + stq a3, 0x18(sp) + stq a4, 0x20(sp) + stq a5, 0x28(sp) + jsr ra, (pv), atexit + ldq ra, 0x00(sp) + ldq a1, 0x08(sp) + ldq a2, 0x10(sp) + ldq a3, 0x18(sp) + ldq a4, 0x20(sp) + ldq a5, 0x28(sp) + +leave: ldq pv, 0x30(sp) + addq sp, 0x38, sp + ret + + .end __bb_init_func diff --git a/sysdeps/alpha/divl.S b/sysdeps/alpha/divl.S index 5c94362cf5..7dbb5048c7 100644 --- a/sysdeps/alpha/divl.S +++ b/sysdeps/alpha/divl.S @@ -1,57 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 0 +#define SIZE 4 +#define SIGNED 1 +#define FUNC_NAME __divl - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(divl) - /* First set up the dividend. */ - sextl t10, t10 - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - sextl t11, t11 - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - sextl t12, t12 - - - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(divl) +#include "divrem.S" diff --git a/sysdeps/alpha/divlu.S b/sysdeps/alpha/divlu.S index 3a7589d355..9cc71da308 100644 --- a/sysdeps/alpha/divlu.S +++ b/sysdeps/alpha/divlu.S @@ -1,57 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 0 +#define SIZE 4 +#define SIGNED 0 +#define FUNC_NAME __divlu - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(divlu) - /* First set up the dividend. */ - zapnot t10, 0xf, t10 - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - zapnot t11, 0xf, t11 - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - sextl t12, t12 - - - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(divlu) +#include "divrem.S" diff --git a/sysdeps/alpha/divq.S b/sysdeps/alpha/divq.S index 730a338f63..f7af8d62a3 100644 --- a/sysdeps/alpha/divq.S +++ b/sysdeps/alpha/divq.S @@ -1,54 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 0 +#define SIZE 8 +#define SIGNED 1 +#define FUNC_NAME __divq - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(divq) - /* First set up the dividend. */ - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - - - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(divq) +#include "divrem.S" diff --git a/sysdeps/alpha/divqu.S b/sysdeps/alpha/divqu.S index 7614742440..faf2932cb5 100644 --- a/sysdeps/alpha/divqu.S +++ b/sysdeps/alpha/divqu.S @@ -1,60 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 0 +#define SIZE 8 +#define SIGNED 0 +#define FUNC_NAME __divqu - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(divqu) - /* First set up the dividend. */ - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - ldit $f26, 18446744073709551616.0 - addt $f26, $f10, $f26 - fcmovlt $f10, $f26, $f10 - - - /* Then set up the divisor. */ - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - ldit $f26, 18446744073709551616.0 - addt $f26, $f1, $f26 - fcmovlt $f1, $f26, $f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - - - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(divqu) +#include "divrem.S" diff --git a/sysdeps/alpha/divrem.S b/sysdeps/alpha/divrem.S new file mode 100644 index 0000000000..e6293bf355 --- /dev/null +++ b/sysdeps/alpha/divrem.S @@ -0,0 +1,169 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* The current Alpha chips don't provide hardware for integer +division. The C compiler expects the functions + + __divqu: 64-bit unsigned long divide + __remqu: 64-bit unsigned long remainder + __divqs/__remqs: signed 64-bit + __divlu/__remlu: unsigned 32-bit + __divls/__remls: signed 32-bit + +These are not normal C functions: instead of the normal calling +sequence, these expect their arguments in registers t10 and t11, and +return the result in t12 (aka pv). Registers AT and v0 may be +clobbered (assembly temporary), anything else must be saved. */ + +#ifdef __linux__ +# include <alpha/regdef.h> +# include <asm/gentrap.h> +# include <asm/pal.h> +#else +# include <regdef.h> +# include <machine/pal.h> +#endif + +#ifdef DEBUG +# define arg1 a0 +# define arg2 a1 +# define result v0 +# define mask t0 +# define tmp0 t1 +# define tmp1 t2 +# define sign t3 +# define retaddr ra +#else +# define arg1 t10 +# define arg2 t11 +# define result t12 +# define mask v0 +# define tmp0 t0 +# define tmp1 t1 +# define sign t2 +# define retaddr t9 +#endif + +# define divisor arg2 +#if IS_REM +# define dividend result +# define quotient arg1 +# define GETDIVIDEND bis arg1,zero,dividend +#else +# define dividend arg1 +# define quotient result +# define GETDIVIDEND +#endif + +#if SIZE == 8 +# define LONGIFYarg1 GETDIVIDEND +# define LONGIFYarg2 +#else +# if SIGNED +# define LONGIFYarg1 addl arg1,zero,dividend +# define LONGIFYarg2 addl arg2,zero,divisor +# else +# define LONGIFYarg1 zapnot arg1,0x0f,dividend +# define LONGIFYarg2 zapnot arg2,0x0f,divisor +# endif +#endif + +#if SIGNED +# define SETSIGN(sign,reg,tmp) subq zero,reg,tmp; cmovlt sign,tmp,reg +# if IS_REM +# define GETSIGN(x,y,s) bis x,zero,s +# else +# define GETSIGN(x,y,s) xor x,y,s +# endif +#else +# define SETSIGN(sign,reg,tmp) +# define GETSIGN(x,y,s) +#endif + + .set noreorder + .set noat + + .ent FUNC_NAME + .globl FUNC_NAME + + .align 5 +FUNC_NAME: +# define FRAME_SIZE 0x30 + .frame sp,FRAME_SIZE,ra,0 + lda sp,-FRAME_SIZE(sp) + .prologue 1 + stq arg1,0x00(sp) + LONGIFYarg1 + stq arg2,0x08(sp) + LONGIFYarg2 + stq mask,0x10(sp) + bis zero,1,mask + stq tmp0,0x18(sp) + bis zero,zero,quotient + stq tmp1,0x20(sp) + beq divisor,divbyzero + stq sign,0x28(sp) + GETSIGN(dividend,divisor,sign) +#if SIGNED + subq zero,dividend,tmp0 + subq zero,divisor,tmp1 + cmovlt dividend,tmp0,dividend + cmovlt divisor,tmp1,divisor +#endif + /* + * Shift divisor left until either bit 63 is set or until it + * is at least as big as the dividend: + */ + .align 3 +1: cmpule dividend,divisor,AT + blt divisor,2f + blbs AT,2f + addq mask,mask,mask + addq divisor,divisor,divisor + br 1b + + .align 3 +2: addq mask,quotient,tmp0 + cmpule divisor,dividend,AT + subq dividend,divisor,tmp1 + srl divisor,1,divisor + srl mask,1,mask + cmovlbs AT,tmp0,quotient + cmovlbs AT,tmp1,dividend + bne mask,2b + + ldq arg1,0x00(sp) + SETSIGN(sign,result,tmp0) +done: ldq arg2,0x08(sp) + ldq mask,0x10(sp) + ldq tmp0,0x18(sp) + ldq tmp1,0x20(sp) + ldq sign,0x28(sp) + lda sp,FRAME_SIZE(sp) + ret zero,(retaddr),0 + +divbyzero: + lda a0,GEN_INTDIV(zero) + call_pal PAL_gentrap + bis zero,zero,result /* if trap returns, return 0 */ + ldq arg1,0x00(sp) + br done + + .end FUNC_NAME diff --git a/sysdeps/alpha/divrem.m4 b/sysdeps/alpha/divrem.m4 deleted file mode 100644 index d2f36383cb..0000000000 --- a/sysdeps/alpha/divrem.m4 +++ /dev/null @@ -1,51 +0,0 @@ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) - - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - -define(path, `SYSDEP_DIR/macros.m4')dnl -include(path) - -FUNC__(OP) - /* First set up the dividend. */ - EXTEND(t10) - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - ADJQU($f10) - - /* Then set up the divisor. */ - EXTEND(t11) - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - ADJQU($f1) - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - FULLEXTEND(t12) - - DOREM - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(OP) diff --git a/sysdeps/alpha/ffs.S b/sysdeps/alpha/ffs.S new file mode 100644 index 0000000000..7676b85aaa --- /dev/null +++ b/sysdeps/alpha/ffs.S @@ -0,0 +1,71 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Finds the first bit set in an integer. Optimized for the Alpha +architecture. */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +#include <regdef.h> +#endif + + .set noreorder + .set noat + +ENTRY(ffs) + .prologue 0 + + ldq_u zero, 0(sp) # on the 21064, this helps dual-issuing + addl a0, zero, a0 # the last insn and reduces the stall + negq a0, t0 # due to the srl instruction + and a0, t0, t0 + clr v0 + beq a0, done + + # now do binary search for first non-zero bit + + zapnot t0, 0x03, t2 + addq v0, 16, t3 + cmoveq t2, t3, v0 + + zapnot t0, 0x05, t2 + addq v0, 8, t3 + cmoveq t2, t3, v0 + + srl t0, v0, t0 + addq v0, 1, v0 + + and t0, 0x0f, t2 + addq v0, 4, t3 + cmoveq t2, t3, v0 + + and t0, 0x33, t2 + addq v0, 2, t3 + cmoveq t2, t3, v0 + + and t0, 0x55, t2 + addq v0, 1, t3 + cmoveq t2, t3, v0 + +done: ret + + .end ffs diff --git a/sysdeps/alpha/htonl.S b/sysdeps/alpha/htonl.S new file mode 100644 index 0000000000..d0bf7e1718 --- /dev/null +++ b/sysdeps/alpha/htonl.S @@ -0,0 +1,42 @@ +/* Copyright (C) 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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +#include <regdef.h> +#endif + +ENTRY(__htonl) + extlh a0,5,t1 # t1 = dd000000 + zap a0,0xfd,t2 # t2 = 0000cc00 + sll t2,5,t2 # t2 = 00198000 + s8addl t2,t1,t1 # t1 = ddcc0000 + zap a0,0xfb,t2 # t2 = 00bb0000 + srl t2,8,t2 # t2 = 0000bb00 + extbl a0,3,v0 # v0 = 000000aa + or t1,v0,v0 # v0 = ddcc00aa + or t2,v0,v0 # v0 = ddccbbaa + ret + + .end __htonl + +strong_alias_asm(__htonl, __ntohl) +weak_alias(__htonl, htonl) +weak_alias(__htonl, ntohl) diff --git a/sysdeps/alpha/htons.S b/sysdeps/alpha/htons.S new file mode 100644 index 0000000000..6e18c7c441 --- /dev/null +++ b/sysdeps/alpha/htons.S @@ -0,0 +1,36 @@ +/* Copyright (C) 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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +#include <regdef.h> +#endif + +ENTRY(__htons) + extwh a0,7,t1 # t1 = bb00 + extbl a0,1,v0 # v0 = 00aa + bis v0,t1,v0 # v0 = bbaa + ret + + .end __htons + +strong_alias_asm(__htons, __ntohs) +weak_alias(__htons, htons) +weak_alias(__htons, ntohs) diff --git a/sysdeps/alpha/fabs.c b/sysdeps/alpha/machine-gmon.h index 321df0d1e1..a551e9f8b1 100644 --- a/sysdeps/alpha/fabs.c +++ b/sysdeps/alpha/machine-gmon.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. +/* Machine-specific calling sequence for `mcount' profiling function. alpha +Copyright (C) 1995 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 +17,9 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define __NO_MATH_INLINES +#define _MCOUNT_DECL void __mcount -#include <math.h> - -__inline double -fabs (double __x) -{ - __asm ("cpys $f31, %1, %0" : "=f" (__x) : "f" (__x)); - return __x; -} +/* Call __mcount with our the return PC for our caller, and the return + PC our caller will return to. Empty since we use an assembly stub + instead. */ +#define MCOUNT diff --git a/sysdeps/alpha/macros.m4 b/sysdeps/alpha/macros.m4 deleted file mode 100644 index f8c1fe9662..0000000000 --- a/sysdeps/alpha/macros.m4 +++ /dev/null @@ -1,34 +0,0 @@ -dnl NOTE: The $1 below is the argument to EXTEND, not register $1. -define(EXTEND, -`ifelse(SIZE, `l', -`ifelse(SIGNED, `true', -` sextl $1, $1 -',dnl -` zapnot $1, 0xf, $1 -')')')dnl - -dnl FULLEXTEND -- extend the register named in the first argument -define(FULLEXTEND, -`ifelse(SIZE, `l', -` sextl $1, $1 -')')dnl - -dnl This is used by divqu. -define(ADJQU, -`ifelse(MODE, `qu', -` ldit $f26, 18446744073709551616.0 - addt $f26, $1, $f26 - fcmovlt $1, $f26, $1 -')')dnl - -define(DOREM, -`ifelse(BASEOP, `rem', -` /* Compute the remainder. */ -ifelse(SIZE, `l', -` mull t11, t12, t11 - subl t10, t11, t12 -',dnl Note mulq/subq were only really used in remq, but we will find out -dnl if assuming they apply to remqu as well is wrong or not. -` mulq t11, t12, t11 - subq t10, t11, t12 -')')')dnl diff --git a/sysdeps/alpha/ntohl.s b/sysdeps/alpha/ntohl.s new file mode 100644 index 0000000000..6a99a01dc4 --- /dev/null +++ b/sysdeps/alpha/ntohl.s @@ -0,0 +1,2 @@ +/* This is a dummy to avoid including the generic version. htonl and +ntohl are identical and htonl.S defines appropriate aliases. */ diff --git a/sysdeps/alpha/ntohs.s b/sysdeps/alpha/ntohs.s new file mode 100644 index 0000000000..69992a894c --- /dev/null +++ b/sysdeps/alpha/ntohs.s @@ -0,0 +1,2 @@ +/* This is a dummy to avoid including the generic version. htons and +ntohs are identical and htons.S defines appropriate aliases. */ diff --git a/sysdeps/alpha/reml.S b/sysdeps/alpha/reml.S index 95896fb831..cede136acd 100644 --- a/sysdeps/alpha/reml.S +++ b/sysdeps/alpha/reml.S @@ -1,60 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 1 +#define SIZE 4 +#define SIGNED 1 +#define FUNC_NAME __reml - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(reml) - /* First set up the dividend. */ - sextl t10, t10 - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - sextl t11, t11 - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - sextl t12, t12 - - - /* Compute the remainder. */ - mull t11, t12, t11 - subl t10, t11, t12 - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(reml) +#include "divrem.S" diff --git a/sysdeps/alpha/remlu.S b/sysdeps/alpha/remlu.S index 24e07cf327..3658d92bc1 100644 --- a/sysdeps/alpha/remlu.S +++ b/sysdeps/alpha/remlu.S @@ -1,60 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 1 +#define SIZE 4 +#define SIGNED 0 +#define FUNC_NAME __remlu - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(remlu) - /* First set up the dividend. */ - zapnot t10, 0xf, t10 - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - zapnot t11, 0xf, t11 - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - sextl t12, t12 - - - /* Compute the remainder. */ - mull t11, t12, t11 - subl t10, t11, t12 - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(remlu) +#include "divrem.S" diff --git a/sysdeps/alpha/remq.S b/sysdeps/alpha/remq.S index ce38c2460a..61f2067383 100644 --- a/sysdeps/alpha/remq.S +++ b/sysdeps/alpha/remq.S @@ -1,57 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 1 +#define SIZE 8 +#define SIGNED 1 +#define FUNC_NAME __remq - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(remq) - /* First set up the dividend. */ - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - - - /* Then set up the divisor. */ - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - - - /* Compute the remainder. */ - mulq t11, t12, t11 - subq t10, t11, t12 - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(remq) +#include "divrem.S" diff --git a/sysdeps/alpha/remqu.S b/sysdeps/alpha/remqu.S index 26bdd3b037..e22d5ac1c8 100644 --- a/sysdeps/alpha/remqu.S +++ b/sysdeps/alpha/remqu.S @@ -1,63 +1,6 @@ - /* This file is generated from divrem.m4; DO NOT EDIT! */ -/* For each N divided by D, we do: - result = (double) N / (double) D - Then, for each N mod D, we do: - result = N - (D * divMODE (N, D)) +#define IS_REM 1 +#define SIZE 8 +#define SIGNED 0 +#define FUNC_NAME __remqu - FIXME: - The q and qu versions won't deal with operands > 50 bits. We also - don't check for divide by zero. */ - -#include "DEFS.h" -#if 0 -/* We do not handle div by zero yet. */ -#include <machine/pal.h> -#endif -#include <sysdep.h> - -/* Avoid the definition of ret that we set in the alpha sysdep.h. */ -#undef ret - - - - - - -FUNC__(remqu) - /* First set up the dividend. */ - - stq t10,0(sp) - ldt $f10,0(sp) - cvtqt $f10,$f10 - ldit $f26, 18446744073709551616.0 - addt $f26, $f10, $f26 - fcmovlt $f10, $f26, $f10 - - - /* Then set up the divisor. */ - - stq t11,0(sp) - ldt $f1,0(sp) - cvtqt $f1,$f1 - ldit $f26, 18446744073709551616.0 - addt $f26, $f1, $f26 - fcmovlt $f1, $f26, $f1 - - - /* Do the division. */ - divt $f10,$f1,$f10 - cvttqc $f10,$f10 - - /* Put the result in t12. */ - stt $f10,0(sp) - ldq t12,0(sp) - - - /* Compute the remainder. */ - mulq t11, t12, t11 - subq t10, t11, t12 - - - lda sp,16(sp) - ret zero,(t9),1 - .end NAME__(remqu) +#include "divrem.S" diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S index 08932ccd1a..8ea2b50f87 100644 --- a/sysdeps/alpha/setjmp.S +++ b/sysdeps/alpha/setjmp.S @@ -23,7 +23,7 @@ Cambridge, MA 02139, USA. */ extra arguments. */ ENTRY (__sigsetjmp) lda $27, __sigsetjmp_aux/* Load address to jump to. */ - bis $15, $15, $18 /* Pass FP as 3rd arg. */ - bis $30, $30, $19 /* Pass SP as 4th arg. */ + bis $30, $30, $18 /* Pass SP as 3rd arg. */ + bis $15, $15, $19 /* Pass FP as 4th arg. */ jmp $31, ($27), __sigsetjmp_aux /* Call __sigsetjmp_aux. */ .end __sigsetjmp diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c index f92517be92..0f05f8b043 100644 --- a/sysdeps/alpha/setjmp_aux.c +++ b/sysdeps/alpha/setjmp_aux.c @@ -69,6 +69,8 @@ __sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp) /* 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/alpha/strlen.S b/sysdeps/alpha/strlen.S new file mode 100644 index 0000000000..7e6a61be8c --- /dev/null +++ b/sysdeps/alpha/strlen.S @@ -0,0 +1,75 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* Finds length of a 0-terminated string. Optimized for the Alpha +architecture: + + - memory accessed as aligned quadwords only + - uses bcmpge to compare 8 bytes in parallel + - does binary search to find 0 byte in last + quadword (HAKMEM needed 12 instructions to + do this instead of the 9 instructions that + binary search needs). */ + +#include <sysdep.h> +#ifdef __linux__ +# include <alpha/regdef.h> +#else +#include <regdef.h> +#endif + + .set noreorder + .set noat + +ENTRY(strlen) + ldq_u t0, 0(a0) # load first quadword (a0 may be misaligned) + lda t1, -1(zero) + insqh t1, a0, t1 + andnot a0, 7, v0 + or t1, t0, t0 + cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0 + bne t1, found + +loop: ldq t0, 8(v0) + addq v0, 8, v0 # addr += 8 + nop # helps dual issue last two insns + cmpbge zero, t0, t1 + beq t1, loop + +found: blbs t1, done # make aligned case fast + negq t1, t2 + and t1, t2, t1 + + and t1, 0x0f, t0 + addq v0, 4, t2 + cmoveq t0, t2, v0 + + and t1, 0x33, t0 + addq v0, 2, t2 + cmoveq t0, t2, v0 + + and t1, 0x55, t0 + addq v0, 1, t2 + cmoveq t0, t2, v0 + +done: subq v0, a0, v0 + ret + + .end strlen diff --git a/sysdeps/alpha/strlen.c b/sysdeps/alpha/strlen.c deleted file mode 100644 index 36f106c9c3..0000000000 --- a/sysdeps/alpha/strlen.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. - -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., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#include <string.h> - -/* Return the length of the null-terminated string STR. Scan for - the null terminator quickly by testing eight bytes at a time. */ - -size_t -strlen (const char *str) -{ - const char *char_ptr; - const unsigned long int *longword_ptr; - - /* Handle the first few characters by reading one character at a time. - Do this until STR is aligned on a 8-byte border. */ - for (char_ptr = str; ((unsigned long int) char_ptr & 7) != 0; ++char_ptr) - if (*char_ptr == '\0') - return char_ptr - str; - - longword_ptr = (unsigned long int *) char_ptr; - - for (;;) - { - const unsigned long int longword = *longword_ptr++; - int mask; - - /* Set bits in MASK if bytes in LONGWORD are zero. */ - asm ("cmpbge $31, %1, %0" : "=r" (mask) : "r" (longword)); - if (mask) - { - /* Which of the bytes was the zero? */ - const char *cp = (const char *) (longword_ptr - 1); - int i; - - for (i = 0; i < 8; i++) - if (cp[i] == 0) - return cp - str + i; - } - } -} diff --git a/sysdeps/generic/bb_init_func.c b/sysdeps/generic/bb_init_func.c new file mode 100644 index 0000000000..0c768c3c2d --- /dev/null +++ b/sysdeps/generic/bb_init_func.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __bb_init_func is invoked at the beginning of each function, before +any registers have been saved. This generic routine should work +provided that calling this function doesn't mangle the arguments +passed to the function being called. If that's not the case, a system +specific routine must be provided. */ + +#include <sys/types.h> +#include <sys/gmon.h> + +#include <ansidecl.h> +#include <stdlib.h> + +void +DEFUN(__bb_init_func, (bb), struct __bb *bb) +{ + struct gmonparam *p = &_gmonparam; + + if (bb->zero_word != 0) + { + return; /* handle common case quickly */ + } + + /* insert this basic-block into basic-block list: */ + bb->zero_word = 1; + bb->next = __bb_head; + __bb_head = bb; + + if (bb->next == 0 && p->state != GMON_PROF_ON) + { + /* we didn't register _mcleanup yet and pc profiling doesn't seem + to be active, so let's register it now: */ + atexit(_mcleanup); + } +} diff --git a/sysdeps/generic/ffs.c b/sysdeps/generic/ffs.c index 016f0336e9..18239cbecb 100644 --- a/sysdeps/generic/ffs.c +++ b/sysdeps/generic/ffs.c @@ -38,8 +38,8 @@ DEFUN(ffs, (i), int i) 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 }; - unsigned long int a; - unsigned long int x = i & -i; + unsigned int a; + unsigned int x = i & -i; a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24); diff --git a/sysdeps/generic/sbrk.c b/sysdeps/generic/sbrk.c index 83e2536d5d..de7794697d 100644 --- a/sysdeps/generic/sbrk.c +++ b/sysdeps/generic/sbrk.c @@ -26,7 +26,7 @@ extern int __brk (void *addr); If INCREMENT is negative, shrink data space by - INCREMENT. Return start of new space allocated, or -1 for errors. */ void * -__sbrk (int increment) +__sbrk (ptrdiff_t increment) { void *oldbrk; diff --git a/sysdeps/i386/fpu/__math.h b/sysdeps/i386/fpu/__math.h new file mode 100644 index 0000000000..2a759c27cb --- /dev/null +++ b/sysdeps/i386/fpu/__math.h @@ -0,0 +1,512 @@ +/* Inline math functions for i387. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. +Contributed by John C. Bowman <bowman@hagar.ph.utexas.edu> + +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 __MATH_H +#define __MATH_H + +#ifdef __GNUC__ +#ifndef __NO_MATH_INLINES + +#ifdef __cplusplus +#define __MATH_INLINE __inline +#else +#define __MATH_INLINE extern __inline +#endif + +__MATH_INLINE double cos (double); +__MATH_INLINE double sin (double); + + +__MATH_INLINE double __expm1 (double __x); +__MATH_INLINE double +__expm1 (double __x) +{ + register double __value, __exponent, __temp; + __asm __volatile__ + ("fldl2e # e^x - 1 = 2^(x * log2(e)) - 1\n\t" + "fmul %%st(1) # x * log2(e)\n\t" + "fstl %%st(1)\n\t" + "frndint # int(x * log2(e))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(x * log2(e))\n\t" + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" + "fscale # 2^(x * log2(e)) - 2^(int(x * log2(e)))\n\t" + : "=t" (__value), "=u" (__exponent) : "0" (__x)); + __asm __volatile__ + ("fscale # 2^int(x * log2(e))\n\t" + : "=t" (__temp) : "0" (1.0), "u" (__exponent)); + __temp -= 1.0; + + return __temp + __value; +} + +__MATH_INLINE double __sgn1 (double __x); +__MATH_INLINE double +__sgn1 (double __x) +{ + return __x >= 0.0 ? 1.0 : -1.0; +} + +__MATH_INLINE double sqrt (double __x); +__MATH_INLINE double +sqrt (double __x) +{ + register double __value; + __asm __volatile__ + ("fsqrt" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double fabs (double __x); +__MATH_INLINE double +fabs (double __x) +{ + register double __value; + __asm __volatile__ + ("fabs" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double sin (double __x); +__MATH_INLINE double +sin (double __x) +{ + register double value; + __asm __volatile__ + ("fsin" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double cos (double __x); +__MATH_INLINE double +cos (double __x) +{ + register double __value; + __asm __volatile__ + ("fcos" + : "=t" (__value): "0" (__x)); + + return __value; +} + +__MATH_INLINE double tan (double __x); +__MATH_INLINE double +tan (double __x) +{ + register double __value; + __asm __volatile__ + ("fptan" + : "=u" (__value) : "t" (__x)); + + return __value; +} + +__MATH_INLINE double atan2 (double __y, double __x); +__MATH_INLINE double +atan2 (double __y, double __x) +{ + register double __value; + __asm __volatile__ + ("fpatan\n\t" + "fldl %%st(0)" + : "=t" (__value) : "0" (__x), "u" (__y)); + + return __value; +} + +__MATH_INLINE double asin (double __x); +__MATH_INLINE double +asin (double __x) +{ + return atan2 (__x, sqrt (1.0 - __x * __x)); +} + +__MATH_INLINE double acos (double __x); +__MATH_INLINE double +acos (double __x) +{ + return atan2 (sqrt (1.0 - __x * __x), __x); +} + +__MATH_INLINE double atan (double __x); +__MATH_INLINE double +atan (double __x) +{ + register double __value; + __asm __volatile__ + ("fld1\n\t" + "fpatan" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double exp (double __x); +__MATH_INLINE double +exp (double __x) +{ + register double __value, __exponent; + __asm __volatile__ + ("fldl2e # e^x = 2^(x * log2(e))\n\t" + "fmul %%st(1) # x * log2(e)\n\t" + "fstl %%st(1)\n\t" + "frndint # int(x * log2(e))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(x * log2(e))\n\t" + "f2xm1 # 2^(fract(x * log2(e))) - 1\n\t" + : "=t" (__value), "=u" (__exponent) : "0" (__x)); + value += 1.0; + __asm __volatile__ + ("fscale" + : "=t" (__value) : "0" (__value), "u" (__exponent)); + + return __value; +} + +__MATH_INLINE double sinh (double __x); +__MATH_INLINE double +sinh (double __x) +{ + register double __exm1 = __expm1 (fabs (__x)); + + return 0.5 * (__exm1 / (__exm1 + 1.0) + __exm1) * __sgn1 (__x); +} + +__MATH_INLINE double cosh (double __x); +__MATH_INLINE double +cosh (double __x) +{ + register double __ex = exp (__x); + + return 0.5 * (__ex + 1.0 / __ex); +} + +__MATH_INLINE double tanh (double __x); +__MATH_INLINE double +tanh (double __x) +{ + register double __exm1 = __expm1 (-fabs (__x + __x)); + + return __exm1 / (__exm1 + 2.0) * __sgn1 (-__x); +} + +__MATH_INLINE double log (double __x); +__MATH_INLINE double +log (double __x) +{ + register double __value; + __asm __volatile__ + ("fldln2\n\t" + "fxch\n\t" + "fyl2x" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double log10 (double __x); +__MATH_INLINE double +log10 (double __x) +{ + register double __value; + __asm __volatile__ + ("fldlg2\n\t" + "fxch\n\t" + "fyl2x" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double __log2 (double __x); +__MATH_INLINE double +__log2 (double __x) +{ + register double __value; + __asm __volatile__ + ("fld1\n\t" + "fxch\n\t" + "fyl2x" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double fmod (double __x, double __y); +__MATH_INLINE double +fmod (double __x, double __y) +{ + register double __value; + __asm __volatile__ + ("1: fprem\n\t" + "fstsw %%ax\n\t" + "sahf\n\t" + "jp 1b" + : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); + + return __value; +} + +__MATH_INLINE double ldexp (double __x, int __y); +__MATH_INLINE double +ldexp (double __x, int __y) +{ + register double __value; + __asm __volatile__ + ("fscale" + : "=t" (__value) : "0" (__x), "u" ((double) __y)); + + return __value; +} + +__MATH_INLINE double pow (double __x, double __y); +__MATH_INLINE double +pow (double __x, double __y) +{ + register double __value, __exponent; + long __p = (long) __y; + + if (__x == 0.0 && __y > 0.0) + return 0.0; + if (__y == (double) __p) + { + double __r = 1.0; + if (__p == 0) + return 1.0; + if (__p < 0) + { + __p = -__p; + __x = 1.0 / __x; + } + while (1) + { + if (__p & 1) + __r *= __x; + __p >>= 1; + if (__p == 0) + return __r; + __x *= __x; + } + /* NOTREACHED */ + } + __asm __volatile__ + ("fmul %%st(1) # y * log2(x)\n\t" + "fstl %%st(1)\n\t" + "frndint # int(y * log2(x))\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(y * log2(x))\n\t" + "f2xm1 # 2^(fract(y * log2(x))) - 1\n\t" + : "=t" (__value), "=u" (__exponent) : "0" (__log2 (__x)), "1" (__y)); + __value += 1.0; + __asm __volatile__ + ("fscale" + : "=t" (__value) : "0" (__value), "u" (__exponent)); + + return __value; +} + +__MATH_INLINE double floor (double __x); +__MATH_INLINE double +floor (double __x) +{ + register double __value; + volatile short __cw, __cwtmp; + + __asm volatile ("fnstcw %0" : "=m" (__cw)); + __cwtmp = (__cw & 0xf3ff) | 0x0400; /* rounding down */ + __asm volatile ("fldcw %0" : : "m" (__cwtmp)); + __asm volatile ("frndint" : "=t" (__value) : "0" (__x)); + __asm volatile ("fldcw %0" : : "m" (__cw)); + + return __value; +} + +__MATH_INLINE double ceil (double __x); +__MATH_INLINE double +ceil (double __x) +{ + register double __value; + volatile short __cw, __cwtmp; + + __asm volatile ("fnstcw %0" : "=m" (__cw)); + __cwtmp = (__cw & 0xf3ff) | 0x0800; /* rounding up */ + __asm volatile ("fldcw %0" : : "m" (__cwtmp)); + __asm volatile ("frndint" : "=t" (__value) : "0" (__x)); + __asm volatile ("fldcw %0" : : "m" (__cw)); + + return __value; +} + + +/* Optimized versions for some non-standardized functions. */ +#ifdef __USE_MISC + +__MATH_INLINE double __hypot (double __x, double __y); +__MATH_INLINE double +hypot (double __x, double __y) +{ + return sqrt (__x * __x + __y * __y); +} + +__MATH_INLINE double __log1p (double __x); +__MATH_INLINE double +log1p (double __x) +{ + register double __value; + + if (fabs (__x) >= 1.0 - 0.5 * M_SQRT2) + __value = log (1.0 + __x); + else + __asm __volatile__ + ("fldln2\n\t" + "fxch\n\t" + "fyl2xp1" + : "=t" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double __asinh (double __x); +__MATH_INLINE double +asinh (double __x) +{ + register double __y = fabs (__x); + + return __log1p ((__y * __y / (sqrt (__y * __y + 1.0) + 1.0) + __y) + * __sgn1 (__x)); +} + +__MATH_INLINE double __acosh (double __x); +__MATH_INLINE double +acosh (double __x) +{ + return log (__x + sqrt (__x - 1.0) * sqrt (__x + 1.0)); +} + +__MATH_INLINE double __atanh (double __x); +__MATH_INLINE double +atanh (double __x) +{ + register double __y = fabs (__x); + + return -0.5 * __log1p (-(__y + __y) / (1.0 + __y)) * __sgn1 (__x); +} + +__MATH_INLINE double __coshm1 (double __x); +__MATH_INLINE double +coshm1 (double __x) +{ + register double __exm1 = __expm1 (fabs (__x)); + + return 0.5 * (__exm1 / (__exm1 + 1.0)) * __exm1; +} + +__MATH_INLINE double __acosh1p (double __x); +__MATH_INLINE double +acosh1p (double __x) +{ + return __log1p (__x + sqrt (__x) * sqrt (__x + 2.0)); +} + +__MATH_INLINE double __logb (double __x); +__MATH_INLINE double +logb (double __x) +{ + register double __value; + __asm __volatile__ + ("fxtract\n\t" + : "=u" (__value) : "0" (__x)); + + return __value; +} + +__MATH_INLINE double __drem (double __x, double __y); +__MATH_INLINE double +drem (double __x, double __y) +{ + register double __value; + __asm __volatile__ + ("1: fprem1\n\t" + "fstsw %%ax\n\t" + "sahf\n\t" + "jp 1b" + : "=t" (__value) : "0" (__x), "u" (__y) : "ax", "cc"); + + return __value; +} + +__MATH_INLINE void __sincos (double __x, double *__sinx, double *__cosx); +__MATH_INLINE void +sincos (double __x, double *__sinx, double *__cosx) +{ + register double __cosr, __sinr; + __asm __volatile__ + ("fsincos" + : "=t" (__cosr), "=u" (__sinr) : "0" (__x)); + + *__sinx = __sinr; + *__cosx = __cosr; +} + +__MATH_INLINE double __sgn (double __x); +__MATH_INLINE double +sgn (double __x) +{ + return (__x == 0.0 ? 0.0 : (__x > 0.0 ? 1.0 : -1.0)); +} + +__MATH_INLINE double __pow2 (double __x); +__MATH_INLINE double +pow2 (double __x) +{ + register double __value, __exponent; + long __p = (long) __x; + + if (__x == (double) __p) + return ldexp (1.0, __p); + + __asm __volatile__ + ("fldl %%st(0)\n\t" + "frndint # int(x)\n\t" + "fxch\n\t" + "fsub %%st(1) # fract(x)\n\t" + "f2xm1 # 2^(fract(x)) - 1\n\t" + : "=t" (__value), "=u" (__exponent) : "0" (__x)); + __value += 1.0; + __asm __volatile__ + ("fscale" + : "=t" (__value) : "0" (__value), "u" (__exponent)); + + return __value; +} + +#endif /* __USE_MISC */ + +#endif /* __NO_MATH_INLINES */ +#endif /* __GNUC__ */ + +#endif /* __MATH_H */ diff --git a/sysdeps/mach/hurd/getcwd.c b/sysdeps/mach/hurd/getcwd.c index b42e0979a6..abec22c12c 100644 --- a/sysdeps/mach/hurd/getcwd.c +++ b/sysdeps/mach/hurd/getcwd.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 92, 93, 94, 95, 96 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 @@ -57,7 +57,7 @@ __getcwd (char *buf, size_t size) (vm_address_t) dirbuf, dirbufsize); } - + if (size == 0) { if (buf != NULL) @@ -139,7 +139,7 @@ __getcwd (char *buf, size_t size) dirdatasize = dirbufsize; while (!(err = __dir_readdir (parent, &dirdata, &dirdatasize, direntry, -1, 0, &nentries)) && - nentries != 0) + nentries != 0) { /* We have a block of directory entries. */ @@ -167,7 +167,7 @@ __getcwd (char *buf, size_t size) d = (struct dirent *) &dirdata[offset]; offset += d->d_reclen; - /* Ignore `.' and `..'. */ + /* Ignore `.' and `..'. */ if (d->d_name[0] == '.' && (d->d_namlen == 1 || (d->d_namlen == 2 && d->d_name[1] == '.'))) @@ -191,6 +191,14 @@ __getcwd (char *buf, size_t size) if (err) goto errlose; + else if (nentries == 0) + { + /* We got to the end of the directory without finding anything! + We are in a directory that has been unlinked, or something is + broken. */ + err = ENOENT; + goto errlose; + } else { /* Prepend the directory name just discovered. */ diff --git a/sysdeps/mach/hurd/setpgid.c b/sysdeps/mach/hurd/setpgid.c index 7c74ef8a4c..cda54e127a 100644 --- a/sysdeps/mach/hurd/setpgid.c +++ b/sysdeps/mach/hurd/setpgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1995, 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 @@ -54,4 +54,3 @@ DEFUN(__setpgid, (pid, pgid), pid_t pid AND pid_t pgid) } weak_alias (__setpgid, setpgid) -weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/posix/clock.c b/sysdeps/posix/clock.c index c34593b9eb..9eadc7888a 100644 --- a/sysdeps/posix/clock.c +++ b/sysdeps/posix/clock.c @@ -29,5 +29,5 @@ DEFUN_VOID(clock) if (__times(&buf) < 0) return (clock_t) -1; - return ((buf.tms_utime + buf.tms_stime) * CLK_TCK * CLOCKS_PER_SEC); + return buf.tms_utime + buf.tms_stime; } diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c index 36864cbf6e..20f78a08bb 100644 --- a/sysdeps/posix/sleep.c +++ b/sysdeps/posix/sleep.c @@ -58,8 +58,8 @@ DEFUN(sleep, (seconds), unsigned int seconds) act.sa_handler = sleep_handler; act.sa_flags = 0; - if (sigemptyset (&act.sa_mask) < 0 || - sigaction (SIGALRM, &act, &oact) < 0) + act.sa_mask = oset; /* execute handler with original mask */ + if (sigaction (SIGALRM, &act, &oact) < 0) return seconds; before = time ((time_t *) NULL); diff --git a/sysdeps/stub/setpgid.c b/sysdeps/stub/setpgid.c index 7e1d1a9b9a..c694215067 100644 --- a/sysdeps/stub/setpgid.c +++ b/sysdeps/stub/setpgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1995, 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 @@ -32,4 +32,3 @@ DEFUN(__setpgid, (pid, pgid), int pid AND int pgid) stub_warning (setpgid) weak_alias (__setpgid, setpgid) -weak_alias (__setpgid, setpgrp) diff --git a/sysdeps/unix/alarm.c b/sysdeps/unix/alarm.c index 7743256a09..e0dd3dbf57 100644 --- a/sysdeps/unix/alarm.c +++ b/sysdeps/unix/alarm.c @@ -31,6 +31,7 @@ unsigned int DEFUN(alarm, (seconds), unsigned int seconds) { struct itimerval old, new; + unsigned int retval; new.it_interval.tv_usec = 0; new.it_interval.tv_sec = 0; @@ -39,5 +40,8 @@ DEFUN(alarm, (seconds), unsigned int seconds) if (__setitimer(ITIMER_REAL, &new, &old) < 0) return 0; - return (old.it_value.tv_sec + (old.it_value.tv_usec + 999999) / 1000000); + retval = old.it_value.tv_sec; + if (old.it_value.tv_usec) + ++retval; + return retval; } diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h new file mode 100644 index 0000000000..9eb9032270 --- /dev/null +++ b/sysdeps/unix/alpha/sysdep.h @@ -0,0 +1,86 @@ +/* Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdeps/unix/sysdep.h> + +#ifdef ASSEMBLER + +#ifdef __STDC__ +#define ENTRY(name) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + name##: \ + .frame sp,0,ra +#else +#define ENTRY(name) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + name/**/: \ + .frame sp,0,ra +#endif + +/* Note that while it's better structurally, going back to set errno + can make things confusing if you're debugging---it looks like it's jumping + backwards into the previous fn. */ +#ifdef __STDC__ +#define PSEUDO(name, syscall_name, args) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + \ +1: br gp,2f; \ +2: ldgp gp,0(gp); \ + lda pv,syscall_error; \ + jmp zero,(pv); \ + \ +name##: \ + ldi v0,SYS_ify(syscall_name); \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + bne a3,1b; \ +3: +#else +#define PSEUDO(name, syscall_name, args) \ + .globl name; \ + .align 3; \ + .ent name,0; \ + \ +1: br gp,2f; \ +2: ldgp gp,0(gp); \ + lda pv,syscall_error; \ + jmp zero,(pv); \ + \ +name/**/: \ + ldi v0,SYS_ify(syscall_name); \ + .set noat; \ + call_pal PAL_callsys; \ + .set at; \ + bne a3,1b; \ +3: +#endif + +#define ret ret zero,(ra),1 +#define r0 v0 +#define r1 a4 + +#define MOVE(x,y) mov x,y + +#endif diff --git a/sysdeps/unix/bsd/osf/alpha/sysdep.h b/sysdeps/unix/bsd/osf/alpha/sysdep.h index fc661a6b86..7bd7192c20 100644 --- a/sysdeps/unix/bsd/osf/alpha/sysdep.h +++ b/sysdeps/unix/bsd/osf/alpha/sysdep.h @@ -19,58 +19,11 @@ Cambridge, MA 02139, USA. */ /* OSF/1 does not precede the asm names of C symbols with a `_'. */ #define NO_UNDERSCORES -#include <sysdeps/unix/sysdep.h> +#include <sysdeps/unix/alpha/sysdep.h> -#ifdef ASSEMBLER +#ifdef ASSEMBLER #include <machine/pal.h> /* get PAL_callsys */ #include <regdef.h> -#ifdef __STDC__ -#define ENTRY(name) \ - .globl name; \ - .ent name,0; \ - name##:; \ - .frame sp,0,ra -#else -#define ENTRY(name) \ - .globl name; \ - .ent name,0; \ - name/**/:; \ - .frame sp,0,ra #endif - -#ifdef __STDC__ -#define PSEUDO(name, syscall_name, args) \ - ENTRY(name); \ - ldiq v0, SYS_##syscall_name; \ - .set noat; \ - call_pal PAL_callsys; \ - .set at; \ - beq a3, 10f; \ - br gp, 20f; \ -20:; \ - ldgp gp, 0(gp); \ - jmp zero, syscall_error; \ -10: -#else -#define PSEUDO(name, syscall_name, args) \ - ENTRY(name); \ - ldiq v0, SYS_/**/syscall_name; \ - .set noat; \ - call_pal PAL_callsys; \ - .set at; \ - beq a3, 10f; \ - br gp, 20f; \ -20:; \ - ldgp gp, 0(gp); \ - jmp zero, syscall_error; \ -10: -#endif - -#define ret ret zero,(ra),1 -#define r0 v0 -#define r1 a4 -#define MOVE(x,y) mov x, y - -#endif /* ASSEMBLER */ diff --git a/sysdeps/unix/bsd/pause.c b/sysdeps/unix/common/pause.c index b2fafb958e..b2fafb958e 100644 --- a/sysdeps/unix/bsd/pause.c +++ b/sysdeps/unix/common/pause.c diff --git a/sysdeps/unix/common/syscalls.list b/sysdeps/unix/common/syscalls.list index 654f73afe2..e859dd2ec2 100644 --- a/sysdeps/unix/common/syscalls.list +++ b/sysdeps/unix/common/syscalls.list @@ -8,7 +8,7 @@ getpgid - getpgrp 1 __getpgid getpgid getrusage - getrusage 2 __getrusage getrusage gettimeofday - gettimeofday 2 __gettimeofday gettimeofday settimeofday - settimeofday 2 __settimeofday settimeofday -setpgid - setpgrp 2 __setpgid setpgid setpgrp +setpgid - setpgrp 2 __setpgid setpgid setregid - setregid 2 __setregid setregid setreuid - setreuid 2 __setreuid setreuid sigaction - sigaction 3 __sigaction sigaction diff --git a/sysdeps/unix/sysv/Makefile b/sysdeps/unix/sysv/Makefile index 6bd4240921..28542374f0 100644 --- a/sysdeps/unix/sysv/Makefile +++ b/sysdeps/unix/sysv/Makefile @@ -35,11 +35,5 @@ $(objpfx)termio.h: $(..)sysdeps/unix/sysv/sysv_termio.h endif -ifeq ($(subdir),dirent) - -sysdep_routines := $(sysdep_routines) s_getdents - -endif - # In SYSV style archives the symbol table member has an empty name. ar-symtab-name = diff --git a/sysdeps/unix/sysv/irix4/syscalls.list b/sysdeps/unix/sysv/irix4/syscalls.list index 47e1c48821..a57529e9ad 100644 --- a/sysdeps/unix/sysv/irix4/syscalls.list +++ b/sysdeps/unix/sysv/irix4/syscalls.list @@ -2,7 +2,7 @@ getpgid - bsdgetpgrp 1 __getpgid getpgid msync - msync 3 msync -setpgid - bsdsetpgrp 2 __setpgid setpgid setpgrp +setpgid - bsdsetpgrp 2 __setpgid setpgid signal - signal 3 __raw_signal sysmp - sysmp 4 __sysmp syssgi - syssgi 2 __syssgi diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index 79334e6425..c33a1906bf 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -15,7 +15,7 @@ sysdep_routines += fxstat lxstat xstat endif ifeq ($(subdir), misc) -sysdep_routines += xmknod mount umount s_ptrace +sysdep_routines += xmknod s_ptrace headers += sys/mount.h endif diff --git a/sysdeps/unix/sysv/linux/adjtime.c b/sysdeps/unix/sysv/linux/adjtime.c index c4b5002801..44a0cbbdb5 100644 --- a/sysdeps/unix/sysv/linux/adjtime.c +++ b/sysdeps/unix/sysv/linux/adjtime.c @@ -20,8 +20,8 @@ Boston, MA 02111-1307, USA. */ #include <sys/time.h> #include <sys/timex.h> -#define MAX_SEC (LONG_MAX / 1000000L - 2) -#define MIN_SEC (LONG_MIN / 1000000L + 2) +#define MAX_SEC (INT_MAX / 1000000L - 2) +#define MIN_SEC (INT_MIN / 1000000L + 2) #ifndef MOD_OFFSET #define modes mode diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile new file mode 100644 index 0000000000..9e12a0daa2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/Makefile @@ -0,0 +1,7 @@ +ifeq ($(subdir), misc) +headers += alpha/regdef.h + +sysdep_routines := $(sysdep_routines) \ + ieee_get_fp_control ieee_set_fp_control fpu_control setfpucw \ + sethae ioperm osf_sigprocmask fstatfs statfs +endif diff --git a/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h b/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h new file mode 100644 index 0000000000..142df9c4f8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/alpha/regdef.h @@ -0,0 +1,44 @@ +#ifndef __alpha_regdef_h__ +#define __alpha_regdef_h__ + +#define v0 $0 /* function return value */ + +#define t0 $1 /* temporary registers (caller-saved) */ +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 + +#define s0 $9 /* saved-registers (callee-saved registers) */ +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +#define fp s6 /* frame-pointer (s6 in frame-less procedures) */ + +#define a0 $16 /* argument registers (caller-saved) */ +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 + +#define t8 $22 /* more temps (caller-saved) */ +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 /* return address register */ +#define t12 $27 + +#define pv t12 /* procedure-variable register */ +#define AT $at /* assembler temporary */ +#define gp $29 /* global pointer */ +#define sp $30 /* stack pointer */ +#define zero $31 /* reads as zero, writes are noops */ + +#endif /* __alpha_regdef_h__ */ diff --git a/sysdeps/unix/sysv/linux/alpha/brk.S b/sysdeps/unix/sysv/linux/alpha/brk.S new file mode 100644 index 0000000000..afd2e3203c --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/brk.S @@ -0,0 +1,60 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __brk is a special syscall under Linux since it never returns an +error. Instead, the error condition is indicated by returning the old +break value (instead of the new, requested one). */ + +#include <sysdep.h> +#include <errnos.h> + +#ifndef HAVE_GNU_LD +#define _end end +#endif + + .extern _end,8 + + .data + + .globl __curbrk +__curbrk: + .quad _end + + .text +ENTRY(__brk) + ldgp gp, 0(t12) + .prologue 1 + + ldi v0, __NR_brk + call_pal PAL_callsys + subq a0, v0, t0 + bne t0, error + + /* Update __curbrk and return cleanly. */ + stl a0, __curbrk + mov zero, v0 + ret + + /* What a horrible way to die. */ +error: ldi v0, ENOMEM + lda pv, syscall_error + jmp zero,(pv) + + .end __brk + +weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/setpgrp.c b/sysdeps/unix/sysv/linux/alpha/fpu_control.c index 4497e07018..20c032a03c 100644 --- a/sysdeps/unix/sysv/linux/setpgrp.c +++ b/sysdeps/unix/sysv/linux/alpha/fpu_control.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1995 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). 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,10 +16,6 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <unistd.h> +#include <fpu_control.h> -int -setpgrp () -{ - return setpgid (0, 0); -} +fpu_control_t __fpu_control = _FPU_DEFAULT; diff --git a/sysdeps/unix/sysv/linux/alpha/fpu_control.h b/sysdeps/unix/sysv/linux/alpha/fpu_control.h new file mode 100644 index 0000000000..782f33e040 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/fpu_control.h @@ -0,0 +1,105 @@ +/* Copyright (C) 1993 Olaf Flebbe +This file is part of the Linux C Library. + +The Linux 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 Linux 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. */ + +#ifndef _ALPHA_FPU_CONTROL_H +#define _ALPHA_FPU_CONTROL_H + +/* + * Since many programs seem to hardcode the values passed to __setfpucw() + * (rather than using the manifest constants) we emulate the x87 interface + * here (at least where this makes sense). + * + * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 + * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM + * + * IM: Invalid operation mask + * DM: Denormalized operand mask + * ZM: Zero-divide mask + * OM: Overflow mask + * UM: Underflow mask + * PM: Precision (inexact result) mask + * + * Mask bit is 1 means no interrupt. + * + * PC: Precision control + * 11 - round to extended precision + * 10 - round to double precision + * 00 - round to single precision + * + * RC: Rounding control + * 00 - rounding to nearest + * 01 - rounding down (toward - infinity) + * 10 - rounding up (toward + infinity) + * 11 - rounding toward zero + * + * IC: Infinity control + * That is for 8087 and 80287 only. + * + * The hardware default is 0x037f. I choose 0x1372. + */ + +#include <features.h> + +/* masking of interrupts */ +#define _FPU_MASK_IM 0x01 +#define _FPU_MASK_DM 0x02 +#define _FPU_MASK_ZM 0x04 +#define _FPU_MASK_OM 0x08 +#define _FPU_MASK_UM 0x10 +#define _FPU_MASK_PM 0x20 + +/* precision control */ +#define _FPU_EXTENDED 0x300 /* RECOMMENDED */ +#define _FPU_DOUBLE 0x200 +#define _FPU_SINGLE 0x0 /* DO NOT USE */ + +/* + * rounding control---notice that on the Alpha this affects only + * instructions with the dynamic rounding mode qualifier (/d). + */ +#define _FPU_RC_NEAREST 0x000 /* RECOMMENDED */ +#define _FPU_RC_DOWN 0x400 +#define _FPU_RC_UP 0x800 +#define _FPU_RC_ZERO 0xC00 + +#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ + + +/* Now two recommended cw */ + +/* Linux default: + - extended precision + - rounding to positive infinity. There is no /p instruction + qualifier. By setting the dynamic rounding mode to +infinity, + one can use /d to get round to +infinity with no extra overhead + (so long as the default isn't changed, of course...) + - exceptions on overflow, zero divide and NaN */ +#define _FPU_DEFAULT 0x1f72 + +/* IEEE: same as above, but exceptions */ +#define _FPU_IEEE 0x1f7f + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +__BEGIN_DECLS + +/* called by start.o. It can be used to manipulate fpu control word. */ +extern void __setfpucw __P ((unsigned short)); + +__END_DECLS + +#endif /* _ALPHA_FPU_CONTROL */ diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S new file mode 100644 index 0000000000..4c86e398d8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#define GSI_IEEE_FP_CONTROL 45 + + .text +ENTRY(__ieee_get_fp_control) + lda sp, -8(sp) + .prologue 1 + + mov sp, a1 + ldi a0, GSI_IEEE_FP_CONTROL + ldi v0, __NR_osf_getsysinfo + call_pal PAL_callsys + bne a3, error + + ldq v0, 0(sp) + lda sp, 8(sp) + ret + +error: lda sp, 8(sp) + lda pv, syscall_error + jmp zero,(pv) + + .end __ieee_get_fp_control + +weak_alias (__ieee_get_fp_control, ieee_get_fp_control) diff --git a/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S new file mode 100644 index 0000000000..d10e9bc24c --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S @@ -0,0 +1,44 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +#define SSI_IEEE_FP_CONTROL 14 + + .text +ENTRY(__ieee_set_fp_control) + lda sp, -8(sp) + .prologue 1 + + stq a0, 0(sp) + mov sp, a1 + ldi a0, SSI_IEEE_FP_CONTROL + ldi v0, __NR_osf_setsysinfo + call_pal PAL_callsys + + lda sp, 8(sp) + + bne a3, error + ret + +error: lda pv, syscall_error + jmp zero,(pv) + + .end __ieee_set_fp_control + +weak_alias (__ieee_set_fp_control, ieee_set_fp_control) diff --git a/sysdeps/unix/sysv/linux/alpha/ioperm.c b/sysdeps/unix/sysv/linux/alpha/ioperm.c new file mode 100644 index 0000000000..306c86b96a --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/ioperm.c @@ -0,0 +1,441 @@ +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by David Mosberger. + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* I/O access is restricted to ISA port space (ports 0..65535). +Modern devices hopefully are sane enough not to put any performance +critical registers in i/o space. + +On the first call to ioperm() or _sethae(), the entire (E)ISA port +space is mapped into the virtual address space at address io.base. +mprotect() calls are then used to enable/disable access to ports. Per +page, there are PAGE_SIZE>>IO_SHIFT I/O ports (e.g., 256 ports on a +Low Cost Alpha based system using 8KB pages). + +Keep in mind that this code should be able to run in a 32bit address +space. It is therefore unreasonable to expect mmap'ing the entire +sparse address space would work (e.g., the Low Cost Alpha chip has an +I/O address space that's 512MB large!). */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/mman.h> + +#include <asm/io.h> +#include <asm/page.h> +#include <asm/system.h> + +#undef inb +#undef inw +#undef inl +#undef outb +#undef outw +#undef outl + +#define PATH_CPUINFO "/proc/cpuinfo" + +#define MAX_PORT 0x10000 +#define vuip volatile unsigned int * + +#define JENSEN_IO_BASE (IDENT_ADDR + 0x0300000000UL) +#define APECS_IO_BASE (IDENT_ADDR + 0x01c0000000UL) +#define ALCOR_IO_BASE (IDENT_ADDR + 0x8580000000UL) + +enum { + IOSYS_JENSEN = 0, IOSYS_APECS = 1, IOSYS_ALCOR = 2 +} iosys_t; + +struct ioswtch { + void (*sethae)(unsigned long addr); + void (*outb)(unsigned char b, unsigned long port); + void (*outw)(unsigned short b, unsigned long port); + void (*outl)(unsigned int b, unsigned long port); + unsigned int (*inb)(unsigned long port); + unsigned int (*inw)(unsigned long port); + unsigned int (*inl)(unsigned long port); +}; + +static struct platform { + const char *name; + int io_sys; +} platform[] = { + {"Alcor", IOSYS_ALCOR}, + {"Avanti", IOSYS_APECS}, + {"Cabriolet", IOSYS_APECS}, + {"EB64+", IOSYS_APECS}, + {"EB66", IOSYS_APECS}, + {"EB66P", IOSYS_APECS}, + {"Jensen", IOSYS_JENSEN}, + {"Mustang", IOSYS_APECS}, + {"Noname", IOSYS_APECS}, +}; + + +static struct { + struct hae hae; + unsigned long base; + struct ioswtch * swp; + int sys; +} io; + + +static inline unsigned long +port_to_cpu_addr (unsigned long port, int iosys, int size) +{ + if (iosys == IOSYS_JENSEN) { + return (port << 7) + ((size - 1) << 4) + io.base; + } else { + return (port << 5) + ((size - 1) << 3) + io.base; + } +} + + +static inline void +inline_sethae (unsigned long addr, int iosys) +{ + if (iosys == IOSYS_JENSEN) { + /* hae on the Jensen is bits 31:25 shifted right */ + addr >>= 25; + if (addr != io.hae.cache) { + __sethae (addr); + io.hae.cache = addr; + } + } else { + unsigned long msb; + + /* no need to set hae if msb is 0: */ + msb = addr & 0xf8000000; + if (msb && msb != io.hae.cache) { + __sethae (msb); + io.hae.cache = msb; + } + } +} + + +static inline void +inline_outb (unsigned char b, unsigned long port, int iosys) +{ + unsigned int w; + unsigned long addr = port_to_cpu_addr (port, iosys, 1); + + inline_sethae (0, iosys); + asm ("insbl %2,%1,%0" : "r=" (w) : "ri" (port & 0x3), "r" (b)); + *(vuip)addr = w; + mb (); +} + + +static inline void +inline_outw (unsigned short b, unsigned long port, int iosys) +{ + unsigned int w; + unsigned long addr = port_to_cpu_addr (port, iosys, 2); + + inline_sethae (0, iosys); + asm ("inswl %2,%1,%0" : "r=" (w) : "ri" (port & 0x3), "r" (b)); + *(vuip)addr = w; + mb (); +} + + +static inline void +inline_outl (unsigned int b, unsigned long port, int iosys) +{ + unsigned long addr = port_to_cpu_addr (port, iosys, 4); + + if (port >= MAX_PORT) + return; + + inline_sethae (0, iosys); + *(vuip)addr = b; + mb (); +} + + +static inline unsigned int +inline_inb (unsigned long port, int iosys) +{ + unsigned long result, addr = port_to_cpu_addr (port, iosys, 1); + + inline_sethae (0, iosys); + result = *(vuip) addr; + result >>= (port & 3) * 8; + return 0xffUL & result; +} + + +static inline unsigned int +inline_inw (unsigned long port, int iosys) +{ + unsigned long result, addr = port_to_cpu_addr (port, iosys, 2); + + inline_sethae (0, iosys); + result = *(vuip) addr; + result >>= (port & 3) * 8; + return 0xffffUL & result; +} + + +static inline unsigned int +inline_inl (unsigned long port, int iosys) +{ + unsigned long addr = port_to_cpu_addr (port, iosys, 4); + + inline_sethae (0, iosys); + return *(vuip) addr; +} + + +#define DCL_SETHAE(name, iosys) \ +static void \ +name##_sethae (unsigned long addr) \ +{ \ + inline_sethae (addr, IOSYS_##iosys); \ +} + +#define DCL_OUT(name, func, type, iosys) \ +static void \ +name##_##func (unsigned type b, unsigned long addr) \ +{ \ + inline_##func (b, addr, IOSYS_##iosys); \ +} + + +#define DCL_IN(name, func, iosys) \ +static unsigned int \ +name##_##func (unsigned long addr) \ +{ \ + return inline_##func (addr, IOSYS_##iosys); \ +} + + +DCL_SETHAE(jensen, JENSEN) +DCL_OUT(jensen, outb, char, JENSEN) +DCL_OUT(jensen, outw, short, JENSEN) +DCL_OUT(jensen, outl, int, JENSEN) +DCL_IN(jensen, inb, JENSEN) +DCL_IN(jensen, inw, JENSEN) +DCL_IN(jensen, inl, JENSEN) + +/* The APECS functions are also used for ALCOR since they are + identical. */ + +DCL_SETHAE(apecs, APECS) +DCL_OUT(apecs, outb, char, APECS) +DCL_OUT(apecs, outw, short, APECS) +DCL_OUT(apecs, outl, int, APECS) +DCL_IN(apecs, inb, APECS) +DCL_IN(apecs, inw, APECS) +DCL_IN(apecs, inl, APECS) + +struct ioswtch ioswtch[] = { + { + jensen_sethae, + jensen_outb, jensen_outw, jensen_outl, + jensen_inb, jensen_inw, jensen_inl + }, + { + apecs_sethae, + apecs_outb, apecs_outw, apecs_outl, + apecs_inb, apecs_inw, apecs_inl + } +}; + + +static int +init_iosys (void) +{ + char name[256], value[256]; + FILE * fp; + int i; + + fp = fopen (PATH_CPUINFO, "r"); + if (!fp) + return -1; + + while (fscanf (fp, "%256[^:]: %256[^\n]\n", name, value) == 2) { + if (strncmp (name, "system type", 11) == 0) { + for (i = 0; i < sizeof (platform) / sizeof (platform[0]); ++i) { + if (strcmp (platform[i].name, value) == 0) { + fclose (fp); + io.sys = platform[i].io_sys; + if (io.sys == IOSYS_JENSEN) + io.swp = &ioswtch[0]; + else + io.swp = &ioswtch[1]; + return 0; + } + } + } + } + fclose (fp); + errno = ENODEV; + return -1; +} + + +int +_ioperm (unsigned long from, unsigned long num, int turn_on) +{ + unsigned long addr, len; + int prot; + + if (!io.swp && init_iosys () < 0) + return -1; + + /* this test isn't as silly as it may look like; consider overflows! */ + if (from >= MAX_PORT || from + num > MAX_PORT) { + errno = EINVAL; + return -1; + } + + if (turn_on) { + if (!io.base) { + unsigned long base; + int fd; + + io.hae.reg = 0; /* not used in user-level */ + io.hae.cache = 0; + __sethae (io.hae.cache); /* synchronize with hw */ + + fd = open ("/dev/mem", O_RDWR); + if (fd < 0) + return fd; + + switch (io.sys) { + case IOSYS_JENSEN: base = JENSEN_IO_BASE; break; + case IOSYS_APECS: base = APECS_IO_BASE; break; + case IOSYS_ALCOR: base = ALCOR_IO_BASE; break; + default: + errno = ENODEV; + return -1; + } + addr = port_to_cpu_addr (from, io.sys, 1); + addr &= PAGE_MASK; + len = port_to_cpu_addr (MAX_PORT, io.sys, 1) - addr; + io.base = + (unsigned long) __mmap (0, len, PROT_NONE, MAP_SHARED, fd, base); + close (fd); + if ((long) io.base == -1) + return -1; + } + prot = PROT_READ | PROT_WRITE; + } else { + if (!io.base) + return 0; /* never was turned on... */ + + /* turnoff access to relevant pages: */ + prot = PROT_NONE; + } + addr = port_to_cpu_addr (from, io.sys, 1); + addr &= PAGE_MASK; + len = port_to_cpu_addr (from + num, io.sys, 1) - addr; + return mprotect ((void *) addr, len, prot); +} + + +int +_iopl (unsigned int level) +{ + if (level > 3) { + errno = EINVAL; + return -1; + } + if (level) { + return _ioperm (0, MAX_PORT, 1); + } + return 0; +} + + +void +_sethae (unsigned long addr) +{ + if (!io.swp && init_iosys () < 0) + return; + + io.swp->sethae (addr); +} + + +void +_outb (unsigned char b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outb (b, port); +} + + +void +_outw (unsigned short b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outw (b, port); +} + + +void +_outl (unsigned int b, unsigned long port) +{ + if (port >= MAX_PORT) + return; + + io.swp->outl (b, port); +} + + +unsigned int +_inb (unsigned long port) +{ + return io.swp->inb (port); +} + + +unsigned int +_inw (unsigned long port) +{ + return io.swp->inw (port); +} + + +unsigned int +_inl (unsigned long port) +{ + return io.swp->inl (port); +} + + +weak_alias (_sethae, sethae); +weak_alias (_ioperm, ioperm); +weak_alias (_iopl, iopl); +weak_alias (_inb, inb); +weak_alias (_inw, inw); +weak_alias (_inl, inl); +weak_alias (_outb, outb); +weak_alias (_outw, outw); +weak_alias (_outl, outl); diff --git a/sysdeps/unix/sysv/linux/alpha/pipe.S b/sysdeps/unix/sysv/linux/alpha/pipe.S new file mode 100644 index 0000000000..f613b08fe0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/pipe.S @@ -0,0 +1,43 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* __pipe is a special syscall since it returns two values. */ + +#include <sysdep.h> + + .text +ENTRY(__pipe) + .prologue 0 + + ldi v0, __NR_pipe + call_pal PAL_callsys + bne a3, error + + stl r0, 0(a0) + stl r1, 4(a0) + mov zero, v0 + ret + +error: br gp, 1f +1: ldgp gp, 0(gp) + lda pv, syscall_error + jmp zero, (pv) + + .end __pipe + +weak_alias (__pipe, pipe) diff --git a/sysdeps/unix/sysv/linux/alpha/profil-counter.h b/sysdeps/unix/sysv/linux/alpha/profil-counter.h new file mode 100644 index 0000000000..6ab5a88c49 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/profil-counter.h @@ -0,0 +1,28 @@ +/* Low-level statistical profiling support function. Mostly POSIX.1 version. +Copyright (C) 1996 Free Software Foundation, Inc. +Contributed by David Mosberger <davidm@azstarnet.com> +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <asm/sigcontext.h> + +void +profil_counter (int signal, long a1, long a2, long a3, long a4, long a5, + struct sigcontext_struct sc) +{ + profil_count((void *) sc.sc_pc); +} diff --git a/sysdeps/unix/sysv/linux/alpha/setfpucw.c b/sysdeps/unix/sysv/linux/alpha/setfpucw.c new file mode 100644 index 0000000000..43e8536b20 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/setfpucw.c @@ -0,0 +1,65 @@ +#include <fpu_control.h> + +#include <asm/fpu.h> + +extern void __ieee_set_fp_control (unsigned long); +extern unsigned long __ieee_get_fp_control (void); + + +static inline unsigned long +rdfpcr (void) +{ + unsigned long fpcr; + + asm ("trapb; mf_fpcr $f0; trapb; stt $f0,%0" : "m="(fpcr)); + return fpcr; +} + + +static inline void +wrfpcr (unsigned long fpcr) +{ + asm volatile ("ldt $f0,%0; trapb; mt_fpcr $f0; trapb" :: "m"(fpcr)); +} + + +void +__setfpucw (unsigned short fpu_control) +{ + unsigned long fpcr = 0, fpcw = 0; + + if (!fpu_control) + fpu_control = _FPU_DEFAULT; + + /* first, set dynamic rounding mode: */ + + fpcr = rdfpcr(); + fpcr &= ~FPCR_DYN_MASK; + switch (fpu_control & 0xc00) { + case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break; + case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break; + case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break; + case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break; + } + wrfpcr(fpcr); + + /* now tell kernel about traps that we like to hear about: */ + + fpcw = __ieee_get_fp_control(); + fpcw &= ~IEEE_TRAP_ENABLE_MASK; + + if (!(fpu_control & _FPU_MASK_IM)) + fpcw |= IEEE_TRAP_ENABLE_INV; + if (!(fpu_control & _FPU_MASK_DM)) + fpcw |= IEEE_TRAP_ENABLE_UNF; + if (!(fpu_control & _FPU_MASK_ZM)) + fpcw |= IEEE_TRAP_ENABLE_DZE; + if (!(fpu_control & _FPU_MASK_OM)) + fpcw |= IEEE_TRAP_ENABLE_OVF; + if (!(fpu_control & _FPU_MASK_PM)) + fpcw |= IEEE_TRAP_ENABLE_INE; + + __ieee_set_fp_control(fpcw); + + __fpu_control = fpu_control; /* update global copy */ +} diff --git a/sysdeps/unix/sysv/linux/alpha/sigprocmask.c b/sysdeps/unix/sysv/linux/alpha/sigprocmask.c new file mode 100644 index 0000000000..a1d5636fcb --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sigprocmask.c @@ -0,0 +1,49 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#include <signal.h> + +extern unsigned long __osf_sigprocmask (int how, unsigned long newmask); + +int +__sigprocmask (int how, const sigset_t *set, sigset_t *oset) +{ + sigset_t setval; + long result; + + if (set) { + setval = *set; + } else { + sigemptyset(&setval); + how = SIG_BLOCK; /* ensure blocked mask doesn't get changed */ + } + result = __osf_sigprocmask(how, setval); + if (result == -1) { + /* if there are ever more than 63 signals, we need to recode this + in assembler since we wouldn't be able to distinguish a mask of + all 1s from -1, but for now, we're doing just fine... */ + return result; + } + if (oset) { + *oset = result; + } + return 0; +} + +weak_alias (__sigprocmask, sigprocmask); diff --git a/sysdeps/unix/sysv/linux/alpha/sigsuspend.S b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S new file mode 100644 index 0000000000..29cba8d312 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sigsuspend.S @@ -0,0 +1,39 @@ +/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@cs.arizona.edu). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* sigsuspend is a special syscall since it needs to dereference the +sigset. */ + +#include <sysdep.h> + + .text +ENTRY(sigsuspend) + .prologue 0 + + ldq a0, 0(a0) + ldi v0, __NR_sigsuspend + call_pal PAL_callsys + bne a3, error + ret + +error: br gp, 1f +1: ldgp gp, 0(gp) + lda pv, syscall_error + jmp zero, (pv) + + .end sigsuspend diff --git a/sysdeps/unix/sysv/linux/alpha/speed.c b/sysdeps/unix/sysv/linux/alpha/speed.c new file mode 100644 index 0000000000..b61cfbbfe3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/speed.c @@ -0,0 +1,102 @@ +/* `struct termios' speed frobnication functions. Linux version. +Copyright (C) 1991, 1992, 1993, 1995 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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <stddef.h> +#include <errno.h> +#include <termios.h> + +static const speed_t speeds[] = + { + 0, + 50, + 75, + 110, + 134, + 150, + 200, + 300, + 600, + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + }; + + +/* Return the output baud rate stored in *TERMIOS_P. */ +speed_t +cfgetospeed (termios_p) + const struct termios *termios_p; +{ + speed_t retval = termios_p->c_cflag & (CBAUD | CBAUDEX); + + if (retval & CBAUDEX) + { + retval &= ~CBAUDEX; + retval |= CBAUD + 1; + } + + return retval; +} + +/* Return the input baud rate stored in *TERMIOS_P. + For Linux there is no difference between input and output speed. */ +strong_alias (cfgetospeed, cfgetispeed); + +/* Set the output baud rate stored in *TERMIOS_P to SPEED. */ +int +cfsetospeed (termios_p, speed) + struct termios *termios_p; + speed_t speed; +{ + register unsigned int i; + + if (termios_p == NULL) + { + errno = EINVAL; + return -1; + } + + /* This allows either B1200 or 1200 to work. XXX + Do we really want to try to support this, given that + fetching the speed must return one or the other? */ + + for (i = 0; i < sizeof (speeds) / sizeof (speeds[0]); ++i) + if (i == speed || speeds[i] == speed) + { + termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag |= (i & CBAUD); + if (i & ~CBAUD) + termios_p->c_cflag |= CBAUDEX; + return 0; + } + + errno = EINVAL; + return -1; +} + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. + For Linux there is no difference between input and output speed. */ +strong_alias (cfsetospeed, cfsetispeed); diff --git a/sysdeps/unix/sysv/linux/alpha/start.S b/sysdeps/unix/sysv/linux/alpha/start.S new file mode 100644 index 0000000000..d1966a82ba --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/start.S @@ -0,0 +1,93 @@ +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +.comm errno, 4 + + .text +ENTRY(__start) + lda sp, -16(sp) + stq zero, 8(sp) /* terminate frame chain */ + + br t0, 1f +1: ldgp gp, 0(t0) + + mov zero, a0 /* establish __fpu_control w/kernel */ + jsr ra, __setfpucw + ldgp gp, 0(ra) + + /* clear out errno. */ + lda t0, errno + stl zero, 0(t0) + + ldl a0, 16(sp) /* get argc */ + lda a1, 24(sp) /* get argv */ + + /* initialize environ: */ + lda t0, environ + s8addq a0, a1, a2 + addq a2, 0x8, a2 + stq a2, 0(t0) + +#ifndef HAVE_INITFINI + mov a0, s0 + mov a1, s1 + mov a2, s2 + + jsr ra, __libc_init + ldgp gp, 0(ra) + + mov s0, a0 + mov s1, a1 + mov s2, a2 + + /* initialize constructors: */ + jsr ra, __main + ldgp gp, 0(ra) + + mov s0, a0 + mov s1, a1 + mov s2, a2 +#endif + + jsr ra, main + ldgp gp, 0(ra) + + mov v0, a0 + + lda pv, exit + jsr ra, (pv), 1 + ldgp gp, 0(ra) + + /* in case exit returns: */ + +1: ldi v0, __NR_exit + call_pal PAL_callsys + br 1b + + .end __start + + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + +weak_alias(__data_start, data_start) diff --git a/sysdeps/unix/sysv/linux/alpha/syscall.S b/sysdeps/unix/sysv/linux/alpha/syscall.S new file mode 100644 index 0000000000..54a8484c58 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/syscall.S @@ -0,0 +1,61 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by David Mosberger (davidm@azstarnet.com). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> + +/* + * This is for COMPATIBILITY with Linux/x86 only. Linux/Alpha system + * calls return an error indication in a3. This allows to return + * arbitrary 64bit values in v0 (because negative values are not + * mistaken as error numbers). However, C allows to return only one + * value so the interface below folds the error indication passed in + * a3 back into v0: it sets v0 to -errno if an error occurs. Thus, + * no negative 64bit numbers can be returned. To avoid this problem, + * use assembly stubs wherever possible/convenient. + * + * Usage: + * + * long syscall(syscall_number, arg1, arg2, arg3, arg4, arg5) + * + * syscall_number = the index of the system call we're invoking + * arg1-arg5 = up to 5 integer arguments to the system call + * + * We need to do some arg shifting: the kernel expects the + * syscall number in v0 and the first five args in a0-a4. + * + */ + + +1: br gp,2f +2: ldgp gp,0(gp) + jmp zero,syscall_error + + +ENTRY (__syscall) + bis a0,a0,v0 # Syscall number -> v0 + bis a1,a1,a0 # arg1-arg5 -> a0-a4 + bis a2,a2,a1 + bis a3,a3,a2 + bis a4,a4,a3 + bis a5,a5,a4 + + call_pal PAL_callsys # Invoke system call + bne a3,1b + ret + +weak_alias(__syscall, syscall) diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list new file mode 100644 index 0000000000..a842908901 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -0,0 +1,45 @@ +# File name Caller Syscall name # args Strong name Weak names + +# used to implement inb()/outb() etc. +sethae - sethae 1 __sethae + +msgctl - msgctl 3 __msgctl msgctl +msgget - msgget 2 __msgget msgget +msgrcv - msgrcv 5 __msgrcv msgrcv +msgsnd - msgsnd 4 __msgsnd msgsnd +shmat - osf_shmat 3 __shmat shmat +shmctl - shmctl 3 __shmctl shmctl +shmdt - shmdt 1 __shmdt shmdt +shmget - shmget 3 __shmget shmget +semop - semop 3 __semop semop +semget - semget 3 __semget semget +semctl - semctl 4 __semctl semctl + +osf_sigprocmask - osf_sigprocmask 2 __osf_sigprocmask + +getdents - getdents 3 __getdirentries getdirentries +getpeername - getpeername 3 __getpeername getpeername +getpriority - getpriority 2 __getpriority getpriority +mmap - mmap 6 __mmap mmap + +# these are actually common with the x86: +fstatfs - fstatfs 2 __fstatfs fstatfs +statfs - statfs 2 __statfs statfs + +# override select.S in parent directory: +select - select 5 __select select +accept - accept 3 __accept accept +bind - bind 3 __bind bind +connect - connect 3 __connect connect +getpeername - getpeername 3 __getpeername getpeername +getsockname - getsockname 3 __getsockname getsockname +listen - listen 2 __listen listen +recv - recv 4 __recv recv +recvfrom - recvfrom 6 __recvfrom recvfrom +recvmsg - recvmsg 3 __recvmsg recvmsg +send - send 4 __send send +sendmsg - sendmsg 3 __sendmsg sendmsg +sendto - sendto 6 __sendto sendto +setsockopt - setsockopt 5 __setsockopt setsockopt +shutdown - shutdown 2 __shutdown shutdown +socketpair - socketpair 4 __socketpair socketpair diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.S b/sysdeps/unix/sysv/linux/alpha/sysdep.S new file mode 100644 index 0000000000..74b153e7b9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.S @@ -0,0 +1,33 @@ +/* Copyright (C) 1993 Free Software Foundation, Inc. + Contributed by Brendan Kehoe (brendan@zen.org). + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <errnos.h> + +ENTRY(syscall_error) + /* Store return value in errno... */ + ldgp gp, 0(t12) + lda t0, errno + stl v0, 0(t0) + + /* And just kick back a -1. */ + ldi v0, -1 + ret + + .end syscall_error diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h new file mode 100644 index 0000000000..febfa3a4fb --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -0,0 +1,60 @@ +/* Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>, August 1995. + +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., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* In the Linux ELF and ECOFF worlds, C symbols are asm symbols. */ +#define NO_UNDERSCORES + +#ifdef ASSEMBLER + +#include <asm/pal.h> +#include <alpha/regdef.h> + +#endif + +/* There is some commonality. */ +#include <sysdeps/unix/alpha/sysdep.h> + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#ifdef __STDC__ +# define SYS_ify(syscall_name) __NR_##syscall_name +#else +# define SYS_ify(syscall_name) __NR_/**/syscall_name +#endif + +/* + * Define some aliases for syscalls that return two values (in r0 and r1): + */ +#define __NR_getpid __NR_getxpid +#define __NR_getppid __NR_getxpid +#define __NR_getuid __NR_getxuid +#define __NR_geteuid __NR_getxuid +#define __NR_getgid __NR_getxgid +#define __NR_getegid __NR_getxgid + +/* + * Some syscalls no Linux program should know about: + */ +#define __NR_osf_sigprocmask 48 +#define __NR_osf_shmat 209 +#define __NR_osf_getsysinfo 256 +#define __NR_osf_setsysinfo 257 diff --git a/sysdeps/unix/sysv/linux/sys/mman.h b/sysdeps/unix/sysv/linux/sys/mman.h index 007dbfd6d6..33361549f9 100644 --- a/sysdeps/unix/sysv/linux/sys/mman.h +++ b/sysdeps/unix/sysv/linux/sys/mman.h @@ -66,7 +66,7 @@ int mprotect __P ((__caddr_t __addr, size_t __len, int __prot)); /* Synchronize the region starting at ADDR and extending LEN bytes with the file it maps. Filesystem operations on a file being mapped are unpredictable before this is done. */ -int msync __P ((__caddr_t __addr, size_t __len)); +int msync __P ((__caddr_t __addr, size_t __len, int flags)); /* Advise the system about particular usage patterns the program follows for the region starting at ADDR and extending LEN bytes. */ diff --git a/sysdeps/unix/sysv/sysv4/setpgid.c b/sysdeps/unix/sysv/sysv4/setpgid.c index b9e06dc719..743b8ca374 100644 --- a/sysdeps/unix/sysv/sysv4/setpgid.c +++ b/sysdeps/unix/sysv/sysv4/setpgid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 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 @@ -32,4 +32,3 @@ DEFUN(__setpgid, (pid, pgid), int pid AND int pgid) } weak_alias (__setpgid, setpgid) -weak_alias (__setpgid, setpgrp) |