From: ro Date: Tue, 24 Jul 2001 12:27:03 +0000 (+0000) Subject: * config/mips/irix6-libc-compat.c: New file. X-Git-Tag: upstream/4.9.2~93069 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1166e61200cc6bbc8b3e6fa5ac8cfe7432247766;p=platform%2Fupstream%2Flinaro-gcc.git * config/mips/irix6-libc-compat.c: New file. * config/mips/t-iris6 (LIB2FUNCS_STATIC_EXTRA): Use it. * doc/install.texi (Specific, mips*-sgi-irix6): Mention structure passing workaround. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44294 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c73c8d..4e70b95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2001-07-24 Rainer Orth + + * config/mips/irix6-libc-compat.c: New file. + * config/mips/t-iris6 (LIB2FUNCS_STATIC_EXTRA): Use it. + * doc/install.texi (Specific, mips*-sgi-irix6): Mention structure + passing workaround. + 2001-07-24 lars brinkhoff * rtl.texi (REG_POINTER): Document. diff --git a/gcc/config/mips/irix6-libc-compat.c b/gcc/config/mips/irix6-libc-compat.c new file mode 100644 index 0000000..cc81ab5 --- /dev/null +++ b/gcc/config/mips/irix6-libc-compat.c @@ -0,0 +1,140 @@ +/* Compensate for inconsistent structure passing conventions on IRIX 6. */ +/* Compile this one with gcc. */ +/* Copyright (C) 2001 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file into combinations with other programs, +and to distribute those combinations without any restriction coming +from the use of this file. (The General Public License restrictions +do apply in other respects; for example, they cover modification of +the file, and distribution when not linked into a combine +executable.) + +GNU CC 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* GCC doesn't correctly implement the structure and union passing and return + conventions of the N32 and N64 ABIs on IRIX 6, as described in the + MIPSpro N32 ABI Handbook, ch. 2, Calling Convention Implementations, p.7. + The ABI requires that structures (or trailing parts of structures) smaller + than 8 bytes (a 64-bit register) are left-justified, whereas GCC + right-justifies them. + + While GCC is internally consistent, calling routines compiled with a + compiler that does implement the documented ABI (like SGIs MIPSpro C + compiler) doesn't work. This is primarily an issue for system libraries + like libc. Fortunately, there exist only very few routines that take + structure value arguments or return structures by value, so until the + underlying bug is fixed, it is possible to work around it by providing + wrapper functions for the few affected routines that compensate for the + inconsistent alignment. + + These wrappers rely on the fact that e.g. libc contains weak versions of + those routines, and the real implementation is provided by _-prefixed + variants. So we can provide our own versions, which will only be linked + if the application uses any of the affected functions, calling the private + variants after shifting the arguments or results as required. + + This is a rewrite of code created by Andy Polyakov. */ + +#include "config.h" +#include "system.h" + +/* This must only be used for the N32 and N64 ABIs. O32 is correct. */ + +#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 + +/* The affected arguments need to be shifted by + + BITS_PER_WORD - (sizeof (arg) * BITS_PER_UNIT). + + Since only 32-bit args and results are involved, the shift count is + always 32. */ +#define SHIFT_BITS 32 + +extern machreg_t _inet_ntoa PARAMS ((machreg_t)); +extern machreg_t _inet_lnaof PARAMS ((machreg_t)); +extern machreg_t _inet_netof PARAMS ((machreg_t)); +extern machreg_t _inet_makeaddr PARAMS ((machreg_t, machreg_t)); + +/* has + + char *inet_ntoa (struct in_addr); + + on both IRIX 6.2 and 6.5, with struct in_addr containing a 32-bit int. */ + +machreg_t +inet_ntoa (machreg_t in) +{ + return _inet_ntoa (in << SHIFT_BITS); +} + +/* has + + unsigned long inet_lnaof (struct in_addr); (IRIX 6.2) + in_addr_t inet_lnaof (struct in_addr); (IRIX 6.5) + + in_addr_t is a 32-bit int. */ + +machreg_t +inet_lnaof (machreg_t in) +{ + return _inet_lnaof (in << SHIFT_BITS); +} + +/* has + + unsigned long inet_netof (struct in_addr); (IRIX 6.2) + in_addr_t inet_netof (struct in_addr); (IRIX 6.5) */ + +machreg_t +inet_netof (machreg_t in) +{ + return _inet_netof (in << SHIFT_BITS); +} + +/* has + + struct in_addr inet_makeaddr (int, int); (IRIX 6.2) + struct in_addr inet_makeaddr (in_addr_t, in_addr_t); (IRIX 6.5) */ + +machreg_t +inet_makeaddr (machreg_t net, machreg_t lna) +{ + return _inet_makeaddr (net, lna) >> SHIFT_BITS; +} + +#if _MIPS_SIM == _ABIN32 +extern machreg_t _semctl PARAMS ((machreg_t, machreg_t, machreg_t, machreg_t)); + +/* has + + int semctl (int, int, int, ...); + + where the variadic argument is union semun if used. union semun contains + an int and two pointers, so the union is already 64 bits wide under the + N64 ABI and alignment is not an issue. */ + +machreg_t +semctl (machreg_t semid, machreg_t semnum, machreg_t cmd, machreg_t arg) +{ + return _semctl(semid, semnum, cmd, arg << SHIFT_BITS); +} +#endif /* _ABIN32 */ + +#endif /* _ABIN32 || _ABI64 */ diff --git a/gcc/config/mips/t-iris6 b/gcc/config/mips/t-iris6 index 7391012..c1a710f 100644 --- a/gcc/config/mips/t-iris6 +++ b/gcc/config/mips/t-iris6 @@ -53,3 +53,7 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT' > fp-bit.c echo '#undef US_SOFTWARE_GOFAST' >> fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +# This is only needed in the static libgcc as a band-aid until gcc correctly +# implements the N32/N64 ABI structure passing conventions +LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/mips/irix6-libc-compat.c diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 628833b..65e576d 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -2779,7 +2779,8 @@ GCC is consistent with itself, but not consistent with the SGI C compiler happen are when there are library functions that take/return such structures. There are very few such library functions. Currently this is known to affect @code{inet_ntoa}, @code{inet_lnaof}, -@code{inet_netof}, @code{inet_makeaddr}, and @code{semctl}. +@code{inet_netof}, @code{inet_makeaddr}, and @code{semctl}. Until the +bug is fixed, GCC contains workarounds for the known affected functions. See @uref{http://freeware.sgi.com/,,http://freeware.sgi.com/} for more information about using GCC on IRIX platforms.