aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Orth <ro@TechFak.Uni-Bielefeld.DE>2001-07-24 12:27:03 +0000
committerRainer Orth <ro@gcc.gnu.org>2001-07-24 12:27:03 +0000
commit46d2e8d7780c9caf47f292eeae73ac1843c8fe2c (patch)
tree7b95158e28ff7e2de1e28ae702a2c73439c575de
parentcd6e5291125aababb4af2bc5ee29c41778b340eb (diff)
downloadgcc-46d2e8d7780c9caf47f292eeae73ac1843c8fe2c.zip
gcc-46d2e8d7780c9caf47f292eeae73ac1843c8fe2c.tar.gz
gcc-46d2e8d7780c9caf47f292eeae73ac1843c8fe2c.tar.bz2
irix6-libc-compat.c: New file.
* 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. From-SVN: r44294
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/mips/irix6-libc-compat.c140
-rw-r--r--gcc/config/mips/t-iris64
-rw-r--r--gcc/doc/install.texi3
4 files changed, 153 insertions, 1 deletions
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 <ro@TechFak.Uni-Bielefeld.DE>
+
+ * 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 <lars@nocrew.org>
* 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));
+
+/* <arpa/inet.h> 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);
+}
+
+/* <arpa/inet.h> 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);
+}
+
+/* <arpa/inet.h> 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);
+}
+
+/* <arpa/inet.h> 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));
+
+/* <sys/sem.h> 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.