aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/alpha
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-03-19 19:52:47 +0000
committerRoland McGrath <roland@gnu.org>1996-03-19 19:52:47 +0000
commit95a89bf364c80593fcf146aeb5e0569b26c7f6b3 (patch)
tree08d4e96325de1f4d5a62375fdf3d66fae1cedee1 /sysdeps/alpha
parent4e4e7fca8e8b2c68665b6864d1757fca20fbacf3 (diff)
downloadglibc-95a89bf364c80593fcf146aeb5e0569b26c7f6b3.tar
glibc-95a89bf364c80593fcf146aeb5e0569b26c7f6b3.tar.gz
glibc-95a89bf364c80593fcf146aeb5e0569b26c7f6b3.tar.bz2
glibc-95a89bf364c80593fcf146aeb5e0569b26c7f6b3.zip
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.
Diffstat (limited to 'sysdeps/alpha')
-rw-r--r--sysdeps/alpha/_mcount.S112
-rw-r--r--sysdeps/alpha/divrem.S169
-rw-r--r--sysdeps/alpha/htonl.S42
-rw-r--r--sysdeps/alpha/htons.S36
-rw-r--r--sysdeps/alpha/machine-gmon.h25
-rw-r--r--sysdeps/alpha/ntohl.s2
-rw-r--r--sysdeps/alpha/ntohs.s2
-rw-r--r--sysdeps/alpha/strlen.S75
8 files changed, 463 insertions, 0 deletions
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/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/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/machine-gmon.h b/sysdeps/alpha/machine-gmon.h
new file mode 100644
index 0000000000..a551e9f8b1
--- /dev/null
+++ b/sysdeps/alpha/machine-gmon.h
@@ -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
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/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