glibc/sysdeps/alpha/divrem.h
Roland McGrath a1470b6f83 Thu Jun 13 17:25:11 1996 David Mosberger-Tang <davidm@azstarnet.com>
* sysdeps/generic/memcmp.c: Add prototype decls for internal fns.

	* locale/programs/locale.c: Include string.h.

	* sunrpc/xdr_stdio.c (xdrstdio_getlong), sunrpc/xdr_rec.c
 	(xdrrec_getlong), sunrpc/xdr_mem.c (xdrmem_getlong): Make sure
 	appropriate sign-extension is performed on machines with
 	sizeof(long) > 4.

	* sunrpc/xdr.c (xdr_int, xdr_u_int): If sizeof(long)==8 and
 	sizeof(int)<sizeof(long), we need to go through a temporary
 	variable.

	* locale/programs/ld-numeric.c: Include <alloca.h>

	* libio/stdio.h (__libc_fatal): Add prototype.

	* libio/cleanup.c: Use __P() to declare prototype when __STDC__ is
 	in efect.

	* libio/iopopen.c (read_or_write, parent_end, child_end): Declare
 	volatile to avoid "might get clobbered by longjmp" warning.

	* features.h (__KERNEL_STRICT_NAMES): Define __KERNEL_STRICT_NAMES
 	unless _LOOSE_KERNEL_NAMES is in effect (which, with high
 	probability is a sure loser).
	* sysdeps/unix/sysv/linux/gnu/types.h (__KERNEL_STRICT_NAMES): Remove.

	* sysdeps/unix/bsd/osf/alpha/start.S (errno): Removed.
	* sysdeps/unix/sysv/linux/alpha/start.S: Ditto.

	* misc/paths.h (_PATH_MAN): Change from /usr/share/man to /usr/man
	to be Linux FSSTND compliant.

Mon Jun 10 17:50:31 1996  David Mosberger-Tang  <davidm@azstarnet.com>

	* sysdeps/unix/sysv/linux/alpha/pipe.S: Use PSEUDO.

	* sysdeps/unix/sysv/linux/alpha/sysdep.S,
 	sysdeps/unix/sysv/linux/alpha/brk.S,
 	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/llseek.S,
 	sysdeps/unix/sysv/linux/alpha/sigsuspend.S,
 	sysdeps/unix/sysv/linux/alpha/syscall.S: Rename syscall_error to
 	__syscall_error to avoid intruding application name space.

	* sysdeps/unix/sysv/linux/alpha/sysdep.h: Rename __NR_get?id
	to SYS_get?id so that syscall stubs in sysdeps/unix define
	these syscalls in terms of getxpid/getxuid/getxgid.

	* sysdeps/unix/_exit.S, sysdeps/unix/getegid.S,
 	sysdeps/unix/geteuid.S, sysdeps/unix/getppid.S,
 	sysdeps/unix/execve.S, sysdeps/unix/fork.S,
 	sysdeps/unix/syscall.S: Terminate syscall with PSEUDO_END.

	* sysdeps/unix/make-syscalls.sh, sysdeps/unix/sysdep.h
 	(PSEUDO_END): Rename END() to PSEUDO_END().

	* sysdeps/unix/alpha/sysdep.h: Move error-handling code in PSEUDO
 	to PSEUDO_END to improve branch-prediction.  Include .frame
 	directive to make syscalls debugabble.
	(PSEUDO_END): New macro.

	* sysdeps/unix/alpha/sysdep.h, sysdeps/alpha/bb_init_func.S,
 	sysdeps/unix/sysv/linux/alpha/brk.S: Use ldiq instead of ldi since
 	latter is illegal under DEC Unix.

	* sysdeps/unix/alpha/sysdep.S: Renamed from
	sysdeps/unix/sysv/linux/alpha/sysdep.S.  This file works for OSF/1
 	as well.
	* sysdeps/unix/bsd/osf/alpha/sysdep.S: Remove (note that the
 	EWOULDBLOCK -> EAGAIN mapping was unnecessary since
 	EWOULDBLOCK==EAGAIN under DEC Unix and Linux/Alpha).

	* sysdeps/alpha/divrem.h: Use retaddr instead of ra as the return
 	address register in the .frame directive.

	* sysdeps/alpha/copysign.c: Remove.

	* sunrpc/rpc/types.h: Include <sys/param.h> and <netinet/in.h> to
 	avoid RPC definitions of INADDR_LOOPBACK and/or MAXHOSTNAMELEN.

	* errno.h: Move __END_DECLS to correct place to make file
 	compilable under c++.

	* dirent/dirent.h: Document _DIRENT_HAVE_D_OFF macro.  Define
	d_ino only if <direntry.h> hasn't defined d_fileno.

	* configure.in (HAVE_ASM_WEAKEXT_DIRECTIVE): Reverse order of
	arguments to weakext to make .weakext detection work on ECOFF systems.

	* FAQ: Add Linux/Alpha to list of supported platforms.  Mention
	that _validuser() has been replaced by __ivaliduser().

Thu Jun  6 21:39:38 1996  David Mosberger-Tang  <davidm@azstarnet.com>

	* sysdeps/unix/bsd/sun/sunos4/tcsetattr.c (tcsetattr): Declare cmd
 	as unsigned long, not as int (to avoid incorrect int->long
 	promotion).
1996-06-19 06:54:12 +00:00

189 lines
4.1 KiB
C

/* 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. */
#include <sysdep.h>
#ifdef __linux__
# include <asm/gentrap.h>
# include <asm/pal.h>
#else
# 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
#define FRAME_SIZE 0x30
.align 5
FUNC_NAME:
#ifdef PROF
lda sp, -0x18(sp)
stq ra, 0x00(sp)
stq pv, 0x08(sp)
stq gp, 0x10(sp)
br AT, 1f
1: ldgp gp, 0(AT)
lda AT, _mcount
mov retaddr, ra
jsr AT, (AT), _mcount
ldq ra, 0x00(sp)
ldq pv, 0x08(sp)
ldq gp, 0x10(sp)
lda sp, 0x18(sp)
#endif
.frame sp, FRAME_SIZE, retaddr, 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)