Wed Feb 14 00:21:17 1996 David Mosberger-Tang <davidm@azstarnet.com>

* 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.
This commit is contained in:
Roland McGrath 1996-03-19 19:52:47 +00:00
parent 4e4e7fca8e
commit 95a89bf364
8 changed files with 463 additions and 0 deletions

112
sysdeps/alpha/_mcount.S Normal file
View File

@ -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

169
sysdeps/alpha/divrem.S Normal file
View File

@ -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

42
sysdeps/alpha/htonl.S Normal file
View File

@ -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)

36
sysdeps/alpha/htons.S Normal file
View File

@ -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)

View File

@ -0,0 +1,25 @@
/* 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
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. */
#define _MCOUNT_DECL void __mcount
/* 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

2
sysdeps/alpha/ntohl.s Normal file
View File

@ -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. */

2
sysdeps/alpha/ntohs.s Normal file
View File

@ -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. */

75
sysdeps/alpha/strlen.S Normal file
View File

@ -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