This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC, PATCH] Automatic architecture selection for bi-arch hosts
- From: Ulrich Weigand <uweigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 16 Dec 2005 22:13:12 +0100 (CET)
- Subject: [RFC, PATCH] Automatic architecture selection for bi-arch hosts
Hello,
bi-arch 64-bit Linux systems support a 32-bit 'personality' that
causes 'uname' to return the 32-bit machine architecture variant
instead of the 64-bit one. This allows building 32-bit packages
on the 64-bit system by having configure scripts detecting the
system as a 32-bit one.
However, invoking GCC as part of such a build process will still
generate binaries of the wrong architecture, even if the installed
compiler is bi-arch capable, unless care is taken to always pass
the correct flags.
The following patch intends to simplify this by allowing a bi-arch
compiler to default to the architecture mode implied by the current
personality setting.
Technically, the selection works by way of a new spec function,
"if-machine". This function has two arguments; it compares the
first against the current host machine architecture name (as
provided by uname), and if they match, returns the second argument.
A back end can use this spec function in its DRIVER_SELF_SPECS
to add the appropriate architecture mode selection flags
depending on the current machine name. I've implemented this
below for s390.
Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK for mainline?
Bye,
Ulrich
ChangeLog:
* configure.ac: Add sys/utsname.h to AC_CHECK_HEADERS.
Add uname to AC_CHECK_FUNCS.
* configure: Regenerate.
* config.in: Likewise.
* gcc.c: Include <sys/utsname.h> if present.
(if_machine_spec_function): New spec function.
(static_spec_functions): Add it.
* config/s390/s390.h (DEFAULT_S390_ABI): Define.
(DRIVER_SELF_SPECS): Use it.
Index: gcc/configure
===================================================================
*** gcc/configure (revision 108545)
--- gcc/configure (working copy)
*************** fi
*** 8152,8161 ****
for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
! direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
--- 8152,8163 ----
+
for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
! direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h \
! sys/utsname.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
*************** fi
*** 9116,9124 ****
for ac_func in times clock kill getrlimit setrlimit atoll atoq \
sysconf strsignal getrusage nl_langinfo scandir alphasort \
! gettimeofday mbstowcs wcswidth mmap mincore setlocale \
clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
--- 9118,9127 ----
+
for ac_func in times clock kill getrlimit setrlimit atoll atoq \
sysconf strsignal getrusage nl_langinfo scandir alphasort \
! gettimeofday mbstowcs wcswidth mmap mincore setlocale uname \
clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
Index: gcc/gcc.c
===================================================================
*** gcc/gcc.c (revision 108545)
--- gcc/gcc.c (working copy)
*************** compilation is specified by a string cal
*** 87,92 ****
--- 87,96 ----
#include "gcc.h"
#include "flags.h"
+ #ifdef HAVE_SYS_UTSNAME_H
+ #include <sys/utsname.h>
+ #endif
+
/* By default there is no special suffix for target executables. */
/* FIXME: when autoconf is fixed, remove the host check - dj */
#if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
*************** static const char *convert_filename (con
*** 349,354 ****
--- 353,359 ----
static const char *if_exists_spec_function (int, const char **);
static const char *if_exists_else_spec_function (int, const char **);
+ static const char *if_machine_spec_function (int, const char **);
static const char *replace_outfile_spec_function (int, const char **);
static const char *version_compare_spec_function (int, const char **);
*************** static const struct spec_function static
*** 1578,1583 ****
--- 1583,1589 ----
{
{ "if-exists", if_exists_spec_function },
{ "if-exists-else", if_exists_else_spec_function },
+ { "if-machine", if_machine_spec_function },
{ "replace-outfile", replace_outfile_spec_function },
{ "version-compare", version_compare_spec_function },
{ 0, 0 }
*************** if_exists_else_spec_function (int argc,
*** 7622,7627 ****
--- 7628,7661 ----
return argv[1];
}
+ /* if-machine built-in spec function.
+
+ Checks to see if the first argument matches the current machine
+ architecture name. Returns the second argument if so. */
+
+ static const char *
+ if_machine_spec_function (int argc, const char **argv)
+ {
+ #ifdef HAVE_UNAME
+ struct utsname uts;
+
+ /* Must have exactly two arguments. */
+ if (argc != 2)
+ return NULL;
+
+ if (uname (&uts))
+ return NULL;
+ if (strcmp (uts.machine, argv[0]) != 0)
+ return NULL;
+
+ return argv[1];
+
+ #else
+ /* This function is currently only usable on hosts that have uname. */
+ return NULL;
+ #endif
+ }
+
/* replace-outfile built-in spec function.
This looks for the first argument in the outfiles array's name and
Index: gcc/config.in
===================================================================
*** gcc/config.in (revision 108545)
--- gcc/config.in (working copy)
***************
*** 1090,1095 ****
--- 1090,1101 ----
#endif
+ /* Define to 1 if you have the <sys/utsname.h> header file. */
+ #ifndef USED_FOR_TARGET
+ #undef HAVE_SYS_UTSNAME_H
+ #endif
+
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#ifndef USED_FOR_TARGET
#undef HAVE_SYS_WAIT_H
***************
*** 1108,1113 ****
--- 1114,1125 ----
#endif
+ /* Define to 1 if you have the `uname' function. */
+ #ifndef USED_FOR_TARGET
+ #undef HAVE_UNAME
+ #endif
+
+
/* Define to 1 if you have the <unistd.h> header file. */
#ifndef USED_FOR_TARGET
#undef HAVE_UNISTD_H
Index: gcc/configure.ac
===================================================================
*** gcc/configure.ac (revision 108545)
--- gcc/configure.ac (working copy)
*************** AC_HEADER_SYS_WAIT
*** 902,908 ****
AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
! direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
# Check for thread headers.
AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
--- 902,909 ----
AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
! direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h \
! sys/utsname.h)
# Check for thread headers.
AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
*************** define(gcc_UNLOCKED_FUNCS, clearerr_unlo
*** 1001,1007 ****
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
sysconf strsignal getrusage nl_langinfo scandir alphasort \
! gettimeofday mbstowcs wcswidth mmap mincore setlocale \
gcc_UNLOCKED_FUNCS)
if test x$ac_cv_func_mbstowcs = xyes; then
--- 1002,1008 ----
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
sysconf strsignal getrusage nl_langinfo scandir alphasort \
! gettimeofday mbstowcs wcswidth mmap mincore setlocale uname \
gcc_UNLOCKED_FUNCS)
if test x$ac_cv_func_mbstowcs = xyes; then
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h (revision 108545)
--- gcc/config/s390/s390.h (working copy)
*************** extern enum processor_flags s390_arch_fl
*** 106,111 ****
--- 106,121 ----
#define TARGET_DEFAULT MASK_HARD_FLOAT
#endif
+ /* Default architecture mode selection. We want to support automatic
+ 31-bit vs. 64-bit ABI selection on native bi-arch hosts. */
+ #if !defined(CROSS_COMPILE)
+ #define DEFAULT_S390_ABI "%:if-machine(s390 -m31)%:if-machine(s390x -m64)"
+ #elif defined(DEFAULT_TARGET_64BIT)
+ #define DEFAULT_S390_ABI "-m64"
+ #else
+ #define DEFAULT_S390_ABI "-m31"
+ #endif
+
/* Support for configure-time defaults. */
#define OPTION_DEFAULT_SPECS \
{ "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" }, \
*************** extern enum processor_flags s390_arch_fl
*** 113,129 ****
{ "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
/* Defaulting rules. */
- #ifdef DEFAULT_TARGET_64BIT
#define DRIVER_SELF_SPECS \
! "%{!m31:%{!m64:-m64}}", \
"%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
"%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
- #else
- #define DRIVER_SELF_SPECS \
- "%{!m31:%{!m64:-m31}}", \
- "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
- "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
- #endif
/* Target version string. Overridden by the OS header. */
#ifdef DEFAULT_TARGET_64BIT
--- 123,132 ----
{ "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
/* Defaulting rules. */
#define DRIVER_SELF_SPECS \
! "%{!m31:%{!m64:" DEFAULT_S390_ABI "}}", \
"%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
"%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
/* Target version string. Overridden by the OS header. */
#ifdef DEFAULT_TARGET_64BIT
--
Dr. Ulrich Weigand
Linux on zSeries Development
Ulrich.Weigand@de.ibm.com