From 46d7de1907b6d575d9f156c1f93e0e8dd6254674 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 13 Feb 1996 11:38:58 +0000 Subject: [PATCH] Sat Feb 10 13:09:03 1996 Andreas Schwab * sysdeps/unix/sysv/linux/m68k/brk.c, sysdeps/unix/sysv/linux/m68k/mmap.S, sysdeps/unix/sysv/linux/m68k/select.S, sysdeps/unix/sysv/linux/m68k/sigcontext.h, sysdeps/unix/sysv/linux/m68k/sigreturn.S, sysdeps/unix/sysv/linux/m68k/socket.S, sysdeps/unix/sysv/linux/m68k/syscall.S, sysdeps/unix/sysv/linux/m68k/sysdep.S, sysdeps/unix/sysv/linux/m68k/sysdep.h: New files. * sysdeps/unix/sysv/linux/m68k/brk.c, sysdeps/unix/sysv/linux/m68k/mmap.S, sysdeps/unix/sysv/linux/m68k/select.S, sysdeps/unix/sysv/linux/m68k/sigcontext.h, sysdeps/unix/sysv/linux/m68k/sigreturn.S, sysdeps/unix/sysv/linux/m68k/socket.S, sysdeps/unix/sysv/linux/m68k/syscall.S, sysdeps/unix/sysv/linux/m68k/sysdep.S, sysdeps/unix/sysv/linux/m68k/sysdep.h: New files. --- ChangeLog | 10 +++ sysdeps/unix/sysv/linux/m68k/brk.c | 52 ++++++++++++ sysdeps/unix/sysv/linux/m68k/mmap.S | 44 ++++++++++ sysdeps/unix/sysv/linux/m68k/select.S | 53 ++++++++++++ sysdeps/unix/sysv/linux/m68k/sigcontext.h | 31 +++++++ sysdeps/unix/sysv/linux/m68k/sigreturn.S | 28 +++++++ sysdeps/unix/sysv/linux/m68k/socket.S | 62 ++++++++++++++ sysdeps/unix/sysv/linux/m68k/syscall.S | 31 +++++++ sysdeps/unix/sysv/linux/m68k/sysdep.S | 71 ++++++++++++++++ sysdeps/unix/sysv/linux/m68k/sysdep.h | 131 ++++++++++++++++++++++++++++++ 10 files changed, 513 insertions(+) create mode 100644 sysdeps/unix/sysv/linux/m68k/brk.c create mode 100644 sysdeps/unix/sysv/linux/m68k/mmap.S create mode 100644 sysdeps/unix/sysv/linux/m68k/select.S create mode 100644 sysdeps/unix/sysv/linux/m68k/sigcontext.h create mode 100644 sysdeps/unix/sysv/linux/m68k/sigreturn.S create mode 100644 sysdeps/unix/sysv/linux/m68k/socket.S create mode 100644 sysdeps/unix/sysv/linux/m68k/syscall.S create mode 100644 sysdeps/unix/sysv/linux/m68k/sysdep.S create mode 100644 sysdeps/unix/sysv/linux/m68k/sysdep.h diff --git a/ChangeLog b/ChangeLog index 4c711d2..00f9a75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,16 @@ Tue Feb 13 05:12:02 1996 Roland McGrath Sat Feb 10 13:09:03 1996 Andreas Schwab + * sysdeps/unix/sysv/linux/m68k/brk.c, + sysdeps/unix/sysv/linux/m68k/mmap.S, + sysdeps/unix/sysv/linux/m68k/select.S, + sysdeps/unix/sysv/linux/m68k/sigcontext.h, + sysdeps/unix/sysv/linux/m68k/sigreturn.S, + sysdeps/unix/sysv/linux/m68k/socket.S, + sysdeps/unix/sysv/linux/m68k/syscall.S, + sysdeps/unix/sysv/linux/m68k/sysdep.S, + sysdeps/unix/sysv/linux/m68k/sysdep.h: New files. + * sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c, sysdeps/m68k/isinfl.c, sysdeps/m68k/isnanl.c: New files. diff --git a/sysdeps/unix/sysv/linux/m68k/brk.c b/sysdeps/unix/sysv/linux/m68k/brk.c new file mode 100644 index 0000000..3fd5475 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/brk.c @@ -0,0 +1,52 @@ +/* brk system call for Linux/m68k. +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 +#include +#include + +void *__curbrk; + +int +__brk (void *addr) +{ + void *newbrk; + + { + register long d0 __asm__ ("%d0"); + + asm ("move%.l %2, %%d1\n" + "trap #0" /* Perform the system call. */ + : "=d" (d0) + : "0" (SYS_ify (brk)), "g" (addr) + : "%d0", "%d1"); + newbrk = (void *) d0; + } + __curbrk = newbrk; + + if (newbrk < addr) + { + errno = ENOMEM; + return -1; + } + + return 0; +} +weak_alias (__brk, brk) + diff --git a/sysdeps/unix/sysv/linux/m68k/mmap.S b/sysdeps/unix/sysv/linux/m68k/mmap.S new file mode 100644 index 0000000..ed0480d --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/mmap.S @@ -0,0 +1,44 @@ +/* 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 + + .text + SYSCALL_ERROR_HANDLER + +ENTRY (__mmap) + + move.l #SYS_ify (mmap), %d0 /* System call number in %d0. */ + + lea 4(%sp), %a0 /* Address of args is 1st arg. */ + move.l %a0, %d1 + + /* Do the system call trap. */ + trap #0 + + /* Kludge: negative numbers are among the legal return values. + If %d0 is between -4096 and 0 then there was an error. */ + cmp.l #-4096, %d0 + jhi syscall_error + + /* Successful; return the syscall's value. Copy it to %a0 because + mmap is declared to return a pointer. */ + move.l %d0, %a0 + rts + +weak_alias (__mmap, mmap) diff --git a/sysdeps/unix/sysv/linux/m68k/select.S b/sysdeps/unix/sysv/linux/m68k/select.S new file mode 100644 index 0000000..2770df8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/select.S @@ -0,0 +1,53 @@ +/* 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., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include +#define _ERRNO_H +#include + +/* Linux has two versions of the select system call. The old one expected + one argument which must be a pointer to a struct which contains the + five values. The new version expects the five arguments be given in the + registers. First try the new version, if it's not available fall back + to the old version. */ + + .text + SYSCALL_ERROR_HANDLER +ENTRY (__select) + +#if 0 /* For now only use the old version. */ + DO_CALL (#SYS_ify (_newselect), 5) + tst.l %d0 + jmi 1f + rts + +1: move.l #-ENOSYS, %d1 + cmp.l %d1, %d0 + jne syscall_error /* Real error */ + + /* Try again using the old syscall interface. */ +#endif + lea 4(%sp), %a0 + move.l %a0, %d1 + move.l #SYS_ify (select), %d0 + trap #0 + tst.l %d0 + jmi syscall_error + ret + +weak_alias (__select, select) diff --git a/sysdeps/unix/sysv/linux/m68k/sigcontext.h b/sysdeps/unix/sysv/linux/m68k/sigcontext.h new file mode 100644 index 0000000..585b479 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/sigcontext.h @@ -0,0 +1,31 @@ +/* Structure describing state saved while handling a signal. Linux/m68k version. +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. */ + +/* State of this thread when the signal was taken. */ +struct sigcontext +{ + __sigset_t sc_mask; + unsigned long sc_usp; + unsigned long sc_d0; + unsigned long sc_d1; + unsigned long sc_a0; + unsigned long sc_a1; + unsigned short sc_sr; + unsigned long sc_pc; +}; diff --git a/sysdeps/unix/sysv/linux/m68k/sigreturn.S b/sysdeps/unix/sysv/linux/m68k/sigreturn.S new file mode 100644 index 0000000..7f6d643 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/sigreturn.S @@ -0,0 +1,28 @@ +/* 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 + +.text +ENTRY (__sigreturn) + addq.l #4, %sp /* Pop the return PC. */ + DO_CALL (#SYS_ify (sigreturn), 0) + /* Do the system call; it never returns. */ + /* NOTREACHED */ + +weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/unix/sysv/linux/m68k/socket.S b/sysdeps/unix/sysv/linux/m68k/socket.S new file mode 100644 index 0000000..a85f41c --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/socket.S @@ -0,0 +1,62 @@ +/* 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 +#include + +#define P(a, b) P2(a, b) +#define P2(a, b) a##b + + .text + SYSCALL_ERROR_HANDLER + +/* The socket-oriented system calls are handled unusally in Linux. + They are all gated through the single `socketcall' system call number. + `socketcall' takes two arguments: the first is the subcode, specifying + which socket function is being called; and the second is a pointer to + the arguments to the specific function. + + The .S files for the other calls just #define socket and #include this. */ + +.globl P(__,socket) +ENTRY (P(__,socket)) + + /* Save registers. */ + move.l %d2, %a0 + + move.l #SYS_ify (socketcall), %d0 /* System call number in %d0. */ + + /* Use ## so `socket' is a separate token that might be #define'd. */ + move.l #P (SOCKOP_,socket), %d1 /* Subcode is first arg to syscall. */ + lea 4(%sp), %a1 /* Address of args is 2nd arg. */ + move.l %a1, %d2 + + /* Do the system call trap. */ + trap #0 + + /* Restore registers. */ + move.l %a0, %d2 + + /* %d0 is < 0 if there was an error. */ + tst.l %d0 + jmi syscall_error + + /* Successful; return the syscall's value. */ + rts + +weak_alias (P(__,socket), socket) diff --git a/sysdeps/unix/sysv/linux/m68k/syscall.S b/sysdeps/unix/sysv/linux/m68k/syscall.S new file mode 100644 index 0000000..2cc451c --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/syscall.S @@ -0,0 +1,31 @@ +/* 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 + + .text + SYSCALL_ERROR_HANDLER +ENTRY (syscall) + move.l (%sp)+, %a0 /* Pop return address. */ + DO_CALL ((%sp), 5) /* Frob the args and do the system call. */ + tst.l %d0 /* Check %d0 for error. */ + jmi error /* Jump to error handler if negative. */ + jmp (%a0) /* Return to caller. */ + +error: pea (%a0) + jra syscall_error diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.S b/sysdeps/unix/sysv/linux/m68k/sysdep.S new file mode 100644 index 0000000..895ea27 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/sysdep.S @@ -0,0 +1,71 @@ +/* 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. */ + +/* Because the Linux version is in fact m68k/ELF and the start.? file + for this system (sysdeps/m68k/elf/start.S) is also used by The Hurd + and therefore this files must not contain the definition of the + `errno' variable (I don't know why, ask Roland), we have to define + it somewhere else. + + ...and this place is here. */ + .bss + .globl errno + .type errno,@object +errno: .space 4 + .size errno,4 + .globl _errno + .type _errno,@object +_errno = errno /* This name is expected by hj libc.so.5 startup code. */ + .text + +/* The following code is not used at all in the shared library. + The PIC system call stubs set errno themselves. */ + +#ifndef PIC + +#include +#define _ERRNO_H +#include + +.globl errno +.globl __syscall_error + +/* The syscall stubs jump here when they detect an error. */ + +.globl __syscall_error +__syscall_error: + neg.l %d0 + +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + move.l #EWOULDBLOCK_sys, %d1 + cmp.l %d0, %d1 + jne 1f + move.l #EAGAIN, %d0 +1: +#endif + + move.l %d0, errno + move.l #-1, %d0 + /* Copy return value to %a0 for syscalls that are declared to + return a pointer. */ + move.l %d0, %a0 + rts +#endif /* PIC */ diff --git a/sysdeps/unix/sysv/linux/m68k/sysdep.h b/sysdeps/unix/sysv/linux/m68k/sysdep.h new file mode 100644 index 0000000..9b6c8e1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/sysdep.h @@ -0,0 +1,131 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. +Written by Andreas Schwab, , +December 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 world, C symbols are asm symbols. */ +#define NO_UNDERSCORES + +#include + +#ifdef ASSEMBLER + +#define POUND # + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + .globl name; \ + .type name, @function; \ + .align 4; \ + name##: + +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error + +/* Linux uses a negative return value to indicate syscall errors, unlike + most Unices, which use the condition codes' carry flag. */ +#define PSEUDO(name, syscall_name, args) \ + .text; \ + SYSCALL_ERROR_HANDLER \ + ENTRY (name) \ + DO_CALL (POUND SYS_ify (syscall_name), args); \ + tst.l %d0; \ + jmi syscall_error; + +#ifdef PIC +/* Store (- %d0) into errno through the GOT. */ +#define SYSCALL_ERROR_HANDLER \ +syscall_error: \ + move.l (errno@GOTPC.l, %pc), %a0; \ + neg.l %d0; \ + move.l %d0, (%a0); \ + move.l POUND -1, %d0; \ + /* Copy return value to %a0 for syscalls that are declared to return \ + a pointer (e.g., mmap). */ \ + move.l %d0, %a0; \ + rts; +#else +#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +#endif + +/* Linux takes system call arguments in registers: + + syscall number %d0 call-clobbered + arg 1 %d1 call-clobbered + arg 2 %d2 call-saved + arg 3 %d3 call-saved + arg 4 %d4 call-saved + arg 5 %d5 call-saved + + The stack layout upon entering the function is: + + 20(%sp) Arg# 5 + 16(%sp) Arg# 4 + 12(%sp) Arg# 3 + 8(%sp) Arg# 2 + 4(%sp) Arg# 1 + (%sp) Return address + + (Of course a function with say 3 arguments does not have entries for + arguments 4 and 5.) + + Separate move's are faster than movem, but need more space. Since + speed is more important, we don't use movem. Since %a0 and %a1 are + scratch registers, we can use them for saving as well. */ + +#define DO_CALL(syscall, args) \ + move.l syscall, %d0; \ + DOARGS_##args \ + trap POUND 0; \ + UNDOARGS_##args + +#define DOARGS_0 /* No arguments to frob. */ +#define UNDOARGS_0 /* No arguments to unfrob. */ +#define _DOARGS_0(n) /* No arguments to frob. */ + +#define DOARGS_1 _DOARGS_1 (4) +#define _DOARGS_1(n) move.l n(%sp), %d1; _DOARGS_0 (n) +#define UNDOARGS_1 UNDOARGS_0 + +#define DOARGS_2 _DOARGS_2 (8) +#define _DOARGS_2(n) move.l %d2, %a0; move.l n(%sp), %d2; _DOARGS_1 (n-4) +#define UNDOARGS_2 UNDOARGS_1; move.l %a0, %d2 + +#define DOARGS_3 _DOARGS_3 (12) +#define _DOARGS_3(n) move.l %d3, %a1; move.l n(%sp), %d3; _DOARGS_2 (n-4) +#define UNDOARGS_3 UNDOARGS_2; move.l %a1, %d3 + +#define DOARGS_4 _DOARGS_4 (16) +#define _DOARGS_4(n) move.l %d4, -(%sp); move.l n+4(%sp), %d4; _DOARGS_3 (n) +#define UNDOARGS_4 UNDOARGS_3; move.l (%sp)+, %d4 + +#define DOARGS_5 _DOARGS_5 (20) +#define _DOARGS_5(n) move.l %d5, -(%sp); move.l n+4(%sp), %d5; _DOARGS_4 (n) +#define UNDOARGS_5 UNDOARGS_4; move.l (%sp)+, %d5 + + +#define ret rts +#if 0 /* Not used by Linux */ +#define r0 %d0 +#define r1 %d1 +#define MOVE(x,y) movel x , y +#endif + +#endif /* ASSEMBLER */ -- 2.7.4