From 6932e4446116214695007f42a3426baf5333bc2f Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 19 Mar 1996 19:51:23 +0000 Subject: [PATCH] Wed Feb 14 00:21:17 1996 David Mosberger-Tang * 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/sysdep.S, sysdeps/unix/sysv/linux/alpha/sysdep.h: New files. --- sysdeps/unix/sysv/linux/alpha/Makefile | 7 ++ sysdeps/unix/sysv/linux/alpha/brk.S | 60 ++++++++++ sysdeps/unix/sysv/linux/alpha/fpu_control.c | 21 ++++ sysdeps/unix/sysv/linux/alpha/fpu_control.h | 105 ++++++++++++++++++ .../sysv/linux/alpha/ieee_get_fp_control.S | 44 ++++++++ .../sysv/linux/alpha/ieee_set_fp_control.S | 44 ++++++++ sysdeps/unix/sysv/linux/alpha/pipe.S | 43 +++++++ sysdeps/unix/sysv/linux/alpha/setfpucw.c | 65 +++++++++++ sysdeps/unix/sysv/linux/alpha/sigprocmask.c | 49 ++++++++ sysdeps/unix/sysv/linux/alpha/speed.c | 102 +++++++++++++++++ sysdeps/unix/sysv/linux/alpha/start.S | 93 ++++++++++++++++ sysdeps/unix/sysv/linux/alpha/syscall.S | 61 ++++++++++ sysdeps/unix/sysv/linux/alpha/sysdep.S | 33 ++++++ sysdeps/unix/sysv/linux/alpha/sysdep.h | 60 ++++++++++ 14 files changed, 787 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/alpha/Makefile create mode 100644 sysdeps/unix/sysv/linux/alpha/brk.S create mode 100644 sysdeps/unix/sysv/linux/alpha/fpu_control.c create mode 100644 sysdeps/unix/sysv/linux/alpha/fpu_control.h create mode 100644 sysdeps/unix/sysv/linux/alpha/ieee_get_fp_control.S create mode 100644 sysdeps/unix/sysv/linux/alpha/ieee_set_fp_control.S create mode 100644 sysdeps/unix/sysv/linux/alpha/pipe.S create mode 100644 sysdeps/unix/sysv/linux/alpha/setfpucw.c create mode 100644 sysdeps/unix/sysv/linux/alpha/sigprocmask.c create mode 100644 sysdeps/unix/sysv/linux/alpha/speed.c create mode 100644 sysdeps/unix/sysv/linux/alpha/start.S create mode 100644 sysdeps/unix/sysv/linux/alpha/syscall.S create mode 100644 sysdeps/unix/sysv/linux/alpha/sysdep.S create mode 100644 sysdeps/unix/sysv/linux/alpha/sysdep.h 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/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 +#include + +#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/alpha/fpu_control.c b/sysdeps/unix/sysv/linux/alpha/fpu_control.c new file mode 100644 index 0000000000..20c032a03c --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/fpu_control.c @@ -0,0 +1,21 @@ +/* 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 + +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 + +/* 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 + +#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 + +#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/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 + + .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/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 + +#include + +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 +#include + +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/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 +#include +#include + +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 + +.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 + +/* + * 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/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 +#define _ERRNO_H +#include + +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, , 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 +#include + +#endif + +/* There is some commonality. */ +#include + +/* 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