1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00

Virgin import of the GCC 2.95.1 compilers

This commit is contained in:
David E. O'Brien 1999-10-16 06:09:09 +00:00
parent aef9219924
commit f2c57ef828
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gcc/dist/; revision=52284
499 changed files with 128225 additions and 79265 deletions

View File

@ -1,9 +1,9 @@
If you think you may have found a bug in GNU CC, please
If you think you may have found a bug in GCC, please
read the Bugs section of the GCC manual for advice on
(1) how to tell when to report a bug,
(2) where to send your bug report, and
(2) how to write a useful bug report and what information
(3) how to write a useful bug report and what information
it needs to have.
There are three ways to read the Bugs section.
@ -20,4 +20,8 @@ to get to the section on bugs. Or use standalone Info in
a like manner. (Standalone Info is part of the Texinfo distribution.)
(3) By hand. Search for the chapter "Reporting Bugs" in gcc.texi, or
cat /usr/local/info/gcc* | more "+/^File: emacs, Node: Bugs,"
cat /usr/local/info/gcc* | more "+/^File: gcc.info, Node: Bugs,"
You may also want to take a look at the GCC FAQ, in which there are
additional instructions for submitting bug reports:
http://www.gnu.org/software/gcc/faq.html#bugreport

File diff suppressed because it is too large Load Diff

2154
contrib/gcc/FSFChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,18 @@ time as we can formally start documenting the interface this file will
serve as a repository for information on these interface and any incompatable
changes we've made.
Aug 31, 1998:
The interface to HANDLE_PRAGMA has changed. It now takes three arguments.
The first two are pointers to functions that should be used to read characters
from the input stream, and to push them back into the input stream respectively.
The third argument is a pointer to a null terminate string which is the first
word after #pragma. The expression supplied by HANDLE_PRAGMA should return
non-zero if it parsed and implemented the pragma. Otherwise it should return
zero, and leave the input stream as it was before the expression was evaluated.
A new back-end definable macro has been added: INSERT_ATTRIBUTES. This macro
allows backend to add attributes to decls as they are created.
Jun 10, 1998:
The interface to lang_decode_option has changed. It now uses and argc/argv
interface to allow for options that use more than one input string. The new

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,11 @@
Noteworthy changes in GCC after EGCS 1.1.
-----------------------------------------
Target specific NEWS
RS6000/PowerPC: -mcpu=401 was added as an alias for -mcpu=403. -mcpu=e603e
was added to do -mcpu=603e and -msoft-float.
Noteworthy changes in GCC for EGCS 1.1.
---------------------------------------

View File

@ -1,8 +1,8 @@
This directory contains the egcs version 1.1.2 release of the GNU C
compiler. It includes all of the support for compiling C++ and
Objective C, including a run-time library for Objective C.
This directory contains the GNU Compiler Collection (GCC) version 2.95.
It includes all of the support for compiling C, C++, Objective C, Fortran,
Java, and Chill.
The GNU C compiler is free software. See the file COPYING for copying
The GNU Compiler Collection is free software. See the file COPYING for copying
permission.
See the file gcc.texi (together with other files that it includes) for

View File

@ -1,9 +1,21 @@
/* Define if you can safely include both <string.h> and <strings.h>. */
#undef STRING_WITH_STRINGS
/* Define if printf supports "%p". */
#undef HAVE_PRINTF_PTR
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
/* Define to 1 if NLS is requested. */
#undef ENABLE_NLS
/* Define as 1 if you have catgets and don't want to use GNU gettext. */
#undef HAVE_CATGETS
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define if your cpp understands the stringify operator. */
#undef HAVE_CPP_STRINGIFY
@ -17,9 +29,22 @@
/* Define if your assembler supports .balign and .p2align. */
#undef HAVE_GAS_BALIGN_AND_P2ALIGN
/* Define if your assembler supports .subsection and .subsection -1 starts
emitting at the beginning of your section */
#undef HAVE_GAS_SUBSECTION_ORDERING
/* Define if your assembler uses the old HImode fild and fist notation. */
#undef HAVE_GAS_FILDS_FISTS
/* Define if you have a working <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define as 1 if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Whether malloc must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_MALLOC
@ -53,6 +78,9 @@
/* Whether atol must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOL
/* Whether atof must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOF
/* Whether sbrk must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_SBRK
@ -62,6 +90,12 @@
/* Whether strerror must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRERROR
/* Whether strsignal must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRSIGNAL
/* Whether strstr must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRSTR
/* Whether getcwd must be declared even if <unistd.h> is included. */
#undef NEED_DECLARATION_GETCWD
@ -74,6 +108,24 @@
/* Whether setrlimit must be declared even if <sys/resource.h> is included. */
#undef NEED_DECLARATION_SETRLIMIT
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
/* Whether putc_unlocked must be declared even if <stdio.h> is included. */
#undef NEED_DECLARATION_PUTC_UNLOCKED
/* Whether fputs_unlocked must be declared even if <stdio.h> is included. */
#undef NEED_DECLARATION_FPUTS_UNLOCKED
/* Define to enable the use of a default assembler. */
#undef DEFAULT_ASSEMBLER
/* Define to enable the use of a default linker. */
#undef DEFAULT_LINKER
/* Define if host mkdir takes a single argument. */
#undef MKDIR_TAKES_ONE_ARG
/* Define to the name of the distribution. */
#undef PACKAGE
/* Define to the version of the distribution. */
#undef VERSION
@TOP@

448
contrib/gcc/aclocal.m4 vendored
View File

@ -1,3 +1,14 @@
dnl See whether we can include both string.h and strings.h.
AC_DEFUN(GCC_HEADER_STRING,
[AC_CACHE_CHECK([whether string.h and strings.h may both be included],
gcc_cv_header_string,
[AC_TRY_COMPILE([#include <string.h>
#include <strings.h>], , gcc_cv_header_string=yes, gcc_cv_header_string=no)])
if test $gcc_cv_header_string = yes; then
AC_DEFINE(STRING_WITH_STRINGS)
fi
])
dnl See whether we need a declaration for a function.
dnl GCC_NEED_DECLARATION(FUNCTION [, EXTRA-HEADER-FILES])
AC_DEFUN(GCC_NEED_DECLARATION,
@ -5,12 +16,17 @@ AC_DEFUN(GCC_NEED_DECLARATION,
AC_CACHE_VAL(gcc_cv_decl_needed_$1,
[AC_TRY_COMPILE([
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#ifdef STRING_WITH_STRINGS
# include <string.h>
# include <strings.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
# ifdef HAVE_STRING_H
# include <string.h>
# else
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
# endif
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@ -156,6 +172,27 @@ if test $gcc_cv_c_volatile = yes ; then
fi
])
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
dnl of the usual 2.
AC_DEFUN(GCC_FUNC_MKDIR_TAKES_ONE_ARG,
[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg,
[AC_TRY_COMPILE([
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_DIRECT_H
# include <direct.h>
#endif], [mkdir ("foo", 0);],
gcc_cv_mkdir_takes_one_arg=no, gcc_cv_mkdir_takes_one_arg=yes)])
if test $gcc_cv_mkdir_takes_one_arg = yes ; then
AC_DEFINE(MKDIR_TAKES_ONE_ARG)
fi
])
AC_DEFUN(EGCS_PROG_INSTALL,
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
# Find a good install program. We prefer a C program (faster),
@ -219,3 +256,404 @@ AC_SUBST(INSTALL_PROGRAM)dnl
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
AC_SUBST(INSTALL_DATA)dnl
])
#serial 1
dnl This test replaces the one in autoconf.
dnl Currently this macro should have the same name as the autoconf macro
dnl because gettext's gettext.m4 (distributed in the automake package)
dnl still uses it. Otherwise, the use in gettext.m4 makes autoheader
dnl give these diagnostics:
dnl configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
dnl configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
undefine([AC_ISC_POSIX])
AC_DEFUN(AC_ISC_POSIX,
[
dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
]
)
# Macro to add for using GNU gettext.
# Ulrich Drepper <drepper@cygnus.com>, 1995.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 5
AC_DEFUN(AM_WITH_NLS,
[AC_MSG_CHECKING([whether NLS is requested])
dnl Default is enabled NLS
AC_ARG_ENABLE(nls,
[ --disable-nls do not use Native Language Support],
USE_NLS=$enableval, USE_NLS=yes)
AC_MSG_RESULT($USE_NLS)
AC_SUBST(USE_NLS)
USE_INCLUDED_LIBINTL=no
dnl If we use NLS figure out what method
if test "$USE_NLS" = "yes"; then
AC_DEFINE(ENABLE_NLS)
AC_MSG_CHECKING([whether included gettext is requested])
AC_ARG_WITH(included-gettext,
[ --with-included-gettext use the GNU gettext library included here],
nls_cv_force_use_gnu_gettext=$withval,
nls_cv_force_use_gnu_gettext=no)
AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
dnl User does not insist on using GNU NLS library. Figure out what
dnl to use. If gettext or catgets are available (in this order) we
dnl use this. Else we have to fall back to GNU NLS library.
dnl catgets is only used if permitted by option --with-catgets.
nls_cv_header_intl=
nls_cv_header_libgt=
CATOBJEXT=NONE
AC_CHECK_HEADER(libintl.h,
[AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
[AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
if test "$gt_cv_func_gettext_libc" != "yes"; then
AC_CHECK_LIB(intl, bindtextdomain,
[AC_CACHE_CHECK([for gettext in libintl],
gt_cv_func_gettext_libintl,
[AC_CHECK_LIB(intl, gettext,
gt_cv_func_gettext_libintl=yes,
gt_cv_func_gettext_libintl=no)],
gt_cv_func_gettext_libintl=no)])
fi
if test "$gt_cv_func_gettext_libc" = "yes" \
|| test "$gt_cv_func_gettext_libintl" = "yes"; then
AC_DEFINE(HAVE_GETTEXT)
AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
if test "$MSGFMT" != "no"; then
AC_CHECK_FUNCS(dcgettext)
AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr],
[CATOBJEXT=.gmo
DATADIRNAME=share],
[CATOBJEXT=.mo
DATADIRNAME=lib])
INSTOBJEXT=.mo
fi
fi
])
if test "$CATOBJEXT" = "NONE"; then
AC_MSG_CHECKING([whether catgets can be used])
AC_ARG_WITH(catgets,
[ --with-catgets use catgets functions if available],
nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
AC_MSG_RESULT($nls_cv_use_catgets)
if test "$nls_cv_use_catgets" = "yes"; then
dnl No gettext in C library. Try catgets next.
AC_CHECK_LIB(i, main)
AC_CHECK_FUNC(catgets,
[AC_DEFINE(HAVE_CATGETS)
INTLOBJS="\$(CATOBJS)"
AC_PATH_PROG(GENCAT, gencat, no)dnl
if test "$GENCAT" != "no"; then
AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
if test "$GMSGFMT" = "no"; then
AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
fi
AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
USE_INCLUDED_LIBINTL=yes
CATOBJEXT=.cat
INSTOBJEXT=.cat
DATADIRNAME=lib
INTLDEPS='$(top_builddir)/intl/libintl.a'
INTLLIBS=$INTLDEPS
LIBS=`echo $LIBS | sed -e 's/-lintl//'`
nls_cv_header_intl=intl/libintl.h
nls_cv_header_libgt=intl/libgettext.h
fi])
fi
fi
if test "$CATOBJEXT" = "NONE"; then
dnl Neither gettext nor catgets in included in the C library.
dnl Fall back on GNU gettext library.
nls_cv_use_gnu_gettext=yes
fi
fi
if test "$nls_cv_use_gnu_gettext" = "yes"; then
dnl Mark actions used to generate GNU NLS library.
INTLOBJS="\$(GETTOBJS)"
AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
[test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
AC_SUBST(MSGFMT)
USE_INCLUDED_LIBINTL=yes
CATOBJEXT=.gmo
INSTOBJEXT=.mo
DATADIRNAME=share
INTLDEPS='$(top_builddir)/intl/libintl.a'
INTLLIBS=$INTLDEPS
LIBS=`echo $LIBS | sed -e 's/-lintl//'`
nls_cv_header_intl=intl/libintl.h
nls_cv_header_libgt=intl/libgettext.h
fi
dnl Test whether we really found GNU xgettext.
if test "$XGETTEXT" != ":"; then
dnl If it is no GNU xgettext we define it as : so that the
dnl Makefiles still can work.
if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
: ;
else
AC_MSG_RESULT(
[found xgettext program is not GNU xgettext; ignore it])
XGETTEXT=":"
fi
fi
# We need to process the po/ directory.
POSUB=po
else
DATADIRNAME=share
nls_cv_header_intl=intl/libintl.h
nls_cv_header_libgt=intl/libgettext.h
fi
AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
AC_OUTPUT_COMMANDS(
[case "$CONFIG_FILES" in *po/Makefile.in*)
sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
esac])
# If this is used in GNU gettext we have to set USE_NLS to `yes'
# because some of the sources are only built for this goal.
if test "$PACKAGE" = gettext; then
USE_NLS=yes
USE_INCLUDED_LIBINTL=yes
fi
dnl These rules are solely for the distribution goal. While doing this
dnl we only have to keep exactly one list of the available catalogs
dnl in configure.in.
for lang in $ALL_LINGUAS; do
GMOFILES="$GMOFILES $lang.gmo"
POFILES="$POFILES $lang.po"
done
dnl Make all variables we use known to autoconf.
AC_SUBST(USE_INCLUDED_LIBINTL)
AC_SUBST(CATALOGS)
AC_SUBST(CATOBJEXT)
AC_SUBST(DATADIRNAME)
AC_SUBST(GMOFILES)
AC_SUBST(INSTOBJEXT)
AC_SUBST(INTLDEPS)
AC_SUBST(INTLLIBS)
AC_SUBST(INTLOBJS)
AC_SUBST(POFILES)
AC_SUBST(POSUB)
])
AC_DEFUN(AM_GNU_GETTEXT,
[AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_REQUIRE([AC_ISC_POSIX])dnl
AC_REQUIRE([AC_HEADER_STDC])dnl
AC_REQUIRE([AC_C_CONST])dnl
AC_REQUIRE([AC_C_INLINE])dnl
AC_REQUIRE([AC_TYPE_OFF_T])dnl
AC_REQUIRE([AC_TYPE_SIZE_T])dnl
AC_REQUIRE([AC_FUNC_ALLOCA])dnl
AC_REQUIRE([AC_FUNC_MMAP])dnl
AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
unistd.h sys/param.h])
AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
strdup __argz_count __argz_stringify __argz_next])
if test "${ac_cv_func_stpcpy+set}" != "set"; then
AC_CHECK_FUNCS(stpcpy)
fi
if test "${ac_cv_func_stpcpy}" = "yes"; then
AC_DEFINE(HAVE_STPCPY)
fi
AM_LC_MESSAGES
AM_WITH_NLS
if test "x$CATOBJEXT" != "x"; then
if test "x$ALL_LINGUAS" = "x"; then
LINGUAS=
else
AC_MSG_CHECKING(for catalogs to be installed)
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
*$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
esac
done
LINGUAS=$NEW_LINGUAS
AC_MSG_RESULT($LINGUAS)
fi
dnl Construct list of names of catalog files to be constructed.
if test -n "$LINGUAS"; then
for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
fi
fi
dnl The reference to <locale.h> in the installed <libintl.h> file
dnl must be resolved because we cannot expect the users of this
dnl to define HAVE_LOCALE_H.
if test $ac_cv_header_locale_h = yes; then
INCLUDE_LOCALE_H="#include <locale.h>"
else
INCLUDE_LOCALE_H="\
/* The system does not provide the header <locale.h>. Take care yourself. */"
fi
AC_SUBST(INCLUDE_LOCALE_H)
dnl Determine which catalog format we have (if any is needed)
dnl For now we know about two different formats:
dnl Linux libc-5 and the normal X/Open format
test -d intl || mkdir intl
if test "$CATOBJEXT" = ".cat"; then
AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
dnl Transform the SED scripts while copying because some dumb SEDs
dnl cannot handle comments.
sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
fi
dnl po2tbl.sed is always needed.
sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
$srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
dnl In the intl/Makefile.in we have a special dependency which makes
dnl only sense for gettext. We comment this out for non-gettext
dnl packages.
if test "$PACKAGE" = "gettext"; then
GT_NO="#NO#"
GT_YES=
else
GT_NO=
GT_YES="#YES#"
fi
AC_SUBST(GT_NO)
AC_SUBST(GT_YES)
dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
dnl Try to locate is.
MKINSTALLDIRS=
if test -n "$ac_aux_dir"; then
MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
fi
if test -z "$MKINSTALLDIRS"; then
MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
fi
AC_SUBST(MKINSTALLDIRS)
dnl *** For now the libtool support in intl/Makefile is not for real.
l=
AC_SUBST(l)
dnl Generate list of files to be processed by xgettext which will
dnl be included in po/Makefile.
test -d po || mkdir po
if test "x$srcdir" != "x."; then
if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
posrcprefix="$srcdir/"
else
posrcprefix="../$srcdir/"
fi
else
posrcprefix="../"
fi
rm -f po/POTFILES
sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
< $srcdir/po/POTFILES.in > po/POTFILES
])
# Check whether LC_MESSAGES is available in <locale.h>.
# Ulrich Drepper <drepper@cygnus.com>, 1995.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 1
AC_DEFUN(AM_LC_MESSAGES,
[if test $ac_cv_header_locale_h = yes; then
AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
[AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
if test $am_cv_val_LC_MESSAGES = yes; then
AC_DEFINE(HAVE_LC_MESSAGES)
fi
fi])
# Search path for a program which passes the given test.
# Ulrich Drepper <drepper@cygnus.com>, 1996.
#
# This file can be copied and used freely without restrictions. It can
# be used in projects which are not available under the GNU Public License
# but which still want to provide support for the GNU gettext functionality.
# Please note that the actual code is *not* freely available.
# serial 1
dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
AC_DEFUN(AM_PATH_PROG_WITH_TEST,
[# Extract the first word of "$2", so it can be a program name with args.
set dummy $2; ac_word=[$]2
AC_MSG_CHECKING([for $ac_word])
AC_CACHE_VAL(ac_cv_path_$1,
[case "[$]$1" in
/*)
ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
;;
*)
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in ifelse([$5], , $PATH, [$5]); do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if [$3]; then
ac_cv_path_$1="$ac_dir/$ac_word"
break
fi
fi
done
IFS="$ac_save_ifs"
dnl If no 4th arg is given, leave the cache variable unset,
dnl so AC_PATH_PROGS will keep looking.
ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
])dnl
;;
esac])dnl
$1="$ac_cv_path_$1"
if test -n "[$]$1"; then
AC_MSG_RESULT([$]$1)
else
AC_MSG_RESULT(no)
fi
AC_SUBST($1)dnl
])

View File

@ -1,5 +1,5 @@
/* Alias analysis for GNU C
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by John Carr (jfc@mit.edu).
This file is part of GNU CC.
@ -26,7 +26,51 @@ Boston, MA 02111-1307, USA. */
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "output.h"
#include "toplev.h"
#include "splay-tree.h"
/* The alias sets assigned to MEMs assist the back-end in determining
which MEMs can alias which other MEMs. In general, two MEMs in
different alias sets to not alias each other. There is one
exception, however. Consider something like:
struct S {int i; double d; };
a store to an `S' can alias something of either type `int' or type
`double'. (However, a store to an `int' cannot alias a `double'
and vice versa.) We indicate this via a tree structure that looks
like:
struct S
/ \
/ \
|/_ _\|
int double
(The arrows are directed and point downwards.) If, when comparing
two alias sets, we can hold one set fixed, and trace the other set
downwards, and at some point find the first set, the two MEMs can
alias one another. In this situation we say the alias set for
`struct S' is the `superset' and that those for `int' and `double'
are `subsets'.
Alias set zero is implicitly a superset of all other alias sets.
However, this is no actual entry for alias set zero. It is an
error to attempt to explicitly construct a subset of zero. */
typedef struct alias_set_entry {
/* The alias set number, as stored in MEM_ALIAS_SET. */
int alias_set;
/* The children of the alias set. These are not just the immediate
children, but, in fact, all children. So, if we have:
struct T { struct S s; float f; }
continuing our example above, the children here will be all of
`int', `double', `float', and `struct S'. */
splay_tree children;
}* alias_set_entry;
static rtx canon_rtx PROTO((rtx));
static int rtx_equal_for_memref_p PROTO((rtx, rtx));
@ -35,34 +79,27 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
HOST_WIDE_INT));
static void record_set PROTO((rtx, rtx));
static rtx find_base_term PROTO((rtx));
static int base_alias_check PROTO((rtx, rtx));
static int base_alias_check PROTO((rtx, rtx, enum machine_mode,
enum machine_mode));
static rtx find_base_value PROTO((rtx));
static int mems_in_disjoint_alias_sets_p PROTO((rtx, rtx));
static int insert_subset_children PROTO((splay_tree_node,
void*));
static alias_set_entry get_alias_set_entry PROTO((int));
static rtx fixed_scalar_and_varying_struct_p PROTO((rtx, rtx, int (*)(rtx)));
static int aliases_everything_p PROTO((rtx));
static int write_dependence_p PROTO((rtx, rtx, int));
/* Set up all info needed to perform alias analysis on memory references. */
#define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
/* Perform a basic sanity check. Namely, that there are
no alias sets if we're not doing strict aliasing. This helps
to catch bugs whereby someone uses PUT_CODE, but doesn't clear
MEM_ALIAS_SET, or where a MEM is allocated in some way other
than by the use of gen_rtx_MEM, and the MEM_ALIAS_SET is not
cleared. */
#ifdef ENABLE_CHECKING
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) \
(!flag_strict_aliasing \
&& (MEM_ALIAS_SET (MEM1) || MEM_ALIAS_SET (MEM2)) \
? (abort (), 0) : 0)
#else
#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) ((void)0)
#endif
/* Returns nonzero if MEM1 and MEM2 do not alias because they are in
different alias sets. */
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
(CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \
MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \
&& MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2))
different alias sets. We ignore alias sets in functions making use
of variable arguments because the va_arg macros on some systems are
not legal ANSI C. */
#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \
mems_in_disjoint_alias_sets_p (MEM1, MEM2)
/* Cap the number of passes we make over the insns propagating alias
information through set chains.
@ -89,7 +126,7 @@ rtx *reg_base_value;
rtx *new_reg_base_value;
unsigned int reg_base_value_size; /* size of reg_base_value array */
#define REG_BASE_VALUE(X) \
(REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
((unsigned) REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0)
/* Vector of known invariant relationships between registers. Set in
loop unrolling. Indexed by register number, if nonzero the value
@ -126,6 +163,148 @@ char *reg_known_equiv_p;
static int copying_arguments;
/* The splay-tree used to store the various alias set entries. */
static splay_tree alias_sets;
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */
static alias_set_entry
get_alias_set_entry (alias_set)
int alias_set;
{
splay_tree_node sn =
splay_tree_lookup (alias_sets, (splay_tree_key) alias_set);
return sn ? ((alias_set_entry) sn->value) : ((alias_set_entry) 0);
}
/* Returns nonzero value if the alias sets for MEM1 and MEM2 are such
that the two MEMs cannot alias each other. */
static int
mems_in_disjoint_alias_sets_p (mem1, mem2)
rtx mem1;
rtx mem2;
{
alias_set_entry ase;
#ifdef ENABLE_CHECKING
/* Perform a basic sanity check. Namely, that there are no alias sets
if we're not using strict aliasing. This helps to catch bugs
whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or
where a MEM is allocated in some way other than by the use of
gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to
use alias sets to indicate that spilled registers cannot alias each
other, we might need to remove this check. */
if (!flag_strict_aliasing &&
(MEM_ALIAS_SET (mem1) || MEM_ALIAS_SET (mem2)))
abort ();
#endif
/* The code used in varargs macros are often not conforming ANSI C,
which can trick the compiler into making incorrect aliasing
assumptions in these functions. So, we don't use alias sets in
such a function. FIXME: This should be moved into the front-end;
it is a language-dependent notion, and there's no reason not to
still use these checks to handle globals. */
if (current_function_stdarg || current_function_varargs)
return 0;
if (!MEM_ALIAS_SET (mem1) || !MEM_ALIAS_SET (mem2))
/* We have no alias set information for one of the MEMs, so we
have to assume it can alias anything. */
return 0;
if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2))
/* The two alias sets are the same, so they may alias. */
return 0;
/* Iterate through each of the children of the first alias set,
comparing it with the second alias set. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
if (ase && splay_tree_lookup (ase->children,
(splay_tree_key) MEM_ALIAS_SET (mem2)))
return 0;
/* Now do the same, but with the alias sets reversed. */
ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
if (ase && splay_tree_lookup (ase->children,
(splay_tree_key) MEM_ALIAS_SET (mem1)))
return 0;
/* The two MEMs are in distinct alias sets, and neither one is the
child of the other. Therefore, they cannot alias. */
return 1;
}
/* Insert the NODE into the splay tree given by DATA. Used by
record_alias_subset via splay_tree_foreach. */
static int
insert_subset_children (node, data)
splay_tree_node node;
void *data;
{
splay_tree_insert ((splay_tree) data,
node->key,
node->value);
return 0;
}
/* Indicate that things in SUBSET can alias things in SUPERSET, but
not vice versa. For example, in C, a store to an `int' can alias a
structure containing an `int', but not vice versa. Here, the
structure would be the SUPERSET and `int' the SUBSET. This
function should be called only once per SUPERSET/SUBSET pair. At
present any given alias set may only be a subset of one superset.
It is illegal for SUPERSET to be zero; everything is implicitly a
subset of alias set zero. */
void
record_alias_subset (superset, subset)
int superset;
int subset;
{
alias_set_entry superset_entry;
alias_set_entry subset_entry;
if (superset == 0)
abort ();
superset_entry = get_alias_set_entry (superset);
if (!superset_entry)
{
/* Create an entry for the SUPERSET, so that we have a place to
attach the SUBSET. */
superset_entry =
(alias_set_entry) xmalloc (sizeof (struct alias_set_entry));
superset_entry->alias_set = superset;
superset_entry->children
= splay_tree_new (splay_tree_compare_ints, 0, 0);
splay_tree_insert (alias_sets,
(splay_tree_key) superset,
(splay_tree_value) superset_entry);
}
subset_entry = get_alias_set_entry (subset);
if (subset_entry)
/* There is an entry for the subset. Enter all of its children
(if they are not already present) as children of the SUPERSET. */
splay_tree_foreach (subset_entry->children,
insert_subset_children,
superset_entry->children);
/* Enter the SUBSET itself as a child of the SUPERSET. */
splay_tree_insert (superset_entry->children,
(splay_tree_key) subset,
/*value=*/0);
}
/* Inside SRC, the source of a SET, find a base address. */
static rtx
@ -153,7 +332,7 @@ find_base_value (src)
The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if (REGNO (src) >= FIRST_PSEUDO_REGISTER
&& REGNO (src) < reg_base_value_size
&& (unsigned) REGNO (src) < reg_base_value_size
&& reg_base_value[REGNO (src)])
return reg_base_value[REGNO (src)];
@ -336,7 +515,7 @@ record_base_value (regno, val, invariant)
rtx val;
int invariant;
{
if (regno >= reg_base_value_size)
if ((unsigned) regno >= reg_base_value_size)
return;
/* If INVARIANT is true then this value also describes an invariant
@ -347,7 +526,7 @@ record_base_value (regno, val, invariant)
if (GET_CODE (val) == REG)
{
if (REGNO (val) < reg_base_value_size)
if ((unsigned) REGNO (val) < reg_base_value_size)
{
reg_base_value[regno] = reg_base_value[REGNO (val)];
}
@ -391,9 +570,8 @@ canon_rtx (x)
if (addr != XEXP (x, 0))
{
rtx new = gen_rtx_MEM (GET_MODE (x), addr);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
MEM_COPY_ATTRIBUTES (new, x);
MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x);
x = new;
}
@ -568,10 +746,55 @@ find_base_term (x)
case PLUS:
case MINUS:
{
rtx tmp = find_base_term (XEXP (x, 0));
if (tmp)
return tmp;
return find_base_term (XEXP (x, 1));
rtx tmp1 = XEXP (x, 0);
rtx tmp2 = XEXP (x, 1);
/* This is a litle bit tricky since we have to determine which of
the two operands represents the real base address. Otherwise this
routine may return the index register instead of the base register.
That may cause us to believe no aliasing was possible, when in
fact aliasing is possible.
We use a few simple tests to guess the base register. Additional
tests can certainly be added. For example, if one of the operands
is a shift or multiply, then it must be the index register and the
other operand is the base register. */
/* If either operand is known to be a pointer, then use it
to determine the base term. */
if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1)))
return find_base_term (tmp1);
if (REG_P (tmp2) && REGNO_POINTER_FLAG (REGNO (tmp2)))
return find_base_term (tmp2);
/* Neither operand was known to be a pointer. Go ahead and find the
base term for both operands. */
tmp1 = find_base_term (tmp1);
tmp2 = find_base_term (tmp2);
/* If either base term is named object or a special address
(like an argument or stack reference), then use it for the
base term. */
if (tmp1
&& (GET_CODE (tmp1) == SYMBOL_REF
|| GET_CODE (tmp1) == LABEL_REF
|| (GET_CODE (tmp1) == ADDRESS
&& GET_MODE (tmp1) != VOIDmode)))
return tmp1;
if (tmp2
&& (GET_CODE (tmp2) == SYMBOL_REF
|| GET_CODE (tmp2) == LABEL_REF
|| (GET_CODE (tmp2) == ADDRESS
&& GET_MODE (tmp2) != VOIDmode)))
return tmp2;
/* We could not determine which of the two operands was the
base register and which was the index. So we can determine
nothing from the base alias check. */
return 0;
}
case AND:
@ -592,8 +815,9 @@ find_base_term (x)
objects, 1 if they might be pointers to the same object. */
static int
base_alias_check (x, y)
base_alias_check (x, y, x_mode, y_mode)
rtx x, y;
enum machine_mode x_mode, y_mode;
{
rtx x_base = find_base_term (x);
rtx y_base = find_base_term (y);
@ -625,17 +849,25 @@ base_alias_check (x, y)
if (rtx_equal_p (x_base, y_base))
return 1;
/* The base addresses of the read and write are different
expressions. If they are both symbols and they are not accessed
via AND, there is no conflict. */
/* XXX: We can bring knowledge of object alignment and offset into
play here. For example, on alpha, "char a, b;" can alias one
another, though "char a; long b;" cannot. Similarly, offsets
into strutures may be brought into play. Given "char a, b[40];",
a and b[1] may overlap, but a and b[20] do not. */
/* The base addresses of the read and write are different expressions.
If they are both symbols and they are not accessed via AND, there is
no conflict. We can bring knowledge of object alignment into play
here. For example, on alpha, "char a, b;" can alias one another,
though "char a; long b;" cannot. */
if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
{
return GET_CODE (x) == AND || GET_CODE (y) == AND;
if (GET_CODE (x) == AND && GET_CODE (y) == AND)
return 1;
if (GET_CODE (x) == AND
&& (GET_CODE (XEXP (x, 1)) != CONST_INT
|| GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1))))
return 1;
if (GET_CODE (y) == AND
&& (GET_CODE (XEXP (y, 1)) != CONST_INT
|| GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
return 1;
/* Differing symbols never alias. */
return 0;
}
/* If one address is a stack reference there can be no alias:
@ -656,6 +888,45 @@ base_alias_check (x, y)
return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode);
}
/* Return the address of the (N_REFS + 1)th memory reference to ADDR
where SIZE is the size in bytes of the memory reference. If ADDR
is not modified by the memory reference then ADDR is returned. */
rtx
addr_side_effect_eval (addr, size, n_refs)
rtx addr;
int size;
int n_refs;
{
int offset = 0;
switch (GET_CODE (addr))
{
case PRE_INC:
offset = (n_refs + 1) * size;
break;
case PRE_DEC:
offset = -(n_refs + 1) * size;
break;
case POST_INC:
offset = n_refs * size;
break;
case POST_DEC:
offset = -n_refs * size;
break;
default:
return addr;
}
if (offset)
addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), GEN_INT (offset));
else
addr = XEXP (addr, 0);
return addr;
}
/* Return nonzero if X and Y (memory addresses) could reference the
same location in memory. C is an offset accumulator. When
C is nonzero, we are testing aliases between X and Y + C.
@ -685,13 +956,13 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1);
else
x = canon_rtx (x);
x = canon_rtx (addr_side_effect_eval (x, xsize, 0));
if (GET_CODE (y) == HIGH)
y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1);
else
y = canon_rtx (y);
y = canon_rtx (addr_side_effect_eval (y, ysize, 0));
if (rtx_equal_for_memref_p (x, y))
{
@ -726,11 +997,14 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
if (rtx_equal_for_memref_p (x0, y0))
return memrefs_conflict_p (xsize, x1, ysize, y1, c);
if (GET_CODE (x1) == CONST_INT)
if (GET_CODE (y1) == CONST_INT)
return memrefs_conflict_p (xsize, x0, ysize, y0,
c - INTVAL (x1) + INTVAL (y1));
else
return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1));
{
if (GET_CODE (y1) == CONST_INT)
return memrefs_conflict_p (xsize, x0, ysize, y0,
c - INTVAL (x1) + INTVAL (y1));
else
return memrefs_conflict_p (xsize, x0, ysize, y,
c - INTVAL (x1));
}
else if (GET_CODE (y1) == CONST_INT)
return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1));
@ -784,7 +1058,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
/* Are these registers known not to be equal? */
if (alias_invariant)
{
int r_x = REGNO (x), r_y = REGNO (y);
unsigned int r_x = REGNO (x), r_y = REGNO (y);
rtx i_x, i_y; /* invariant relationships of X and Y */
i_x = r_x >= reg_base_value_size ? 0 : alias_invariant[r_x];
@ -804,18 +1078,24 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
}
/* Treat an access through an AND (e.g. a subword access on an Alpha)
as an access with indeterminate size.
??? Could instead convert an n byte reference at (and x y) to an
n-y byte reference at (plus x y). */
as an access with indeterminate size. Assume that references
besides AND are aligned, so if the size of the other reference is
at least as large as the alignment, assume no other overlap. */
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT)
return memrefs_conflict_p (-1, XEXP (x, 0), ysize, y, c);
{
if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
xsize = -1;
return memrefs_conflict_p (xsize, XEXP (x, 0), ysize, y, c);
}
if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
{
/* XXX: If we are indexing far enough into the array/structure, we
/* ??? If we are indexing far enough into the array/structure, we
may yet be able to determine that we can not overlap. But we
also need to that we are far enough from the end not to overlap
a following reference, so we do nothing for now. */
return memrefs_conflict_p (xsize, x, -1, XEXP (y, 0), c);
a following reference, so we do nothing with that for now. */
if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
ysize = -1;
return memrefs_conflict_p (xsize, x, ysize, XEXP (y, 0), c);
}
if (CONSTANT_P (x))
@ -883,6 +1163,56 @@ read_dependence (mem, x)
return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
}
/* Returns MEM1 if and only if MEM1 is a scalar at a fixed address and
MEM2 is a reference to a structure at a varying address, or returns
MEM2 if vice versa. Otherwise, returns NULL_RTX. If a non-NULL
value is returned MEM1 and MEM2 can never alias. VARIES_P is used
to decide whether or not an address may vary; it should return
nozero whenever variation is possible. */
static rtx
fixed_scalar_and_varying_struct_p (mem1, mem2, varies_p)
rtx mem1;
rtx mem2;
int (*varies_p) PROTO((rtx));
{
rtx mem1_addr = XEXP (mem1, 0);
rtx mem2_addr = XEXP (mem2, 0);
if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
&& !varies_p (mem1_addr) && varies_p (mem2_addr))
/* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
varying address. */
return mem1;
if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
&& varies_p (mem1_addr) && !varies_p (mem2_addr))
/* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
varying address. */
return mem2;
return NULL_RTX;
}
/* Returns nonzero if something about the mode or address format MEM1
indicates that it might well alias *anything*. */
static int
aliases_everything_p (mem)
rtx mem;
{
if (GET_MODE (mem) == QImode)
/* ANSI C says that a `char*' can point to anything. */
return 1;
if (GET_CODE (XEXP (mem, 0)) == AND)
/* If the address is an AND, its very hard to know at what it is
actually pointing. */
return 1;
return 0;
}
/* True dependence: X is read after store in MEM takes place. */
int
@ -910,59 +1240,46 @@ true_dependence (mem, mem_mode, x, varies)
if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
return 0;
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
if (mem_mode == VOIDmode)
mem_mode = GET_MODE (mem);
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x), mem_mode))
return 0;
x_addr = canon_rtx (XEXP (x, 0));
mem_addr = canon_rtx (XEXP (mem, 0));
if (mem_mode == VOIDmode)
mem_mode = GET_MODE (mem);
if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0))
return 0;
/* If both references are struct references, or both are not, nothing
is known about aliasing.
If either reference is QImode or BLKmode, ANSI C permits aliasing.
If both addresses are constant, or both are not, nothing is known
about aliasing. */
if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem)
|| mem_mode == QImode || mem_mode == BLKmode
|| GET_MODE (x) == QImode || GET_MODE (x) == BLKmode
|| GET_CODE (x_addr) == AND || GET_CODE (mem_addr) == AND
|| varies (x_addr) == varies (mem_addr))
if (aliases_everything_p (x))
return 1;
/* One memory reference is to a constant address, one is not.
One is to a structure, the other is not.
/* We cannot use aliases_everyting_p to test MEM, since we must look
at MEM_MODE, rather than GET_MODE (MEM). */
if (mem_mode == QImode || GET_CODE (mem_addr) == AND)
return 1;
If either memory reference is a variable structure the other is a
fixed scalar and there is no aliasing. */
/* In true_dependence we also allow BLKmode to alias anything. Why
don't we do this in anti_dependence and output_dependence? */
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1;
/* Disabled by default for egcs 1.1.x as alias analysis isn't good
enough yet to discover all cases where this doesn't apply. */
if (flag_structure_noalias)
{
if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr))
|| (MEM_IN_STRUCT_P (x) && varies (x_addr)))
return 0;
}
return 1;
return !fixed_scalar_and_varying_struct_p (mem, x, varies);
}
/* Anti dependence: X is written after read in MEM takes place. */
/* Returns non-zero if a write to X might alias a previous read from
(or, if WRITEP is non-zero, a write to) MEM. */
int
anti_dependence (mem, x)
static int
write_dependence_p (mem, x, writep)
rtx mem;
rtx x;
int writep;
{
rtx x_addr, mem_addr;
rtx fixed_scalar;
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
@ -970,10 +1287,11 @@ anti_dependence (mem, x)
/* If MEM is an unchanging read, then it can't possibly conflict with
the store to X, because there is at most one store to MEM, and it must
have occurred somewhere before MEM. */
if (RTX_UNCHANGING_P (mem))
if (!writep && RTX_UNCHANGING_P (mem))
return 0;
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x),
GET_MODE (mem)))
return 0;
x = canon_rtx (x);
@ -985,16 +1303,25 @@ anti_dependence (mem, x)
x_addr = XEXP (x, 0);
mem_addr = XEXP (mem, 0);
return (memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0)
&& ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
&& GET_MODE (mem) != QImode
&& GET_CODE (mem_addr) != AND
&& ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
&& ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
&& GET_MODE (x) != QImode
&& GET_CODE (x_addr) != AND
&& ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0))
return 0;
fixed_scalar
= fixed_scalar_and_varying_struct_p (mem, x, rtx_addr_varies_p);
return (!(fixed_scalar == mem && !aliases_everything_p (x))
&& !(fixed_scalar == x && !aliases_everything_p (mem)));
}
/* Anti dependence: X is written after read in MEM takes place. */
int
anti_dependence (mem, x)
rtx mem;
rtx x;
{
return write_dependence_p (mem, x, /*writep=*/0);
}
/* Output dependence: X is written after store in MEM takes place. */
@ -1004,28 +1331,7 @@ output_dependence (mem, x)
register rtx mem;
register rtx x;
{
if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
return 1;
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
return 0;
x = canon_rtx (x);
mem = canon_rtx (mem);
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
SIZE_FOR_MODE (x), XEXP (x, 0), 0)
&& ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
&& GET_MODE (mem) != QImode
&& GET_CODE (XEXP (mem, 0)) != AND
&& ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
&& ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
&& GET_MODE (x) != QImode
&& GET_CODE (XEXP (x, 0)) != AND
&& ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
return write_dependence_p (mem, x, /*writep=*/1);
}
@ -1046,6 +1352,8 @@ init_alias_once ()
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
&& HARD_REGNO_MODE_OK (i, Pmode))
SET_HARD_REG_BIT (argument_registers, i);
alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
}
void
@ -1054,6 +1362,7 @@ init_alias_analysis ()
int maxreg = max_reg_num ();
int changed, pass;
register int i;
register unsigned int ui;
register rtx insn;
reg_known_value_size = maxreg;
@ -1194,13 +1503,13 @@ init_alias_analysis ()
}
/* Now propagate values from new_reg_base_value to reg_base_value. */
for (i = 0; i < reg_base_value_size; i++)
for (ui = 0; ui < reg_base_value_size; ui++)
{
if (new_reg_base_value[i]
&& new_reg_base_value[i] != reg_base_value[i]
&& ! rtx_equal_p (new_reg_base_value[i], reg_base_value[i]))
if (new_reg_base_value[ui]
&& new_reg_base_value[ui] != reg_base_value[ui]
&& ! rtx_equal_p (new_reg_base_value[ui], reg_base_value[ui]))
{
reg_base_value[i] = new_reg_base_value[i];
reg_base_value[ui] = new_reg_base_value[ui];
changed = 1;
}
}
@ -1227,16 +1536,16 @@ init_alias_analysis ()
{
changed = 0;
pass++;
for (i = 0; i < reg_base_value_size; i++)
for (ui = 0; ui < reg_base_value_size; ui++)
{
rtx base = reg_base_value[i];
rtx base = reg_base_value[ui];
if (base && GET_CODE (base) == REG)
{
int base_regno = REGNO (base);
if (base_regno == i) /* register set from itself */
reg_base_value[i] = 0;
unsigned int base_regno = REGNO (base);
if (base_regno == ui) /* register set from itself */
reg_base_value[ui] = 0;
else
reg_base_value[i] = reg_base_value[base_regno];
reg_base_value[ui] = reg_base_value[base_regno];
changed = 1;
}
}

View File

@ -1,5 +1,5 @@
/* Define control and data flow tables, and regsets.
Copyright (C) 1987, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1987, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA. */
#include "bitmap.h"
#include "sbitmap.h"
#include "varray.h"
typedef bitmap regset; /* Head of register set linked list. */
@ -94,29 +96,65 @@ do { \
/* Grow any tables needed when the number of registers is calculated
or extended. For the linked list allocation, nothing needs to
be done, other than zero the statistics on the first allocation. */
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
/* Control flow edge information. */
typedef struct edge_def {
/* Links through the predecessor and successor lists. */
struct edge_def *pred_next, *succ_next;
/* The two blocks at the ends of the edge. */
struct basic_block_def *src, *dest;
/* Instructions queued on the edge. */
rtx insns;
/* Auxiliary info specific to a pass. */
void *aux;
int flags; /* see EDGE_* below */
int probability; /* biased by REG_BR_PROB_BASE */
} *edge;
#define EDGE_FALLTHRU 1
#define EDGE_CRITICAL 2
#define EDGE_ABNORMAL 4
#define EDGE_ABNORMAL_CALL 8
#define EDGE_EH 16
#define EDGE_FAKE 32
/* Basic block information indexed by block number. */
typedef struct basic_block_def {
/* The first and last insns of the block. */
rtx head, end;
/* The edges into and out of the block. */
edge pred, succ;
/* Liveness info. */
regset local_set;
regset global_live_at_start;
regset global_live_at_end;
/* Auxiliary info specific to a pass. */
void *aux;
/* The index of this block. */
int index;
/* The loop depth of this block plus one. */
int loop_depth;
} *basic_block;
/* Number of basic blocks in the current function. */
extern int n_basic_blocks;
/* Index by basic block number, get first insn in the block. */
/* Index by basic block number, get basic block struct info. */
extern rtx *basic_block_head;
extern varray_type basic_block_info;
/* Index by basic block number, get last insn in the block. */
extern rtx *basic_block_end;
/* Index by basic block number, determine whether the block can be reached
through a computed jump. */
extern char *basic_block_computed_jump_target;
/* Index by basic block number, get address of regset
describing the registers live at the start of that block. */
extern regset *basic_block_live_at_start;
#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N)))
/* What registers are live at the setjmp call. */
@ -176,91 +214,49 @@ extern void free_int_list PROTO ((int_list_block **));
/* Stuff for recording basic block info. */
#define BLOCK_HEAD(B) basic_block_head[(B)]
#define BLOCK_END(B) basic_block_end[(B)]
#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head)
#define BLOCK_END(B) (BASIC_BLOCK (B)->end)
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
#define EXIT_BLOCK (-2)
/* from flow.c */
extern void free_regset_vector PROTO ((regset *, int nelts));
extern int *uid_block_number;
#define BLOCK_NUM(INSN) uid_block_number[INSN_UID (INSN)]
/* Similarly, block pointers for the edge list. */
extern struct basic_block_def entry_exit_blocks[2];
#define ENTRY_BLOCK_PTR (&entry_exit_blocks[0])
#define EXIT_BLOCK_PTR (&entry_exit_blocks[1])
extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
int *, int *));
extern void dump_bb_data PROTO ((FILE *, int_list_ptr *, int_list_ptr *));
extern void free_bb_mem PROTO ((void));
/* from flow.c */
extern void free_regset_vector PROTO ((regset *, int nelts));
extern varray_type basic_block_for_insn;
#define BLOCK_FOR_INSN(INSN) VARRAY_BB (basic_block_for_insn, INSN_UID (INSN))
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
extern void set_block_for_insn PROTO ((rtx, basic_block));
extern void dump_bb_data PROTO ((FILE *, int_list_ptr *,
int_list_ptr *, int));
extern void free_bb_mem PROTO ((void));
extern void free_basic_block_vars PROTO ((int));
/* Simple bitmaps.
It's not clear yet whether using bitmap.[ch] will be a win.
It should be straightforward to convert so for now we keep things simple
while more important issues are dealt with. */
extern basic_block split_edge PROTO ((edge));
extern void insert_insn_on_edge PROTO ((rtx, edge));
extern void commit_edge_insertions PROTO ((void));
#define SBITMAP_ELT_BITS HOST_BITS_PER_WIDE_INT
#define SBITMAP_ELT_TYPE unsigned HOST_WIDE_INT
typedef struct simple_bitmap_def {
/* Number of bits. */
int n_bits;
/* Size in elements. */
int size;
/* Size in bytes. */
int bytes;
/* The elements. */
SBITMAP_ELT_TYPE elms[1];
} *sbitmap;
typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
/* Return the set size needed for N elements. */
#define SBITMAP_SET_SIZE(n) (((n) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
/* set bit number bitno in the bitmap */
#define SET_BIT(bitmap, bitno) \
do { \
(bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS; \
} while (0)
/* test if bit number bitno in the bitmap is set */
#define TEST_BIT(bitmap, bitno) \
((bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] & ((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS))
/* reset bit number bitno in the bitmap */
#define RESET_BIT(bitmap, bitno) \
do { \
(bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS); \
} while (0)
extern void dump_sbitmap PROTO ((FILE *, sbitmap));
extern void dump_sbitmap_vector PROTO ((FILE *, char *, char *,
sbitmap *, int));
extern sbitmap sbitmap_alloc PROTO ((int));
extern sbitmap *sbitmap_vector_alloc PROTO ((int, int));
extern void sbitmap_copy PROTO ((sbitmap, sbitmap));
extern void sbitmap_zero PROTO ((sbitmap));
extern void sbitmap_ones PROTO ((sbitmap));
extern void sbitmap_vector_zero PROTO ((sbitmap *, int));
extern void sbitmap_vector_ones PROTO ((sbitmap *, int));
extern int sbitmap_union_of_diff PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern void sbitmap_difference PROTO ((sbitmap, sbitmap, sbitmap));
extern void sbitmap_not PROTO ((sbitmap, sbitmap));
extern int sbitmap_a_or_b_and_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_and_b_or_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_and_b PROTO ((sbitmap, sbitmap, sbitmap));
extern int sbitmap_a_or_b PROTO ((sbitmap, sbitmap, sbitmap));
extern void sbitmap_intersect_of_predsucc PROTO ((sbitmap, sbitmap *,
int, int_list_ptr *));
extern void sbitmap_intersect_of_predecessors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
extern void sbitmap_intersect_of_successors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
extern void sbitmap_union_of_predecessors PROTO ((sbitmap, sbitmap *, int,
int_list_ptr *));
extern void sbitmap_union_of_successors PROTO ((sbitmap, sbitmap *, int,
extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *,
int *, int *));
extern void compute_dominators PROTO ((sbitmap *, sbitmap *,
int_list_ptr *,
int_list_ptr *));
extern void compute_dominators PROTO ((sbitmap *, sbitmap *,
int_list_ptr *, int_list_ptr *));
extern void compute_immediate_dominators PROTO ((int *, sbitmap *));
/* In lcm.c */
extern void pre_lcm PROTO ((int, int, int_list_ptr *,
int_list_ptr *,
sbitmap *, sbitmap *,
sbitmap *, sbitmap *));
extern void pre_rev_lcm PROTO ((int, int, int_list_ptr *,
int_list_ptr *,
sbitmap *, sbitmap *,
sbitmap *, sbitmap *));

View File

@ -613,10 +613,10 @@ void
bitmap_print (file, head, prefix, suffix)
FILE *file;
bitmap head;
char *prefix;
char *suffix;
const char *prefix;
const char *suffix;
{
char *comma = "";
const char *comma = "";
int i;
fputs (prefix, file);

View File

@ -1,5 +1,5 @@
/* Functions to support general ended bitmaps.
Copyright (C) 1997 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -48,7 +48,7 @@ typedef struct bitmap_element_def
typedef struct bitmap_head_def {
bitmap_element *first; /* First element in linked list. */
bitmap_element *current; /* Last element looked at. */
int indx; /* Index of last element looked at. */
unsigned int indx; /* Index of last element looked at. */
} bitmap_head, *bitmap;
/* Enumeration giving the various operations we support. */
@ -89,7 +89,7 @@ extern void bitmap_debug PROTO((bitmap));
extern void bitmap_debug_file PROTO((FILE *, bitmap));
/* Print a bitmap */
extern void bitmap_print PROTO((FILE *, bitmap, char *, char *));
extern void bitmap_print PROTO((FILE *, bitmap, const char *, const char *));
/* Initialize a bitmap header. */
extern bitmap bitmap_initialize PROTO((bitmap));

View File

@ -1,7 +1,7 @@
/* Generate information regarding function declarations and definitions based
on information stored in GCC's tree structure. This code implements the
-aux-info option.
Copyright (C) 1989, 91, 94, 95, 97, 1998 Free Software Foundation, Inc.
Copyright (C) 1989, 91, 94, 95, 97-98, 1999 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@segfault.us.com).
This file is part of GNU CC.
@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "toplev.h"
#include "flags.h"
#include "tree.h"
#include "c-tree.h"
@ -35,67 +36,75 @@ enum formals_style_enum {
typedef enum formals_style_enum formals_style;
static char *data_type;
static const char *data_type;
static char *concat PROTO((char *, char *));
static char *concat3 PROTO((char *, char *, char *));
static char *affix_data_type PROTO((char *));
static char *gen_formal_list_for_type PROTO((tree, formals_style));
static char *affix_data_type PROTO((const char *));
static const char *gen_formal_list_for_type PROTO((tree, formals_style));
static int deserves_ellipsis PROTO((tree));
static char *gen_formal_list_for_func_def PROTO((tree, formals_style));
static char *gen_type PROTO((char *, tree, formals_style));
static char *gen_decl PROTO((tree, int, formals_style));
static const char *gen_formal_list_for_func_def PROTO((tree, formals_style));
static const char *gen_type PROTO((const char *, tree, formals_style));
static const char *gen_decl PROTO((tree, int, formals_style));
/* Take two strings and mash them together into a newly allocated area. */
/* Concatenate a sequence of strings, returning the result.
static char *
concat (s1, s2)
char *s1;
char *s2;
This function is based on the one in libiberty. */
/* This definition will conflict with the one from prefix.c in
libcpp.a when linking cc1 and cc1obj. So only provide it if we are
not using libcpp.a */
#ifndef USE_CPPLIB
char *
concat VPROTO((const char *first, ...))
{
int size1, size2;
char *ret_val;
register int length;
register char *newstr;
register char *end;
register const char *arg;
va_list args;
#ifndef ANSI_PROTOTYPES
const char *first;
#endif
if (!s1)
s1 = "";
if (!s2)
s2 = "";
/* First compute the size of the result and get sufficient memory. */
size1 = strlen (s1);
size2 = strlen (s2);
ret_val = xmalloc (size1 + size2 + 1);
strcpy (ret_val, s1);
strcpy (&ret_val[size1], s2);
return ret_val;
}
/* Take three strings and mash them together into a newly allocated area. */
static char *
concat3 (s1, s2, s3)
char *s1;
char *s2;
char *s3;
{
int size1, size2, size3;
char *ret_val;
if (!s1)
s1 = "";
if (!s2)
s2 = "";
if (!s3)
s3 = "";
size1 = strlen (s1);
size2 = strlen (s2);
size3 = strlen (s3);
ret_val = xmalloc (size1 + size2 + size3 + 1);
strcpy (ret_val, s1);
strcpy (&ret_val[size1], s2);
strcpy (&ret_val[size1+size2], s3);
return ret_val;
VA_START (args, first);
#ifndef ANSI_PROTOTYPES
first = va_arg (args, const char *);
#endif
arg = first;
length = 0;
while (arg != 0)
{
length += strlen (arg);
arg = va_arg (args, const char *);
}
newstr = (char *) malloc (length + 1);
va_end (args);
/* Now copy the individual pieces to the result string. */
VA_START (args, first);
#ifndef ANSI_PROTOTYPES
first = va_arg (args, char *);
#endif
end = newstr;
arg = first;
while (arg != 0)
{
while (*arg)
*end++ = *arg++;
arg = va_arg (args, const char *);
}
*end = '\000';
va_end (args);
return (newstr);
}
#endif /* ! USE_CPPLIB */
/* Given a string representing an entire type or an entire declaration
which only lacks the actual "data-type" specifier (at its left end),
@ -112,13 +121,16 @@ concat3 (s1, s2, s3)
that look as expected. */
static char *
affix_data_type (type_or_decl)
char *type_or_decl;
affix_data_type (param)
const char *param;
{
char *type_or_decl = (char *) alloca (strlen (param) + 1);
char *p = type_or_decl;
char *qualifiers_then_data_type;
char saved;
strcpy (type_or_decl, param);
/* Skip as many leading const's or volatile's as there are. */
for (;;)
@ -140,13 +152,13 @@ affix_data_type (type_or_decl)
add a blank after the data-type of course. */
if (p == type_or_decl)
return concat3 (data_type, " ", type_or_decl);
return concat (data_type, " ", type_or_decl, NULL_PTR);
saved = *p;
*p = '\0';
qualifiers_then_data_type = concat (type_or_decl, data_type);
qualifiers_then_data_type = concat (type_or_decl, data_type, NULL_PTR);
*p = saved;
return concat3 (qualifiers_then_data_type, " ", p);
return concat (qualifiers_then_data_type, " ", p, NULL_PTR);
}
/* Given a tree node which represents some "function type", generate the
@ -156,12 +168,12 @@ affix_data_type (type_or_decl)
we are currently aiming for is non-ansi, then we just return a pair
of empty parens here. */
static char *
static const char *
gen_formal_list_for_type (fntype, style)
tree fntype;
formals_style style;
{
char *formal_list = "";
const char *formal_list = "";
tree formal_type;
if (style != ansi)
@ -170,16 +182,16 @@ gen_formal_list_for_type (fntype, style)
formal_type = TYPE_ARG_TYPES (fntype);
while (formal_type && TREE_VALUE (formal_type) != void_type_node)
{
char *this_type;
const char *this_type;
if (*formal_list)
formal_list = concat (formal_list, ", ");
formal_list = concat (formal_list, ", ", NULL_PTR);
this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
formal_list
= ((strlen (this_type))
? concat (formal_list, affix_data_type (this_type))
: concat (formal_list, data_type));
? concat (formal_list, affix_data_type (this_type), NULL_PTR)
: concat (formal_list, data_type, NULL_PTR));
formal_type = TREE_CHAIN (formal_type);
}
@ -228,10 +240,10 @@ gen_formal_list_for_type (fntype, style)
petered out to a NULL (i.e. without being terminated by a
void_type_node) then we need to tack on an ellipsis. */
if (!formal_type)
formal_list = concat (formal_list, ", ...");
formal_list = concat (formal_list, ", ...", NULL_PTR);
}
return concat3 (" (", formal_list, ")");
return concat (" (", formal_list, ")", NULL_PTR);
}
/* For the generation of an ANSI prototype for a function definition, we have
@ -276,37 +288,37 @@ deserves_ellipsis (fntype)
This routine returns a string which is the source form for the entire
function formal parameter list. */
static char *
static const char *
gen_formal_list_for_func_def (fndecl, style)
tree fndecl;
formals_style style;
{
char *formal_list = "";
const char *formal_list = "";
tree formal_decl;
formal_decl = DECL_ARGUMENTS (fndecl);
while (formal_decl)
{
char *this_formal;
const char *this_formal;
if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
formal_list = concat (formal_list, ", ");
formal_list = concat (formal_list, ", ", NULL_PTR);
this_formal = gen_decl (formal_decl, 0, style);
if (style == k_and_r_decls)
formal_list = concat3 (formal_list, this_formal, "; ");
formal_list = concat (formal_list, this_formal, "; ", NULL_PTR);
else
formal_list = concat (formal_list, this_formal);
formal_list = concat (formal_list, this_formal, NULL_PTR);
formal_decl = TREE_CHAIN (formal_decl);
}
if (style == ansi)
{
if (!DECL_ARGUMENTS (fndecl))
formal_list = concat (formal_list, "void");
formal_list = concat (formal_list, "void", NULL_PTR);
if (deserves_ellipsis (TREE_TYPE (fndecl)))
formal_list = concat (formal_list, ", ...");
formal_list = concat (formal_list, ", ...", NULL_PTR);
}
if ((style == ansi) || (style == k_and_r_names))
formal_list = concat3 (" (", formal_list, ")");
formal_list = concat (" (", formal_list, ")", NULL_PTR);
return formal_list;
}
@ -351,9 +363,9 @@ gen_formal_list_for_func_def (fndecl, style)
to do at this point is for the initial caller to prepend the "data_type"
string onto the returned "seed". */
static char *
static const char *
gen_type (ret_val, t, style)
char *ret_val;
const char *ret_val;
tree t;
formals_style style;
{
@ -368,14 +380,14 @@ gen_type (ret_val, t, style)
{
case POINTER_TYPE:
if (TYPE_READONLY (t))
ret_val = concat ("const ", ret_val);
ret_val = concat ("const ", ret_val, NULL_PTR);
if (TYPE_VOLATILE (t))
ret_val = concat ("volatile ", ret_val);
ret_val = concat ("volatile ", ret_val, NULL_PTR);
ret_val = concat ("*", ret_val);
ret_val = concat ("*", ret_val, NULL_PTR);
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
ret_val = concat3 ("(", ret_val, ")");
ret_val = concat ("(", ret_val, ")", NULL_PTR);
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
@ -383,21 +395,26 @@ gen_type (ret_val, t, style)
case ARRAY_TYPE:
if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style);
ret_val = gen_type (concat (ret_val, "[]", NULL_PTR),
TREE_TYPE (t), style);
else if (int_size_in_bytes (t) == 0)
ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style);
ret_val = gen_type (concat (ret_val, "[0]", NULL_PTR),
TREE_TYPE (t), style);
else
{
int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t)));
char buff[10];
sprintf (buff, "[%d]", size);
ret_val = gen_type (concat (ret_val, buff),
ret_val = gen_type (concat (ret_val, buff, NULL_PTR),
TREE_TYPE (t), style);
}
break;
case FUNCTION_TYPE:
ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style);
ret_val = gen_type (concat (ret_val,
gen_formal_list_for_type (t, style),
NULL_PTR),
TREE_TYPE (t), style);
break;
case IDENTIFIER_NODE:
@ -424,13 +441,14 @@ gen_type (ret_val, t, style)
chain_p = TYPE_FIELDS (t);
while (chain_p)
{
data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
data_type = concat (data_type, "; ");
data_type = concat (data_type, "; ", NULL_PTR);
}
data_type = concat3 ("{ ", data_type, "}");
data_type = concat ("{ ", data_type, "}", NULL_PTR);
}
data_type = concat ("struct ", data_type);
data_type = concat ("struct ", data_type, NULL_PTR);
break;
case UNION_TYPE:
@ -442,13 +460,14 @@ gen_type (ret_val, t, style)
chain_p = TYPE_FIELDS (t);
while (chain_p)
{
data_type = concat (data_type, gen_decl (chain_p, 0, ansi));
data_type = concat (data_type, gen_decl (chain_p, 0, ansi),
NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
data_type = concat (data_type, "; ");
data_type = concat (data_type, "; ", NULL_PTR);
}
data_type = concat3 ("{ ", data_type, "}");
data_type = concat ("{ ", data_type, "}", NULL_PTR);
}
data_type = concat ("union ", data_type);
data_type = concat ("union ", data_type, NULL_PTR);
break;
case ENUMERAL_TYPE:
@ -461,14 +480,14 @@ gen_type (ret_val, t, style)
while (chain_p)
{
data_type = concat (data_type,
IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)));
IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL_PTR);
chain_p = TREE_CHAIN (chain_p);
if (chain_p)
data_type = concat (data_type, ", ");
data_type = concat (data_type, ", ", NULL_PTR);
}
data_type = concat3 ("{ ", data_type, " }");
data_type = concat ("{ ", data_type, " }", NULL_PTR);
}
data_type = concat ("enum ", data_type);
data_type = concat ("enum ", data_type, NULL_PTR);
break;
case TYPE_DECL:
@ -478,9 +497,9 @@ gen_type (ret_val, t, style)
case INTEGER_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
/* Normally, `unsigned' is part of the deal. Not so if it comes
with `const' or `volatile'. */
if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
data_type = concat ("unsigned ", data_type);
with a type qualifier. */
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
data_type = concat ("unsigned ", data_type, NULL_PTR);
break;
case REAL_TYPE:
@ -500,9 +519,11 @@ gen_type (ret_val, t, style)
}
}
if (TYPE_READONLY (t))
ret_val = concat ("const ", ret_val);
ret_val = concat ("const ", ret_val, NULL_PTR);
if (TYPE_VOLATILE (t))
ret_val = concat ("volatile ", ret_val);
ret_val = concat ("volatile ", ret_val, NULL_PTR);
if (TYPE_RESTRICT (t))
ret_val = concat ("restrict ", ret_val, NULL_PTR);
return ret_val;
}
@ -516,13 +537,13 @@ gen_type (ret_val, t, style)
associated with a function definition. In this case, we can assume that
an attached list of DECL nodes for function formal arguments is present. */
static char *
static const char *
gen_decl (decl, is_func_definition, style)
tree decl;
int is_func_definition;
formals_style style;
{
char *ret_val;
const char *ret_val;
if (DECL_NAME (decl))
ret_val = IDENTIFIER_POINTER (DECL_NAME (decl));
@ -544,9 +565,9 @@ gen_decl (decl, is_func_definition, style)
generate the qualifiers here. */
if (TREE_THIS_VOLATILE (decl))
ret_val = concat ("volatile ", ret_val);
ret_val = concat ("volatile ", ret_val, NULL_PTR);
if (TREE_READONLY (decl))
ret_val = concat ("const ", ret_val);
ret_val = concat ("const ", ret_val, NULL_PTR);
data_type = "";
@ -564,7 +585,8 @@ gen_decl (decl, is_func_definition, style)
if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition)
{
ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi));
ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi),
NULL_PTR);
/* Since we have already added in the formals list stuff, here we don't
add the whole "type" of the function we are considering (which
@ -581,11 +603,11 @@ gen_decl (decl, is_func_definition, style)
ret_val = affix_data_type (ret_val);
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
ret_val = concat ("register ", ret_val);
ret_val = concat ("register ", ret_val, NULL_PTR);
if (TREE_PUBLIC (decl))
ret_val = concat ("extern ", ret_val);
ret_val = concat ("extern ", ret_val, NULL_PTR);
if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl))
ret_val = concat ("static ", ret_val);
ret_val = concat ("static ", ret_val, NULL_PTR);
return ret_val;
}

View File

@ -1,5 +1,5 @@
/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -27,6 +27,8 @@ Boston, MA 02111-1307, USA. */
#include "obstack.h"
#include "toplev.h"
#include "output.h"
#include "c-pragma.h"
#include "rtl.h"
#if USE_CPPLIB
#include "cpplib.h"
@ -50,19 +52,22 @@ extern struct obstack permanent_obstack;
int skip_evaluation;
enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
enum format_type { printf_format_type, scanf_format_type,
strftime_format_type };
static void declare_hidden_char_array PROTO((char *, char *));
static void add_attribute PROTO((enum attrs, char *,
static void declare_hidden_char_array PROTO((const char *, const char *));
static void add_attribute PROTO((enum attrs, const char *,
int, int, int));
static void init_attributes PROTO((void));
static void record_function_format PROTO((tree, tree, enum format_type,
int, int));
static void record_international_format PROTO((tree, tree, int));
static tree c_find_base_decl PROTO((tree));
static int default_valid_lang_attribute PROTO ((tree, tree, tree, tree));
/* Keep a stack of if statements. We record the number of compound
statements seen up to the if keyword, as well as the line number
@ -73,9 +78,10 @@ typedef struct
{
int compstmt_count;
int line;
char *file;
const char *file;
int needs_warning;
} if_elt;
static void tfaff PROTO((void));
static if_elt *if_stack;
@ -153,12 +159,12 @@ c_expand_start_else ()
expand_start_else ();
}
/* Make bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */
/* Make bindings for __FUNCTION__, __PRETTY_FUNCTION__, and __func__. */
void
declare_function_name ()
{
char *name, *printable_name;
const char *name, *printable_name;
if (current_function_decl == NULL)
{
@ -177,11 +183,14 @@ declare_function_name ()
declare_hidden_char_array ("__FUNCTION__", name);
declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name);
/* The ISO C people "of course" couldn't use __FUNCTION__ in the
ISO C 9x standard; instead a new variable is invented. */
declare_hidden_char_array ("__func__", name);
}
static void
declare_hidden_char_array (name, value)
char *name, *value;
const char *name, *value;
{
tree decl, type, init;
int vlen;
@ -262,7 +271,7 @@ combine_strings (strings)
? wchar_bytes : 1));
if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag)
{
bcopy (TREE_STRING_POINTER (t), q, len);
memcpy (q, TREE_STRING_POINTER (t), len);
q += len;
}
else
@ -290,7 +299,6 @@ combine_strings (strings)
value = make_node (STRING_CST);
TREE_STRING_POINTER (value) = p;
TREE_STRING_LENGTH (value) = length;
TREE_CONSTANT (value) = 1;
}
else
{
@ -305,8 +313,9 @@ combine_strings (strings)
/* Create the array type for the string constant.
-Wwrite-strings says make the string constant an array of const char
so that copying it to a non-const pointer will get a warning. */
if (warn_write_strings
so that copying it to a non-const pointer will get a warning.
For C++, this is the standard behavior. */
if (flag_const_strings
&& (! flag_traditional && ! flag_writable_strings))
{
tree elements
@ -320,7 +329,8 @@ combine_strings (strings)
TREE_TYPE (value)
= build_array_type (wide_flag ? wchar_type_node : char_type_node,
build_index_type (build_int_2 (nchars - 1, 0)));
TREE_CONSTANT (value) = 1;
TREE_READONLY (value) = TREE_CONSTANT (value) = ! flag_writable_strings;
TREE_STATIC (value) = 1;
return value;
}
@ -339,7 +349,7 @@ static int attrtab_idx = 0;
static void
add_attribute (id, string, min_len, max_len, decl_req)
enum attrs id;
char *string;
const char *string;
int min_len, max_len;
int decl_req;
{
@ -382,8 +392,29 @@ init_attributes ()
add_attribute (A_FORMAT_ARG, "format_arg", 1, 1, 1);
add_attribute (A_WEAK, "weak", 0, 0, 1);
add_attribute (A_ALIAS, "alias", 1, 1, 1);
add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1);
add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1);
}
/* Default implementation of valid_lang_attribute, below. By default, there
are no language-specific attributes. */
static int
default_valid_lang_attribute (attr_name, attr_args, decl, type)
tree attr_name ATTRIBUTE_UNUSED;
tree attr_args ATTRIBUTE_UNUSED;
tree decl ATTRIBUTE_UNUSED;
tree type ATTRIBUTE_UNUSED;
{
return 0;
}
/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid language-specific
attribute for either declaration DECL or type TYPE and 0 otherwise. */
int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree))
= default_valid_lang_attribute;
/* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
and install them in NODE, which is either a DECL (including a TYPE_DECL)
or a TYPE. PREFIX_ATTRIBUTES can appear after the declaration specifiers
@ -409,6 +440,18 @@ decl_attributes (node, attributes, prefix_attributes)
else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't')
type = node, is_type = 1;
#ifdef PRAGMA_INSERT_ATTRIBUTES
/* If the code in c-pragma.c wants to insert some attributes then
allow it to do so. Do this before allowing machine back ends to
insert attributes, so that they have the opportunity to override
anything done here. */
PRAGMA_INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
#endif
#ifdef INSERT_ATTRIBUTES
INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes);
#endif
attributes = chainon (prefix_attributes, attributes);
for (a = attributes; a; a = TREE_CHAIN (a))
@ -424,7 +467,8 @@ decl_attributes (node, attributes, prefix_attributes)
if (i == attrtab_idx)
{
if (! valid_machine_attribute (name, args, decl, type))
if (! valid_machine_attribute (name, args, decl, type)
&& ! (* valid_lang_attribute) (name, args, decl, type))
warning ("`%s' attribute directive ignored",
IDENTIFIER_POINTER (name));
else if (decl != 0)
@ -491,7 +535,8 @@ decl_attributes (node, attributes, prefix_attributes)
TREE_USED (type) = 1;
else if (TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL)
|| TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == LABEL_DECL)
TREE_USED (decl) = 1;
else
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@ -555,7 +600,7 @@ decl_attributes (node, attributes, prefix_attributes)
else
{
int j;
char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
int len = strlen (p);
enum machine_mode mode = VOIDmode;
tree typefm;
@ -633,7 +678,7 @@ decl_attributes (node, attributes, prefix_attributes)
= (args ? TREE_VALUE (args)
: size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
int align;
/* Strip any NOPs of any kind. */
while (TREE_CODE (align_expr) == NOP_EXPR
|| TREE_CODE (align_expr) == CONVERT_EXPR
@ -687,7 +732,7 @@ decl_attributes (node, attributes, prefix_attributes)
}
else
{
char *p = IDENTIFIER_POINTER (format_type_id);
const char *p = IDENTIFIER_POINTER (format_type_id);
if (!strcmp (p, "printf") || !strcmp (p, "__printf__"))
format_type = printf_format_type;
@ -698,7 +743,7 @@ decl_attributes (node, attributes, prefix_attributes)
format_type = strftime_format_type;
else
{
error ("`%s' is an unrecognized format function type", p);
warning ("`%s' is an unrecognized format function type", p);
continue;
}
}
@ -864,6 +909,40 @@ decl_attributes (node, attributes, prefix_attributes)
else
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
break;
case A_NO_CHECK_MEMORY_USAGE:
if (TREE_CODE (decl) != FUNCTION_DECL)
{
error_with_decl (decl,
"`%s' attribute applies only to functions",
IDENTIFIER_POINTER (name));
}
else if (DECL_INITIAL (decl))
{
error_with_decl (decl,
"can't set `%s' attribute after definition",
IDENTIFIER_POINTER (name));
}
else
DECL_NO_CHECK_MEMORY_USAGE (decl) = 1;
break;
case A_NO_INSTRUMENT_FUNCTION:
if (TREE_CODE (decl) != FUNCTION_DECL)
{
error_with_decl (decl,
"`%s' attribute applies only to functions",
IDENTIFIER_POINTER (name));
}
else if (DECL_INITIAL (decl))
{
error_with_decl (decl,
"can't set `%s' attribute after definition",
IDENTIFIER_POINTER (name));
}
else
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
break;
}
}
}
@ -983,7 +1062,7 @@ strip_attrs (specs_attrs)
#define T_ST &sizetype
typedef struct {
char *format_chars;
const char *format_chars;
int pointer_count;
/* Type of argument if no length modifier is used. */
tree *nolen;
@ -1006,7 +1085,7 @@ typedef struct {
If NULL, then this modifier is not allowed. */
tree *zlen;
/* List of other modifier characters allowed with these options. */
char *flag_chars;
const char *flag_chars;
} format_char_info;
static format_char_info print_char_table[] = {
@ -1022,7 +1101,7 @@ static format_char_info print_char_table[] = {
{ "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" },
{ "p", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-w" },
{ "n", 1, T_I, NULL, T_S, T_L, T_LL, NULL, NULL, "" },
{ NULL }
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
static format_char_info scan_char_table[] = {
@ -1036,7 +1115,7 @@ static format_char_info scan_char_table[] = {
{ "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "*a" },
{ "p", 2, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "*" },
{ "n", 1, T_I, T_C, T_S, T_L, T_LL, NULL, NULL, "" },
{ NULL }
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
/* Handle format characters recognized by glibc's strftime.c.
@ -1061,7 +1140,7 @@ static format_char_info time_char_table[] = {
{ "p", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "#" },
{ "bh", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "^" },
{ "CY", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0EOw" },
{ NULL }
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
typedef struct function_format_info
@ -1206,7 +1285,11 @@ record_international_format (name, assembler_name, format_num)
info->format_num = format_num;
}
static char tfaff[] = "too few arguments for format";
static void
tfaff ()
{
warning ("too few arguments for format");
}
/* Check the argument list of a call to printf, scanf, etc.
NAME is the function identifier.
@ -1256,7 +1339,7 @@ check_format_info (info, params)
tree cur_type;
tree wanted_type;
tree first_fillin_param;
char *format_chars;
const char *format_chars;
format_char_info *fci = NULL;
char flag_chars[8];
int has_operand_number = 0;
@ -1420,7 +1503,7 @@ check_format_info (info, params)
it is an operand number, so set PARAMS to that operand. */
if (*format_chars >= '0' && *format_chars <= '9')
{
char *p = format_chars;
const char *p = format_chars;
while (*p >= '0' && *p++ <= '9')
;
@ -1473,7 +1556,7 @@ check_format_info (info, params)
++format_chars;
if (params == 0)
{
warning (tfaff);
tfaff ();
return;
}
if (info->first_arg_num != 0)
@ -1516,7 +1599,7 @@ check_format_info (info, params)
++format_chars;
if (params == 0)
{
warning (tfaff);
tfaff ();
return;
}
cur_param = TREE_VALUE (params);
@ -1686,7 +1769,7 @@ check_format_info (info, params)
if (precise && index (flag_chars, '0') != 0
&& (format_char == 'd' || format_char == 'i'
|| format_char == 'o' || format_char == 'u'
|| format_char == 'x' || format_char == 'x'))
|| format_char == 'x' || format_char == 'X'))
warning ("`0' flag ignored with precision specifier and `%c' format",
format_char);
switch (length_char)
@ -1711,7 +1794,7 @@ check_format_info (info, params)
continue;
if (params == 0)
{
warning (tfaff);
tfaff ();
return;
}
cur_param = TREE_VALUE (params);
@ -1737,9 +1820,9 @@ check_format_info (info, params)
continue;
}
if (TREE_CODE (cur_type) != ERROR_MARK)
warning ("format argument is not a %s (arg %d)",
((fci->pointer_count + aflag == 1)
? "pointer" : "pointer to a pointer"),
warning ((fci->pointer_count + aflag == 1
? "format argument is not a pointer (arg %d)"
: "format argument is not a pointer to a pointer (arg %d)"),
arg_num);
break;
}
@ -1779,8 +1862,8 @@ check_format_info (info, params)
&& (TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node
|| TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node)))
{
register char *this;
register char *that;
register const char *this;
register const char *that;
this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
that = 0;
@ -2049,8 +2132,10 @@ type_for_mode (mode, unsignedp)
if (mode == TYPE_MODE (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
if (mode == TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
if (mode == TYPE_MODE (float_type_node))
return float_type_node;
@ -2108,7 +2193,7 @@ void
binary_op_error (code)
enum tree_code code;
{
register char *opname;
register const char *opname;
switch (code)
{
@ -2399,18 +2484,18 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
/* This is the case of (char)x >?< 0x80, which people used to use
expecting old C compilers to change the 0x80 into -0x80. */
if (val == boolean_false_node)
warning ("comparison is always 0 due to limited range of data type");
warning ("comparison is always false due to limited range of data type");
if (val == boolean_true_node)
warning ("comparison is always 1 due to limited range of data type");
warning ("comparison is always true due to limited range of data type");
}
if (!min_lt && unsignedp0 && TREE_CODE (primop0) != INTEGER_CST)
{
/* This is the case of (unsigned char)x >?< -1 or < 0. */
if (val == boolean_false_node)
warning ("comparison is always 0 due to limited range of data type");
warning ("comparison is always false due to limited range of data type");
if (val == boolean_true_node)
warning ("comparison is always 1 due to limited range of data type");
warning ("comparison is always true due to limited range of data type");
}
if (val != 0)
@ -2476,7 +2561,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! (TREE_CODE (primop0) == INTEGER_CST
&& ! TREE_OVERFLOW (convert (signed_type (type),
primop0))))
warning ("unsigned value >= 0 is always 1");
warning ("comparison of unsigned expression >= 0 is always true");
value = boolean_true_node;
break;
@ -2485,7 +2570,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! (TREE_CODE (primop0) == INTEGER_CST
&& ! TREE_OVERFLOW (convert (signed_type (type),
primop0))))
warning ("unsigned value < 0 is always 0");
warning ("comparison of unsigned expression < 0 is always false");
value = boolean_false_node;
break;
@ -2710,7 +2795,7 @@ truthvalue_conversion (expr)
unsigned char *yy_cur, *yy_lim;
#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
#define UNGETC(c) ((c), yy_cur--)
#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--)
int
yy_get_token ()
@ -2884,15 +2969,134 @@ get_directive_line (finput)
down to the element type of an array. */
tree
c_build_type_variant (type, constp, volatilep)
c_build_qualified_type (type, type_quals)
tree type;
int constp, volatilep;
int type_quals;
{
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
the C++ front-end also use POINTER_TYPE for pointer-to-member
values, so even though it should be illegal to use `restrict'
with such an entity we don't flag that here. Thus, special case
code for that case is required in the C++ front-end. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
{
error ("invalid use of `restrict'");
type_quals &= ~TYPE_QUAL_RESTRICT;
}
if (TREE_CODE (type) == ARRAY_TYPE)
return build_array_type (c_build_type_variant (TREE_TYPE (type),
constp, volatilep),
return build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals),
TYPE_DOMAIN (type));
return build_type_variant (type, constp, volatilep);
return build_qualified_type (type, type_quals);
}
/* Apply the TYPE_QUALS to the new DECL. */
void
c_apply_type_quals_to_decl (type_quals, decl)
int type_quals;
tree decl;
{
if (type_quals & TYPE_QUAL_CONST)
TREE_READONLY (decl) = 1;
if (type_quals & TYPE_QUAL_VOLATILE)
{
TREE_SIDE_EFFECTS (decl) = 1;
TREE_THIS_VOLATILE (decl) = 1;
}
if (type_quals & TYPE_QUAL_RESTRICT)
{
if (!TREE_TYPE (decl)
|| !POINTER_TYPE_P (TREE_TYPE (decl))
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
error ("invalid use of `restrict'");
else if (flag_strict_aliasing)
{
/* No two restricted pointers can point at the same thing.
However, a restricted pointer can point at the same thing
as an unrestricted pointer, if that unrestricted pointer
is based on the restricted pointer. So, we make the
alias set for the restricted pointer a subset of the
alias set for the type pointed to by the type of the
decl. */
int pointed_to_alias_set
= get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
if (!pointed_to_alias_set)
/* It's not legal to make a subset of alias set zero. */
;
else
{
DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
record_alias_subset (pointed_to_alias_set,
DECL_POINTER_ALIAS_SET (decl));
}
}
}
}
/* T is an expression with pointer type. Find the DECL on which this
expression is based. (For example, in `a[i]' this would be `a'.)
If there is no such DECL, or a unique decl cannot be determined,
NULL_TREE is retured. */
static tree
c_find_base_decl (t)
tree t;
{
int i;
tree decl;
if (t == NULL_TREE || t == error_mark_node)
return NULL_TREE;
if (!POINTER_TYPE_P (TREE_TYPE (t)))
return NULL_TREE;
decl = NULL_TREE;
if (TREE_CODE (t) == FIELD_DECL
|| TREE_CODE (t) == PARM_DECL
|| TREE_CODE (t) == VAR_DECL)
/* Aha, we found a pointer-typed declaration. */
return t;
/* It would be nice to deal with COMPONENT_REFs here. If we could
tell that `a' and `b' were the same, then `a->f' and `b->f' are
also the same. */
/* Handle general expressions. */
switch (TREE_CODE_CLASS (TREE_CODE (t)))
{
case '1':
case '2':
case '3':
for (i = tree_code_length [(int) TREE_CODE (t)]; --i >= 0;)
{
tree d = c_find_base_decl (TREE_OPERAND (t, i));
if (d)
{
if (!decl)
decl = d;
else if (d && d != decl)
/* Two different declarations. That's confusing; let's
just assume we don't know what's going on. */
decl = NULL_TREE;
}
}
break;
default:
break;
}
return decl;
}
/* Return the typed-based alias set for T, which may be an expression
@ -2902,21 +3106,20 @@ int
c_get_alias_set (t)
tree t;
{
static int next_set = 0;
tree type;
tree u;
if (t == error_mark_node)
return 0;
type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
? t : TREE_TYPE (t);
? t : TREE_TYPE (t);
if (type == error_mark_node)
return 0;
if (TYPE_ALIAS_SET_KNOWN_P (type))
/* If we've already calculated the value, just return it. */
return TYPE_ALIAS_SET (type);
/* Deal with special cases first; for certain kinds of references
we're interested in more than just the type. */
if (TREE_CODE (t) == BIT_FIELD_REF)
/* Perhaps reads and writes to this piece of data alias fields
@ -2924,22 +3127,48 @@ c_get_alias_set (t)
let's just assume that bitfields can alias everything, which is
the conservative assumption. */
return 0;
if (TREE_CODE (t) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
/* Permit type-punning when accessing a union, provided the
access is directly through the union. For example, this code does
not permit taking the address of a union member and then
storing through it. Even the type-punning allowed here is a
GCC extension, albeit a common and useful one; the C standard
says that such accesses have implementation-defined behavior. */
return 0;
else if (TYPE_MAIN_VARIANT (type) != type)
/* Permit type-punning when accessing a union, provided the access
is directly through the union. For example, this code does not
permit taking the address of a union member and then storing
through it. Even the type-punning allowed here is a GCC
extension, albeit a common and useful one; the C standard says
that such accesses have implementation-defined behavior. */
for (u = t;
TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
u = TREE_OPERAND (u, 0))
if (TREE_CODE (u) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
return 0;
if (TREE_CODE (t) == INDIRECT_REF)
{
/* The C standard specifically allows aliasing between
cv-qualified variants of types. */
TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
return TYPE_ALIAS_SET (type);
/* Check for accesses through restrict-qualified pointers. */
tree decl = c_find_base_decl (TREE_OPERAND (t, 0));
if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl))
/* We use the alias set indicated in the declaration. */
return DECL_POINTER_ALIAS_SET (decl);
}
/* From here on, only the type matters. */
if (TREE_CODE (t) == COMPONENT_REF
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)))
/* Since build_modify_expr calls get_unwidened for stores to
component references, the type of a bit field can be changed
from (say) `unsigned int : 16' to `unsigned short' or from
`enum E : 16' to `short'. We want the real type of the
bit-field in this case, not some the integral equivalent. */
type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1));
if (TYPE_ALIAS_SET_KNOWN_P (type))
/* If we've already calculated the value, just return it. */
return TYPE_ALIAS_SET (type);
else if (TYPE_MAIN_VARIANT (type) != type)
/* The C standard specifically allows aliasing between
cv-qualified variants of types. */
TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type));
else if (TREE_CODE (type) == INTEGER_TYPE)
{
tree signed_variant;
@ -2950,34 +3179,37 @@ c_get_alias_set (t)
signed_variant = signed_type (type);
if (signed_variant != type)
{
TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
return TYPE_ALIAS_SET (type);
}
TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant);
else if (signed_variant == signed_char_type_node)
/* The C standard guarantess that any object may be accessed
via an lvalue that has character type. We don't have to
check for unsigned_char_type_node or char_type_node because
we are specifically looking at the signed variant. */
{
TYPE_ALIAS_SET (type) = 0;
return TYPE_ALIAS_SET (type);
}
TYPE_ALIAS_SET (type) = 0;
}
else if (TREE_CODE (type) == ARRAY_TYPE)
/* Anything that can alias one of the array elements can alias
the entire array as well. */
TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type));
else if (TREE_CODE (type) == FUNCTION_TYPE)
/* There are no objects of FUNCTION_TYPE, so there's no point in
using up an alias set for them. (There are, of course,
pointers and references to functions, but that's
different.) */
TYPE_ALIAS_SET (type) = 0;
else if (TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
{
/* If TYPE is a struct or union type then we're reading or
writing an entire struct. Thus, we don't know anything about
aliasing. (In theory, such an access can only alias objects
whose type is the same as one of the fields, recursively, but
we don't yet make any use of that information.) */
TYPE_ALIAS_SET (type) = 0;
return TYPE_ALIAS_SET (type);
}
/* If TYPE is a struct or union type then we're reading or
writing an entire struct. Thus, we don't know anything about
aliasing. (In theory, such an access can only alias objects
whose type is the same as one of the fields, recursively, but
we don't yet make any use of that information.) */
TYPE_ALIAS_SET (type) = 0;
if (!TYPE_ALIAS_SET_KNOWN_P (type))
/* TYPE is something we haven't seen before. Put it in a new
alias set. */
TYPE_ALIAS_SET (type) = new_alias_set ();
/* TYPE is something we haven't seen before. Put it in a new alias
set. */
TYPE_ALIAS_SET (type) = ++next_set;
return TYPE_ALIAS_SET (type);
}

View File

@ -1,5 +1,5 @@
/* Language-level data type conversion for GNU C.
Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
Copyright (C) 1987, 1988, 1991, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.

View File

@ -1,5 +1,5 @@
/* Process declarations and variables for C compiler.
Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -37,9 +37,7 @@ Boston, MA 02111-1307, USA. */
#if USE_CPPLIB
#include "cpplib.h"
extern cpp_reader parse_in;
extern cpp_options parse_options;
static int cpp_initialized;
extern cpp_reader parse_in;
#endif
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
@ -151,13 +149,17 @@ tree intQI_type_node;
tree intHI_type_node;
tree intSI_type_node;
tree intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
tree intTI_type_node;
#endif
tree unsigned_intQI_type_node;
tree unsigned_intHI_type_node;
tree unsigned_intSI_type_node;
tree unsigned_intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
tree unsigned_intTI_type_node;
#endif
/* a VOID_TYPE node. */
@ -424,7 +426,7 @@ tree static_ctors, static_dtors;
static struct binding_level * make_binding_level PROTO((void));
static void clear_limbo_values PROTO((tree));
static int duplicate_decls PROTO((tree, tree, int));
static char *redeclaration_error_message PROTO((tree, tree));
static int redeclaration_error_message PROTO((tree, tree));
static void storedecls PROTO((tree));
static void storetags PROTO((tree));
static tree lookup_tag PROTO((enum tree_code, tree,
@ -464,6 +466,10 @@ int flag_no_nonansi_builtin;
int flag_traditional;
/* Nonzero means use the ISO C9x dialect of C. */
int flag_isoc9x = 0;
/* Nonzero means that we have builtin functions, and main is an int */
int flag_hosted = 1;
@ -477,10 +483,6 @@ int flag_allow_single_precision = 0;
int flag_signed_bitfields = 1;
int explicit_flag_signed_bitfields = 0;
/* Nonzero means handle `#ident' directives. 0 means ignore them. */
int flag_no_ident = 0;
/* Nonzero means warn about use of implicit int. */
int warn_implicit_int;
@ -498,7 +500,7 @@ int mesg_implicit_function_declaration;
to get extra warnings from them. These warnings will be too numerous
to be useful, except in thoroughly ANSIfied programs. */
int warn_write_strings;
int flag_const_strings;
/* Nonzero means warn about pointer casts that can drop a type qualifier
from the pointer target type. */
@ -511,6 +513,10 @@ int warn_cast_qual;
int warn_bad_function_cast;
/* Warn about functions which might be candidates for attribute noreturn. */
int warn_missing_noreturn;
/* Warn about traditional constructs whose meanings changed in ANSI C. */
int warn_traditional;
@ -597,19 +603,12 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
int
c_decode_option (argc, argv)
int argc;
int argc ATTRIBUTE_UNUSED;
char **argv;
{
int strings_processed;
char *p = argv[0];
#if USE_CPPLIB
if (! cpp_initialized)
{
cpp_reader_init (&parse_in);
parse_in.data = &parse_options;
cpp_options_init (&parse_options);
cpp_initialized = 1;
}
strings_processed = cpp_handle_option (&parse_in, argc, argv);
#else
strings_processed = 0;
@ -640,6 +639,63 @@ c_decode_option (argc, argv)
flag_traditional = 0;
flag_writable_strings = 0;
}
else if (!strncmp (p, "-std=", 5))
{
/* Select the appropriate language standard. We currently
recognize:
-std=iso9899:1990 same as -ansi
-std=iso9899:199409 ISO C as modified in amend. 1
-std=iso9899:199x ISO C 9x
-std=c89 same as -std=iso9899:1990
-std=c9x same as -std=iso9899:199x
-std=gnu89 default, iso9899:1990 + gnu extensions
-std=gnu9x iso9899:199x + gnu extensions
*/
const char *argstart = &p[5];
if (!strcmp (argstart, "iso9899:1990")
|| !strcmp (argstart, "c89"))
{
iso_1990:
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
flag_isoc9x = 0;
}
else if (!strcmp (argstart, "iso9899:199409"))
{
/* ??? The changes since ISO C 1990 are not supported. */
goto iso_1990;
}
else if (!strcmp (argstart, "iso9899:199x")
|| !strcmp (argstart, "c9x"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 1;
flag_no_nonansi_builtin = 1;
flag_isoc9x = 1;
}
else if (!strcmp (argstart, "gnu89"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
flag_isoc9x = 0;
}
else if (!strcmp (argstart, "gnu9x"))
{
flag_traditional = 0;
flag_writable_strings = 0;
flag_no_asm = 0;
flag_no_nonansi_builtin = 0;
flag_isoc9x = 1;
}
else
error ("unknown C standard `%s'", argstart);
}
else if (!strcmp (p, "-fdollars-in-identifiers"))
dollars_in_ident = 1;
else if (!strcmp (p, "-fno-dollars-in-identifiers"))
@ -684,12 +740,8 @@ c_decode_option (argc, argv)
flag_no_builtin = 0;
else if (!strcmp (p, "-fno-builtin"))
flag_no_builtin = 1;
else if (!strcmp (p, "-fno-ident"))
flag_no_ident = 1;
else if (!strcmp (p, "-fident"))
flag_no_ident = 0;
else if (!strcmp (p, "-ansi"))
flag_no_asm = 1, flag_no_nonansi_builtin = 1;
goto iso_1990;
else if (!strcmp (p, "-Werror-implicit-function-declaration"))
mesg_implicit_function_declaration = 2;
else if (!strcmp (p, "-Wimplicit-function-declaration"))
@ -713,9 +765,9 @@ c_decode_option (argc, argv)
else if (!strcmp (p, "-Wno-long-long"))
warn_long_long = 0;
else if (!strcmp (p, "-Wwrite-strings"))
warn_write_strings = 1;
flag_const_strings = 1;
else if (!strcmp (p, "-Wno-write-strings"))
warn_write_strings = 0;
flag_const_strings = 0;
else if (!strcmp (p, "-Wcast-qual"))
warn_cast_qual = 1;
else if (!strcmp (p, "-Wno-cast-qual"))
@ -724,6 +776,10 @@ c_decode_option (argc, argv)
warn_bad_function_cast = 1;
else if (!strcmp (p, "-Wno-bad-function-cast"))
warn_bad_function_cast = 0;
else if (!strcmp (p, "-Wmissing-noreturn"))
warn_missing_noreturn = 1;
else if (!strcmp (p, "-Wno-missing-noreturn"))
warn_missing_noreturn = 0;
else if (!strcmp (p, "-Wpointer-arith"))
warn_pointer_arith = 1;
else if (!strcmp (p, "-Wno-pointer-arith"))
@ -799,7 +855,7 @@ c_decode_option (argc, argv)
else if (!strcmp (p, "-Wmain"))
warn_main = 1;
else if (!strcmp (p, "-Wno-main"))
warn_main = 0;
warn_main = -1;
else if (!strcmp (p, "-Wsign-compare"))
warn_sign_compare = 1;
else if (!strcmp (p, "-Wno-sign-compare"))
@ -942,7 +998,7 @@ kept_level_p ()
void
declare_parm_level (definition_flag)
int definition_flag;
int definition_flag ATTRIBUTE_UNUSED;
{
current_binding_level->parm_flag = 1;
}
@ -1059,24 +1115,22 @@ poplevel (keep, reverse, functionbody)
if (TYPE_SIZE (TREE_VALUE (link)) == 0)
{
tree type = TREE_VALUE (link);
char *errmsg;
tree type_name = TYPE_NAME (type);
char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
? type_name
: DECL_NAME (type_name));
switch (TREE_CODE (type))
{
case RECORD_TYPE:
errmsg = "`struct %s' incomplete in scope ending here";
error ("`struct %s' incomplete in scope ending here", id);
break;
case UNION_TYPE:
errmsg = "`union %s' incomplete in scope ending here";
error ("`union %s' incomplete in scope ending here", id);
break;
case ENUMERAL_TYPE:
errmsg = "`enum %s' incomplete in scope ending here";
error ("`enum %s' incomplete in scope ending here", id);
break;
}
if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type)));
else
/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
}
#endif /* 0 */
@ -1456,7 +1510,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& DECL_INITIAL (newdecl) != 0);
tree oldtype = TREE_TYPE (olddecl);
tree newtype = TREE_TYPE (newdecl);
char *errmsg = 0;
int errmsg = 0;
if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
DECL_MACHINE_ATTRIBUTES (newdecl)
@ -1683,16 +1737,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (TREE_CHAIN (t) == 0
&& TYPE_MAIN_VARIANT (type) != void_type_node)
{
error ("A parameter list with an ellipsis can't match");
error ("an empty parameter name list declaration.");
error ("A parameter list with an ellipsis can't match an empty parameter name list declaration.");
break;
}
if (TYPE_MAIN_VARIANT (type) == float_type_node
|| C_PROMOTING_INTEGER_TYPE_P (type))
{
error ("An argument type that has a default promotion");
error ("can't match an empty parameter name list declaration.");
error ("An argument type that has a default promotion can't match an empty parameter name list declaration.");
break;
}
}
@ -1704,7 +1756,21 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
errmsg = redeclaration_error_message (newdecl, olddecl);
if (errmsg)
{
error_with_decl (newdecl, errmsg);
switch (errmsg)
{
case 1:
error_with_decl (newdecl, "redefinition of `%s'");
break;
case 2:
error_with_decl (newdecl, "redeclaration of `%s'");
break;
case 3:
error_with_decl (newdecl, "conflicting declarations of `%s'");
break;
default:
abort ();
}
error_with_decl (olddecl,
((DECL_INITIAL (olddecl)
&& current_binding_level == global_binding_level)
@ -1736,14 +1802,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
type = TYPE_ARG_TYPES (newtype),
nargs = 1;
(TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node);
;
parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
{
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
warning_with_decl (newdecl, "prototype for `%s' follows");
warning_with_decl (olddecl, "non-prototype definition here");
break;
}
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
errmsg = "prototype for `%s' follows and number of arguments";
error_with_decl (newdecl, "prototype for `%s' follows and number of arguments doesn't match");
error_with_decl (olddecl, "non-prototype definition here");
errmsg = 1;
break;
}
/* Type for passing arg must be consistent
@ -1755,21 +1829,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node)))
{
errmsg = "prototype for `%s' follows and argument %d";
error_with_decl (newdecl,
"prototype for `%s' follows and argument %d doesn't match",
nargs);
error_with_decl (olddecl, "non-prototype definition here");
errmsg = 1;
break;
}
}
if (errmsg)
{
error_with_decl (newdecl, errmsg, nargs);
error_with_decl (olddecl,
"doesn't match non-prototype definition here");
}
else
{
warning_with_decl (newdecl, "prototype for `%s' follows");
warning_with_decl (olddecl, "non-prototype definition here");
}
}
/* Warn about mismatches in various flags. */
else
@ -1794,6 +1861,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
&& !TREE_PUBLIC (newdecl))
warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
/* If warn_traditional, warn when a non-static function
declaration follows a static one. */
if (warn_traditional
&& TREE_CODE (olddecl) == FUNCTION_DECL
&& !TREE_PUBLIC (olddecl)
&& TREE_PUBLIC (newdecl))
warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
/* Warn when const declaration follows a non-const
declaration, but not for functions. */
if (TREE_CODE (olddecl) != FUNCTION_DECL
@ -1931,6 +2006,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
{
DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
DECL_NO_CHECK_MEMORY_USAGE (newdecl)
|= DECL_NO_CHECK_MEMORY_USAGE (olddecl);
}
pop_obstacks ();
@ -2017,7 +2097,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
if (DECL_INLINE (newdecl))
DECL_ABSTRACT_ORIGIN (newdecl) = olddecl;
DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ORIGIN (olddecl);
}
}
if (different_binding_level)
@ -2381,7 +2461,7 @@ pushdecl (x)
DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
DECL_RESULT (x) = DECL_RESULT (oldglobal);
TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
DECL_ABSTRACT_ORIGIN (x) = oldglobal;
DECL_ABSTRACT_ORIGIN (x) = DECL_ORIGIN (oldglobal);
}
/* Inner extern decl is built-in if global one is. */
if (DECL_BUILT_IN (oldglobal))
@ -2454,7 +2534,7 @@ pushdecl (x)
/* No shadow warnings for vars made for inlining. */
&& ! DECL_FROM_INLINE (x))
{
char *warnstring = 0;
char *id = IDENTIFIER_POINTER (name);
if (TREE_CODE (x) == PARM_DECL
&& current_binding_level->level_chain->parm_flag)
@ -2465,15 +2545,12 @@ pushdecl (x)
but there is no way to tell it's not a definition. */
;
else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL)
warnstring = "declaration of `%s' shadows a parameter";
warning ("declaration of `%s' shadows a parameter", id);
else if (oldlocal != 0)
warnstring = "declaration of `%s' shadows previous local";
warning ("declaration of `%s' shadows previous local", id);
else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
&& IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
warnstring = "declaration of `%s' shadows global declaration";
if (warnstring)
warning (warnstring, IDENTIFIER_POINTER (name));
warning ("declaration of `%s' shadows global declaration", id);
}
/* If storing a local value, there may already be one (inherited).
@ -2584,10 +2661,10 @@ implicitly_declare (functionid)
/* Return zero if the declaration NEWDECL is valid
when the declaration OLDDECL (assumed to be for the same name)
has already been seen.
Otherwise return an error message format string with a %s
where the identifier should go. */
Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration,
and 3 if it is a conflicting declaration. */
static char *
static int
redeclaration_error_message (newdecl, olddecl)
tree newdecl, olddecl;
{
@ -2606,7 +2683,7 @@ redeclaration_error_message (newdecl, olddecl)
return 0;
if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
return 0;
return "redefinition of `%s'";
return 1;
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@ -2619,7 +2696,7 @@ redeclaration_error_message (newdecl, olddecl)
time in another way is ok. */
&& !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
&& !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
return "redefinition of `%s'";
return 1;
return 0;
}
else if (current_binding_level == global_binding_level)
@ -2630,11 +2707,11 @@ redeclaration_error_message (newdecl, olddecl)
return 0;
/* Reject two definitions. */
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
return "redefinition of `%s'";
return 1;
/* Now we have two tentative defs, or one tentative and one real def. */
/* Insist that the linkage match. */
if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
return "conflicting declarations of `%s'";
return 3;
return 0;
}
else if (current_binding_level->parm_flag
@ -2648,7 +2725,7 @@ redeclaration_error_message (newdecl, olddecl)
be an extern reference to olddecl. */
if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
&& DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
return "redeclaration of `%s'";
return 2;
return 0;
}
}
@ -3038,8 +3115,10 @@ init_decl_processing ()
intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node));
#endif
unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node));
@ -3053,8 +3132,10 @@ init_decl_processing ()
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node));
#endif
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
@ -3288,8 +3369,8 @@ init_decl_processing ()
builtin_function ("__builtin_unwind_init",
build_function_type (void_type_node, endlink),
BUILT_IN_UNWIND_INIT, NULL_PTR);
builtin_function ("__builtin_fp", ptr_ftype_void, BUILT_IN_FP, NULL_PTR);
builtin_function ("__builtin_sp", ptr_ftype_void, BUILT_IN_SP, NULL_PTR);
builtin_function ("__builtin_dwarf_cfa", ptr_ftype_void,
BUILT_IN_DWARF_CFA, NULL_PTR);
builtin_function ("__builtin_dwarf_fp_regnum",
build_function_type (unsigned_type_node, endlink),
BUILT_IN_DWARF_FP_REGNUM, NULL_PTR);
@ -3299,24 +3380,16 @@ init_decl_processing ()
BUILT_IN_FROB_RETURN_ADDR, NULL_PTR);
builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
BUILT_IN_EXTRACT_RETURN_ADDR, NULL_PTR);
builtin_function ("__builtin_set_return_addr_reg",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
ptr_type_node,
endlink)),
BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR);
builtin_function ("__builtin_eh_stub_old", ptr_ftype_void,
BUILT_IN_EH_STUB_OLD, NULL_PTR);
builtin_function ("__builtin_eh_stub", ptr_ftype_void,
BUILT_IN_EH_STUB, NULL_PTR);
builtin_function
("__builtin_set_eh_regs",
("__builtin_eh_return",
build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE,
type_for_mode (ptr_mode, 0),
endlink))),
BUILT_IN_SET_EH_REGS, NULL_PTR);
tree_cons (NULL_TREE,
ptr_type_node,
endlink)))),
BUILT_IN_EH_RETURN, NULL_PTR);
builtin_function ("__builtin_alloca",
build_function_type (ptr_type_node,
@ -3530,7 +3603,7 @@ init_decl_processing ()
incomplete_decl_finalize_hook = finish_incomplete_decl;
lang_get_alias_set = &c_get_alias_set;
lang_get_alias_set = c_get_alias_set;
}
/* Return a definition for a builtin function named NAME and whose data type
@ -3543,10 +3616,10 @@ init_decl_processing ()
tree
builtin_function (name, type, function_code, library_name)
char *name;
const char *name;
tree type;
enum built_in_function function_code;
char *library_name;
const char *library_name;
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@ -3718,7 +3791,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
/* The corresponding pop_obstacks is in finish_decl. */
push_obstacks_nochange ();
if (warn_main && TREE_CODE (decl) != FUNCTION_DECL
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "main"))
warning_with_decl (decl, "`%s' is usually a function");
@ -4309,13 +4382,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
tree type = NULL_TREE;
int longlong = 0;
int constp;
int restrictp;
int volatilep;
int type_quals = TYPE_UNQUALIFIED;
int inlinep;
int explicit_int = 0;
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
char *name;
const char *name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
@ -4471,13 +4546,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
&& ! (specbits & (1 << (int) RID_TYPEDEF) && initialized)
&& ! (in_system_header && ! allocation_temporary_p ()))
{
/* C9x will probably require a diagnostic here.
For now, issue a warning if -Wreturn-type and this is a function,
or if -Wimplicit; prefer the former warning since it is more
explicit. */
/* Issue a warning if this is an ISO C 9x program or if -Wreturn-type
and this is a function, or if -Wimplicit; prefer the former
warning since it is more explicit. */
if ((warn_implicit_int || warn_return_type) && funcdef_flag)
warn_about_return_type = 1;
else if (warn_implicit_int)
else if (warn_implicit_int || flag_isoc9x)
warning ("type defaults to `int' in declaration of `%s'", name);
}
@ -4619,19 +4693,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = build_complex_type (type);
}
/* Set CONSTP if this declaration is `const', whether by
explicit specification or via a typedef.
Likewise for VOLATILEP. */
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
like `const int i' where the `const' is explicit. Another is
something like `typedef const int CI; CI i' where the type of the
declaration contains the `const'. */
constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
inlinep = !! (specbits & (1 << (int) RID_INLINE));
if (constp > 1)
pedwarn ("duplicate `const'");
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type)))
if (! flag_gen_aux_info && (TYPE_QUALS (type)))
type = TYPE_MAIN_VARIANT (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
/* Warn if two storage classes are given. Default to `auto'. */
@ -4865,13 +4946,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
is set correctly. */
type = build_array_type (type, itype);
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
#if 0 /* don't clear these; leave them set so that the array type
or the variable is itself const or volatile. */
constp = 0;
volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
#endif
if (size_varies)
@ -4936,12 +5016,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
flag_traditional
? NULL_TREE : arg_types);
#endif
/* ANSI seems to say that `const int foo ();'
does not make the function foo const. */
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
constp = 0;
volatilep = 0;
/* Type qualifiers before the return type of the function
qualify the return type, not the function type. */
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type_quals = TYPE_UNQUALIFIED;
type = build_function_type (type, arg_types);
declarator = TREE_OPERAND (declarator, 0);
@ -4965,12 +5044,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
for the pointer. */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& (constp || volatilep))
pedwarn ("ANSI C forbids const or volatile function types");
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
constp = 0;
volatilep = 0;
&& type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
type = build_pointer_type (type);
@ -4982,13 +5060,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
register tree typemodlist;
int erred = 0;
constp = 0;
volatilep = 0;
restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
tree qualifier = TREE_VALUE (typemodlist);
if (qualifier == ridpointers[(int) RID_CONST])
constp++;
else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
else if (qualifier == ridpointers[(int) RID_VOLATILE])
volatilep++;
else if (qualifier == ridpointers[(int) RID_RESTRICT])
restrictp++;
else if (!erred)
{
erred = 1;
@ -4999,6 +5085,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
pedwarn ("duplicate `const'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
}
declarator = TREE_OPERAND (declarator, 0);
@ -5025,10 +5117,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
/* Note that the grammar rejects storage classes
in typenames, fields or parameters */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& (constp || volatilep))
pedwarn ("ANSI C forbids const or volatile function types");
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
&& type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator, type);
if ((specbits & (1 << (int) RID_SIGNED))
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
@ -5060,10 +5152,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
/* Note that the grammar rejects storage classes
in typenames, fields or parameters */
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& (constp || volatilep))
&& type_quals)
pedwarn ("ANSI C forbids const or volatile function types");
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
pop_obstacks ();
return type;
}
@ -5103,20 +5195,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
/* Transfer const-ness of array into that of type pointed to. */
type = TREE_TYPE (type);
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
volatilep = constp = 0;
type_quals = TYPE_UNQUALIFIED;
size_varies = 0;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (pedantic && (constp || volatilep))
pedwarn ("ANSI C forbids const or volatile function types");
if (constp || volatilep)
type = c_build_type_variant (type, constp, volatilep);
if (pedantic && type_quals)
pedwarn ("ANSI C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
volatilep = constp = 0;
type_quals = TYPE_UNQUALIFIED;
}
decl = build_decl (PARM_DECL, declarator, type);
@ -5164,13 +5256,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = error_mark_node;
}
/* Move type qualifiers down to element of an array. */
if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
type = build_array_type (c_build_type_variant (TREE_TYPE (type),
constp, volatilep),
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals),
TYPE_DOMAIN (type));
#if 0 /* Leave the field const or volatile as well. */
constp = volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
#endif
}
decl = build_decl (FIELD_DECL, declarator, type);
@ -5209,18 +5301,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
decl = build_decl (FUNCTION_DECL, declarator, type);
decl = build_decl_attribute_variant (decl, decl_machine_attr);
if (pedantic && (constp || volatilep)
&& ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids const or volatile functions");
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids qualified function types");
if (pedantic
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl)))
|| TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl))))
&& TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ANSI C forbids const or volatile void function return type");
pedwarn ("ANSI C forbids qualified void function return type");
if (volatilep
/* GNU C interprets a `volatile void' return type to indicate
that the function does not return. */
if ((type_quals & TYPE_QUAL_VOLATILE)
&& TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
warning ("`noreturn' function returns non-void value");
@ -5250,13 +5342,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN));
/* Move type qualifiers down to element of an array. */
if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep))
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
{
type = build_array_type (c_build_type_variant (TREE_TYPE (type),
constp, volatilep),
type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
type_quals),
TYPE_DOMAIN (type));
#if 0 /* Leave the variable const or volatile as well. */
constp = volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
#endif
}
@ -5303,14 +5395,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
DECL_REGISTER (decl) = 1;
/* Record constancy and volatility. */
c_apply_type_quals_to_decl (type_quals, decl);
if (constp)
TREE_READONLY (decl) = 1;
if (volatilep)
{
TREE_SIDE_EFFECTS (decl) = 1;
TREE_THIS_VOLATILE (decl) = 1;
}
/* If a type has volatile components, it should be stored in memory.
Otherwise, the fact that those components are volatile
will be ignored, and would even crash the compiler. */
@ -5570,8 +5656,7 @@ parmlist_tags_warning ()
if (! already)
{
warning ("its scope is only this definition or declaration,");
warning ("which is probably not what you want.");
warning ("its scope is only this definition or declaration, which is probably not what you want.");
already = 1;
}
}
@ -5685,8 +5770,8 @@ start_struct (code, name)
tree
grokfield (filename, line, declarator, declspecs, width)
char *filename;
int line;
const char *filename ATTRIBUTE_UNUSED;
int line ATTRIBUTE_UNUSED;
tree declarator, declspecs, width;
{
tree value;
@ -5768,9 +5853,10 @@ finish_struct (t, fieldlist, attributes)
break;
if (x == 0)
pedwarn ("%s has no %smembers",
(TREE_CODE (t) == UNION_TYPE ? "union" : "structure"),
(fieldlist ? "named " : ""));
pedwarn ((fieldlist
? "%s has no named members"
: "%s has no members"),
TREE_CODE (t) == UNION_TYPE ? "union" : "struct");
}
/* Install struct as DECL_CONTEXT of each field decl.
@ -6428,6 +6514,10 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
except for defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL (decl1) = current_extern_inline;
#ifdef SET_DEFAULT_DECL_ATTRIBUTES
SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes);
#endif
/* This function exists in static storage.
(This does not mean `static' in the C sense!) */
TREE_STATIC (decl1) = 1;
@ -6437,7 +6527,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested)
TREE_PUBLIC (decl1) = 0;
/* Warn for unlikely, improbable, or stupid declarations of `main'. */
if (warn_main
if (warn_main > 0
&& strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))) == 0)
{
tree args;
@ -7154,12 +7244,8 @@ finish_function (nested)
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
!= integer_type_node)
{
/* You would expect the sense of this test to be the other way
around, but if warn_main is set, we will already have warned,
so this would be a duplicate. This is the warning you get
in some environments even if you *don't* ask for it, because
these are environments where it may be more of a problem than
usual. */
/* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
If warn_main is -1 (-Wno-main) we don't want to be warned. */
if (! warn_main)
pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
}
@ -7183,6 +7269,12 @@ finish_function (nested)
current_function_returns_null |= can_reach_end;
if (warn_missing_noreturn
&& !TREE_THIS_VOLATILE (fndecl)
&& !current_function_returns_null
&& !current_function_returns_value)
warning ("function might be possible candidate for attribute `noreturn'");
if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null)
warning ("`noreturn' function does return");
else if (warn_return_type && can_reach_end

View File

@ -1,5 +1,5 @@
/* Build expressions with type checking for C compiler.
Copyright (C) 1987, 88, 89, 92, 93, 96, 1997 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 89, 92, 93, 96, 1997, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -539,10 +539,10 @@ prdecl (d)
fprintf (stderr, dname);
}
else
fprintf (stderr, "<<Not a Decl!!!>>");
fprintf (stderr, "<<?>>");
}
else
fprintf (stderr, "<<NULL!!>>");
fprintf (stderr, "<<0>>");
}
/* Print Iterator List -- names only */

View File

@ -28,6 +28,13 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "output.h"
#if USE_CPPLIB
#include "cpplib.h"
extern char *yy_cur;
extern cpp_reader parse_in;
extern cpp_options parse_options;
#endif
/* Each of the functions defined here
is an alternative to a function in objc-actions.c. */
@ -42,17 +49,25 @@ lang_decode_option (argc, argv)
void
lang_init_options ()
{
#if USE_CPPLIB
cpp_reader_init (&parse_in);
parse_in.opts = &parse_options;
cpp_options_init (&parse_options);
#endif
}
void
lang_init ()
{
#if !USE_CPPLIB
/* the beginning of the file is a new line; check for # */
/* With luck, we discover the real source file's name from that
and put it in input_filename. */
#if !USE_CPPLIB
ungetc (check_newline (), finput);
#endif
#else
check_newline ();
yy_cur--;
#endif
}
void
@ -134,7 +149,7 @@ recognize_objc_keyword ()
tree
build_objc_string (len, str)
int len ATTRIBUTE_UNUSED;
char *str ATTRIBUTE_UNUSED;
const char *str ATTRIBUTE_UNUSED;
{
abort ();
return NULL_TREE;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Define constants for communication with c-parse.y.
Copyright (C) 1987, 1992 Free Software Foundation, Inc.
Copyright (C) 1987, 1992, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -40,6 +40,7 @@ enum rid
RID_TYPEDEF,
RID_SIGNED,
RID_CONST,
RID_RESTRICT,
RID_VOLATILE,
RID_INLINE,
RID_NOALIAS,
@ -50,6 +51,7 @@ enum rid
RID_OUT,
RID_INOUT,
RID_BYCOPY,
RID_BYREF,
RID_ONEWAY,
RID_ID,
@ -79,7 +81,7 @@ extern void position_after_white_space PROTO((void));
extern int check_newline PROTO((void));
extern int yylex PROTO((void));
extern void yyerror PROTO((char *));
extern void yyerror PROTO((const char *));
extern void forget_protocol_qualifiers PROTO((void));
extern void remember_protocol_qualifiers PROTO((void));

View File

@ -1,7 +1,7 @@
%{
/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */
%}
struct resword { char *name; short token; enum rid rid; };
struct resword { const char *name; short token; enum rid rid; };
%%
@class, CLASS, NORID
@compatibility_alias, ALIAS, NORID
@ -35,6 +35,8 @@ __iterator__, SCSPEC, RID_ITERATOR
__label__, LABEL, NORID
__real, REALPART, NORID
__real__, REALPART, NORID
__restrict, TYPE_QUAL, RID_RESTRICT
__restrict__, TYPE_QUAL, RID_RESTRICT
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED
__typeof, TYPEOF, NORID
@ -45,6 +47,7 @@ asm, ASM_KEYWORD, NORID
auto, SCSPEC, RID_AUTO
break, BREAK, NORID
bycopy, TYPE_QUAL, RID_BYCOPY
byref, TYPE_QUAL, RID_BYREF
case, CASE, NORID
char, TYPESPEC, RID_CHAR
const, TYPE_QUAL, RID_CONST
@ -68,6 +71,7 @@ long, TYPESPEC, RID_LONG
oneway, TYPE_QUAL, RID_ONEWAY
out, TYPE_QUAL, RID_OUT
register, SCSPEC, RID_REGISTER
restrict, TYPE_QUAL, RID_RESTRICT
return, RETURN, NORID
short, TYPESPEC, RID_SHORT
signed, TYPESPEC, RID_SIGNED

View File

@ -1,5 +1,5 @@
/* YACC parser for C syntax and for Objective C. -*-c-*-
Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -31,7 +31,7 @@ ifobjc
%expect 66
end ifobjc
ifc
%expect 46
%expect 51
/* These are the 23 conflicts you should get in parse.output;
the state numbers may vary if minor changes in the grammar are made.
@ -116,7 +116,7 @@ end ifc
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPESPEC
/* Reserved words that qualify type: "const" or "volatile".
/* Reserved words that qualify type: "const", "volatile", or "restrict".
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token TYPE_QUAL
@ -525,7 +525,7 @@ cast_expr:
tree type = $2;
finish_init ();
if (pedantic)
if (pedantic && ! flag_isoc9x)
pedwarn ("ANSI C forbids constructor expressions");
if (TYPE_NAME (type) != 0)
{
@ -604,12 +604,22 @@ expr_no_commas:
{ skip_evaluation -= $1 == boolean_true_node;
$$ = build_conditional_expr ($1, $<ttype>2, $5); }
| expr_no_commas '=' expr_no_commas
{ $$ = build_modify_expr ($1, NOP_EXPR, $3);
C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
{ char class;
$$ = build_modify_expr ($1, NOP_EXPR, $3);
class = TREE_CODE_CLASS (TREE_CODE ($$));
if (class == 'e' || class == '1'
|| class == '2' || class == '<')
C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR);
}
| expr_no_commas ASSIGN expr_no_commas
{ $$ = build_modify_expr ($1, $2, $3);
{ char class;
$$ = build_modify_expr ($1, $2, $3);
/* This inhibits warnings in truthvalue_conversion. */
C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
class = TREE_CODE_CLASS (TREE_CODE ($$));
if (class == 'e' || class == '1'
|| class == '2' || class == '<')
C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK);
}
;
primary:
@ -1275,33 +1285,41 @@ initlist1:
/* `initelt' is a single element of an initializer.
It may use braces. */
initelt:
expr_no_commas
{ process_init_element ($1); }
| '{'
designator_list '=' initval
| designator initval
| identifier ':'
{ set_init_label ($1); }
initval
| initval
;
initval:
'{'
{ push_init_level (0); }
initlist_maybe_comma '}'
{ process_init_element (pop_init_level (0)); }
| expr_no_commas
{ process_init_element ($1); }
| error
;
designator_list:
designator
| designator_list designator
;
designator:
'.' identifier
{ set_init_label ($2); }
/* These are for labeled elements. The syntax for an array element
initializer conflicts with the syntax for an Objective-C message,
so don't include these productions in the Objective-C grammar. */
ifc
| '[' expr_no_commas ELLIPSIS expr_no_commas ']' '='
| '[' expr_no_commas ELLIPSIS expr_no_commas ']'
{ set_init_index ($2, $4); }
initelt
| '[' expr_no_commas ']' '='
{ set_init_index ($2, NULL_TREE); }
initelt
| '[' expr_no_commas ']'
{ set_init_index ($2, NULL_TREE); }
initelt
end ifc
| identifier ':'
{ set_init_label ($1); }
initelt
| '.' identifier '='
{ set_init_label ($2); }
initelt
;
nested_function:
@ -1398,6 +1416,13 @@ parm_declarator:
/* | parm_declarator '(' error ')' %prec '.'
{ $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
poplevel (0, 0, 0); } */
ifc
| parm_declarator '[' '*' ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
if (! flag_isoc9x)
error ("`[*]' in parameter declaration only allowed in ISO C 9x");
}
end ifc
| parm_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| parm_declarator '[' ']' %prec '.'
@ -1427,6 +1452,13 @@ notype_declarator:
{ $$ = $2; }
| '*' type_quals notype_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
ifc
| notype_declarator '[' '*' ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
if (! flag_isoc9x)
error ("`[*]' in parameter declaration only allowed in ISO C 9x");
}
end ifc
| notype_declarator '[' expr ']' %prec '.'
{ $$ = build_nt (ARRAY_REF, $1, $3); }
| notype_declarator '[' ']' %prec '.'
@ -1509,7 +1541,8 @@ maybecomma:
maybecomma_warn:
/* empty */
| ','
{ if (pedantic) pedwarn ("comma at end of enumerator list"); }
{ if (pedantic && ! flag_isoc9x)
pedwarn ("comma at end of enumerator list"); }
;
component_decl_list:
@ -1676,6 +1709,8 @@ absdcl1: /* a nonempty absolute declarator */
{ $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
/* ??? It appears we have to support attributes here, however
using prefix_attributes is wrong. */
| attributes setattrs absdcl1
{ $$ = $3; }
;
/* at least one statement, the first of which parses without error. */
@ -2191,12 +2226,15 @@ label: CASE expr_no_commas ':'
error_with_decl (duplicate, "this is the first default label");
}
position_after_white_space (); }
| identifier ':'
| identifier ':' maybe_attribute
{ tree label = define_label (input_filename, lineno, $1);
stmt_count++;
emit_nop ();
if (label)
expand_label (label);
{
expand_label (label);
decl_attributes (label, $3, NULL_TREE);
}
position_after_white_space (); }
;

View File

@ -1,5 +1,5 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
Copyright (C) 1992, 1997 Free Software Foundation, Inc.
Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -29,147 +29,464 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "toplev.h"
#ifdef HANDLE_SYSV_PRAGMA
#ifdef HANDLE_GENERIC_PRAGMAS
#ifdef HANDLE_PRAGMA_PACK
/* When structure field packing is in effect, this variable is the
number of bits to use as the maximum alignment. When packing is not
in effect, this is zero. */
extern int maximum_field_alignment;
#endif
/* File used for outputting assembler code. */
extern FILE *asm_out_file;
/* Handle one token of a pragma directive. TOKEN is the
current token, and STRING is its printable form. */
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
typedef struct align_stack
{
int alignment;
unsigned int num_pushes;
tree id;
struct align_stack * prev;
} align_stack;
static struct align_stack * alignment_stack = NULL;
static int push_alignment PROTO((int, tree));
static int pop_alignment PROTO((tree));
/* Push an alignment value onto the stack. */
static int
push_alignment (alignment, id)
int alignment;
tree id;
{
switch (alignment)
{
case 0:
case 1:
case 2:
case 4:
case 8:
case 16:
break;
default:
warning ("\
Alignment must be a small power of two, not %d, in #pragma pack",
alignment);
return 0;
}
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
|| id != NULL_TREE)
{
align_stack * entry;
entry = (align_stack *) xmalloc (sizeof (* entry));
if (entry == NULL)
{
warning ("Out of memory pushing #pragma pack");
return 0;
}
entry->alignment = alignment;
entry->num_pushes = 1;
entry->id = id;
entry->prev = alignment_stack;
alignment_stack = entry;
maximum_field_alignment = alignment * 8;
}
else
alignment_stack->num_pushes ++;
return 1;
}
/* Undo a push of an alignment onto the stack. */
static int
pop_alignment (id)
tree id;
{
align_stack * entry;
if (alignment_stack == NULL)
{
warning ("\
#pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
);
return 0;
}
/* If we got an identifier, strip away everything above the target
entry so that the next step will restore the state just below it. */
if (id)
{
for (entry = alignment_stack; entry; entry = entry->prev)
if (entry->id == id)
{
entry->num_pushes = 1;
alignment_stack = entry;
break;
}
if (entry == NULL)
warning ("\
#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
, IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
}
if (-- alignment_stack->num_pushes == 0)
{
entry = alignment_stack->prev;
if (entry == NULL)
maximum_field_alignment = 0;
else
maximum_field_alignment = entry->alignment * 8;
free (alignment_stack);
alignment_stack = entry;
}
return 1;
}
/* Generate 'packed' and 'aligned' attributes for decls whilst a
#pragma pack(push... is in effect. */
void
insert_pack_attributes (node, attributes, prefix)
tree node;
tree * attributes;
tree * prefix;
{
tree a;
int field_alignment;
/* If we are not packing, then there is nothing to do. */
if (maximum_field_alignment == 0
|| alignment_stack == NULL)
return;
/* We are only interested in fields. */
if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd'
|| TREE_CODE (node) != FIELD_DECL)
return;
field_alignment = TYPE_ALIGN (TREE_TYPE (node));
if (field_alignment <= 0 || field_alignment > maximum_field_alignment)
field_alignment = maximum_field_alignment;
/* Add a 'packed' attribute. */
* attributes = tree_cons (get_identifier ("packed"), NULL, * attributes);
/* If the alignment is > 8 then add an alignment attribute as well. */
if (field_alignment > 8)
{
/* If the aligned attribute is already present then do not override it. */
for (a = * attributes; a; a = TREE_CHAIN (a))
{
tree name = TREE_PURPOSE (a);
if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
break;
}
if (a == NULL)
for (a = * prefix; a; a = TREE_CHAIN (a))
{
tree name = TREE_PURPOSE (a);
if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0)
break;
}
if (a == NULL)
{
* attributes = tree_cons
(get_identifier ("aligned"),
tree_cons (NULL,
build_int_2 (field_alignment / 8, 0),
NULL),
* attributes);
}
}
return;
}
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
/* Handle one token of a pragma directive. TOKEN is the current token, and
STRING is its printable form. Some front ends do not support generating
tokens, and will only pass in a STRING. Also some front ends will reuse
the buffer containing STRING, so it must be copied to a local buffer if
it needs to be preserved.
If STRING is non-NULL, then the return value will be ignored, and there
will be futher calls to handle_pragma_token() in order to handle the rest of
the line containing the #pragma directive. If STRING is NULL, the entire
line has now been presented to handle_pragma_token() and the return value
should be zero if the pragma flawed in some way, or if the pragma was not
recognised, and non-zero if it was successfully handled. */
int
handle_pragma_token (string, token)
char *string;
const char * string;
tree token;
{
static enum pragma_state state = ps_start, type;
static char *name;
static char *value;
static enum pragma_state state = ps_start;
static enum pragma_state type;
static char * name;
static char * value;
static int align;
static tree id;
if (string == 0)
/* If we have reached the end of the #pragma directive then
determine what value we should return. */
if (string == NULL)
{
if (type == ps_pack)
int ret_val = 0;
switch (type)
{
default:
abort ();
break;
case ps_done:
/* The pragma was not recognised. */
break;
#ifdef HANDLE_PRAGMA_PACK
case ps_pack:
if (state == ps_right)
maximum_field_alignment = align * 8;
{
maximum_field_alignment = align * 8;
ret_val = 1;
}
else
warning ("malformed `#pragma pack'");
}
else if (type == ps_weak)
{
break;
#endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_push:
if (state == ps_right)
ret_val = push_alignment (align, id);
else
warning ("malformed '#pragma pack(push[,id],<n>)'");
break;
case ps_pop:
if (state == ps_right)
ret_val = pop_alignment (id);
else
warning ("malformed '#pragma pack(pop[,id])'");
break;
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
#ifdef HANDLE_PRAGMA_WEAK
case ps_weak:
if (HANDLE_PRAGMA_WEAK)
handle_pragma_weak (state, name, value);
{
if (state == ps_name)
ret_val = add_weak (name, NULL);
else if (state == ps_value)
ret_val = add_weak (name, value);
else
warning ("malformed `#pragma weak'");
}
else
ret_val = 1; /* Ignore the pragma. */
break;
#endif /* HANDLE_PRAGMA_WEAK */
}
type = state = ps_start;
return;
id = NULL_TREE;
return ret_val;
}
/* If we have been given a token, but it is not an identifier,
or a small constant, then something has gone wrong. */
if (token)
{
switch (TREE_CODE (token))
{
case IDENTIFIER_NODE:
break;
case INTEGER_CST:
if (TREE_INT_CST_HIGH (token) != 0)
return 0;
break;
default:
return 0;
}
}
switch (state)
{
case ps_start:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
type = state = ps_done;
#ifdef HANDLE_PRAGMA_PACK
if (strcmp (string, "pack") == 0)
type = state = ps_pack;
#endif
#ifdef HANDLE_PRAGMA_WEAK
if (strcmp (string, "weak") == 0)
type = state = ps_weak;
#endif
break;
#ifdef HANDLE_PRAGMA_WEAK
case ps_weak:
name = permalloc (strlen (string) + 1);
if (name == NULL)
{
if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
type = state = ps_pack;
else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
type = state = ps_weak;
else
{
type = state = ps_done;
/* Issue a warning message if we have been asked to do so.
Ignoring unknown pragmas in system header file unless
an explcit -Wunknown-pragmas has been given. */
if (warn_unknown_pragmas > 1
|| (warn_unknown_pragmas && ! in_system_header))
warning ("ignoring pragma: %s", string);
}
warning ("Out of memory parsing #pragma weak");
state = ps_bad;
}
else
type = state = ps_done;
break;
case ps_weak:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
{
name = IDENTIFIER_POINTER (token);
strcpy (name, string);
state = ps_name;
}
else
state = ps_bad;
break;
case ps_name:
state = (strcmp (string, "=") ? ps_bad : ps_equals);
break;
case ps_equals:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
value = permalloc (strlen (string) + 1);
if (value == NULL)
{
value = IDENTIFIER_POINTER (token);
state = ps_value;
warning ("Out of memory parsing #pragma weak");
state = ps_bad;
}
else
state = ps_bad;
{
strcpy (value, string);
state = ps_value;
}
break;
case ps_value:
state = ps_bad;
break;
#endif /* HANDLE_PRAGMA_WEAK */
#ifdef HANDLE_PRAGMA_PACK
case ps_pack:
if (strcmp (string, "(") == 0)
state = ps_left;
else
state = ps_bad;
state = (strcmp (string, "(") ? ps_bad : ps_left);
break;
case ps_left:
if (token && TREE_CODE (token) == INTEGER_CST
&& TREE_INT_CST_HIGH (token) == 0)
switch (TREE_INT_CST_LOW (token))
{
case 1:
case 2:
case 4:
align = TREE_INT_CST_LOW (token);
state = ps_align;
break;
default:
state = ps_bad;
}
else if (! token && strcmp (string, ")") == 0)
if (token == NULL_TREE)
{
align = 0;
state = ps_right;
/* #pragma pack () resets packing rules to their
defaults. */
if (strcmp (string, ")") == 0)
{
align = 0;
state = ps_right;
}
else
state = ps_bad;
}
else if (TREE_CODE (token) == INTEGER_CST)
goto handle_align;
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
else if (TREE_CODE (token) == IDENTIFIER_NODE)
{
if (strcmp (string, "push") == 0)
type = state = ps_push;
else if (strcmp (string, "pop") == 0)
type = state = ps_pop;
else
state = ps_bad;
}
#endif
else
state = ps_bad;
break;
handle_align:
align = TREE_INT_CST_LOW (token);
switch (align)
{
case 1:
case 2:
case 4:
case 8:
case 16:
state = ps_align;
break;
default:
state = ps_bad;
break;
}
break;
case ps_align:
if (strcmp (string, ")") == 0)
state = ps_right;
else
state = ps_bad;
state = (strcmp (string, ")") ? ps_bad : ps_right);
break;
case ps_right:
state = ps_bad;
break;
#endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
case ps_push:
state = (strcmp (string, ",") ? ps_bad : ps_pushcomma);
break;
case ps_pushid:
state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2);
break;
case ps_pushcomma:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
{
id = token;
state = ps_pushid;
break;
}
/* else fall through */
case ps_pushcomma2:
if (token && TREE_CODE (token) == INTEGER_CST)
goto handle_align;
else
state = ps_bad;
break;
case ps_pop:
if (strcmp (string, ",") == 0)
state = ps_popcomma;
else
state = (strcmp (string, ")") ? ps_bad : ps_right);
break;
case ps_popcomma:
if (token && TREE_CODE (token) == IDENTIFIER_NODE)
{
id = token;
state = ps_align;
}
else
state = ps_bad;
break;
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
case ps_bad:
case ps_done:
break;
@ -177,5 +494,7 @@ handle_pragma_token (string, token)
default:
abort ();
}
return 1;
}
#endif /* HANDLE_SYSV_PRAGMA */
#endif /* HANDLE_GENERIC_PRAGMAS */

View File

@ -1,5 +1,5 @@
/* Pragma related interfaces.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -18,29 +18,84 @@ 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. */
#ifndef _C_PRAGMA_H
#define _C_PRAGMA_H
#ifdef HANDLE_SYSV_PRAGMA
/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are
defined. */
#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF)
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
#endif
/* We always support #pragma pack for SYSV pragmas. */
#ifndef HANDLE_PRAGMA_PACK
#define HANDLE_PRAGMA_PACK 1
#endif
#endif /* HANDLE_SYSV_PRAGMA */
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
/* If we are supporting #pragma pack(push... then we automatically
support #pragma pack(<n>) */
#define HANDLE_PRAGMA_PACK 1
#define PRAGMA_INSERT_ATTRIBUTES(node, pattr, prefix_attr) \
insert_pack_attributes (node, pattr, prefix_attr)
extern void insert_pack_attributes PROTO((tree, tree *, tree *));
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
#ifdef HANDLE_PRAGMA_WEAK
/* This structure contains any weak symbol declarations waiting to be emitted. */
struct weak_syms
{
struct weak_syms * next;
char * name;
char * value;
};
/* Declared in varasm.c */
extern struct weak_syms * weak_decls;
extern int add_weak PROTO((char *, char *));
#endif /* HANDLE_PRAGMA_WEAK */
#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK
/* Define HANDLE_GENERIC_PRAGMAS if any kind of front-end pragma
parsing is to be done. The code in GCC's generic C source files
will only look for the definition of this constant. They will
ignore definitions of HANDLE_PRAGMA_PACK and so on. */
#define HANDLE_GENERIC_PRAGMAS 1
#endif
#ifdef HANDLE_GENERIC_PRAGMAS
enum pragma_state
{
ps_start,
ps_done,
ps_bad,
#ifdef HANDLE_PRAGMA_WEAK
ps_weak,
ps_name,
ps_equals,
ps_value,
#endif
#ifdef HANDLE_PRAGMA_PACK
ps_pack,
ps_left,
ps_align,
ps_right
ps_right,
#endif
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2,
ps_pop, ps_popcomma,
#endif
ps_bad
};
/* Output asm to handle ``#pragma weak'' */
extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *));
/* Handle a C style pragma */
extern void handle_pragma_token PROTO((char *, tree));
extern int handle_pragma_token PROTO((const char *, tree));
#endif /* HANDLE_GENERIC_PRAGMAS */
#endif /* _C_PRAGMA_H */

View File

@ -1,5 +1,5 @@
/* Definitions for C parsing and type checking.
Copyright (C) 1987, 1993, 1994, 1995, 1997 Free Software Foundation, Inc.
Copyright (C) 1987, 93, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -80,6 +80,22 @@ extern int pedantic;
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type)
/* C types are partitioned into three subsets: object, function, and
incomplete types. */
#define C_TYPE_OBJECT_P(type) \
(TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type))
#define C_TYPE_FUNCTION_P(type) \
(TREE_CODE (type) == FUNCTION_TYPE)
#define C_TYPE_INCOMPLETE_P(type) \
(TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0)
/* For convenience we define a single macro to identify the class of
object or incomplete types. */
#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \
(!C_TYPE_FUNCTION_P (type))
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type
{
@ -154,7 +170,7 @@ extern int maybe_objc_comptypes PROTO((tree, tree, int));
extern tree maybe_building_objc_message_expr PROTO((void));
extern tree maybe_objc_method_name PROTO((tree));
extern int recognize_objc_keyword PROTO((void));
extern tree build_objc_string PROTO((int, char *));
extern tree build_objc_string PROTO((int, const char *));
/* in c-aux-info.c */
extern void gen_aux_info_record PROTO((tree, int, int, int));
@ -165,6 +181,7 @@ extern void decl_attributes PROTO((tree, tree, tree));
extern void init_function_format_info PROTO((void));
extern void check_function_format PROTO((tree, tree, tree));
extern int c_get_alias_set PROTO((tree));
extern void c_apply_type_quals_to_decl PROTO((int, tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code));
@ -213,7 +230,9 @@ extern tree double_ftype_double;
extern tree double_ftype_double_double;
extern tree double_type_node;
extern tree float_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
extern tree intTI_type_node;
#endif
extern tree intDI_type_node;
extern tree intHI_type_node;
extern tree intQI_type_node;
@ -243,7 +262,9 @@ extern tree signed_wchar_type_node;
extern tree string_ftype_ptr_ptr;
extern tree string_type_node;
extern tree unsigned_char_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
extern tree unsigned_intTI_type_node;
#endif
extern tree unsigned_intDI_type_node;
extern tree unsigned_intHI_type_node;
extern tree unsigned_intQI_type_node;
@ -261,9 +282,13 @@ extern tree boolean_false_node;
extern tree build_enumerator PROTO((tree, tree));
/* Declare a predefined function. Return the declaration. */
extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *));
extern tree builtin_function PROTO((const char *, tree, enum built_in_function function_, const char *));
/* Add qualifiers to a type, in the fashion for C. */
extern tree c_build_type_variant PROTO((tree, int, int));
extern tree c_build_qualified_type PROTO((tree, int));
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
c_build_qualified_type (TYPE, \
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
extern int c_decode_option PROTO((int, char **));
extern void c_mark_varargs PROTO((void));
extern tree check_identifier PROTO((tree, tree));
@ -282,7 +307,7 @@ extern tree get_parm_info PROTO((int));
extern tree getdecls PROTO((void));
extern tree gettags PROTO((void));
extern int global_bindings_p PROTO((void));
extern tree grokfield PROTO((char *, int, tree, tree, tree));
extern tree grokfield PROTO((const char *, int, tree, tree, tree));
extern tree groktypename PROTO((tree));
extern tree groktypename_in_parm_context PROTO((tree));
extern tree implicitly_declare PROTO((tree));
@ -340,7 +365,7 @@ extern tree c_alignof PROTO((tree));
extern tree c_alignof_expr PROTO((tree));
extern tree default_conversion PROTO((tree));
extern tree build_component_ref PROTO((tree, tree));
extern tree build_indirect_ref PROTO((tree, char *));
extern tree build_indirect_ref PROTO((tree, const char *));
extern tree build_array_ref PROTO((tree, tree));
extern tree build_function_call PROTO((tree, tree));
extern tree parser_build_binary_op PROTO((enum tree_code,
@ -350,8 +375,8 @@ extern tree build_binary_op PROTO((enum tree_code,
extern tree build_unary_op PROTO((enum tree_code,
tree, int));
extern int lvalue_p PROTO((tree));
extern int lvalue_or_else PROTO((tree, char *));
extern void readonly_warning PROTO((tree, char *));
extern int lvalue_or_else PROTO((tree, const char *));
extern void readonly_warning PROTO((tree, const char *));
extern int mark_addressable PROTO((tree));
extern tree build_conditional_expr PROTO((tree, tree, tree));
extern tree build_compound_expr PROTO((tree));
@ -360,10 +385,8 @@ extern tree build_modify_expr PROTO((tree, enum tree_code,
tree));
extern tree initializer_constant_valid_p PROTO((tree, tree));
extern void store_init_value PROTO((tree, tree));
extern void error_init PROTO((char *, char *,
char *));
extern void pedwarn_init PROTO((char *, char *,
char *));
extern void error_init PROTO((const char *));
extern void pedwarn_init PROTO((const char *));
extern void start_init PROTO((tree, tree, int));
extern void finish_init PROTO((void));
extern void really_start_incremental_init PROTO((tree));
@ -418,10 +441,6 @@ extern int flag_no_asm;
extern int flag_hosted;
/* Nonzero means ignore `#ident' directives. */
extern int flag_no_ident;
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@ -430,7 +449,7 @@ extern int warn_implicit;
to get extra warnings from them. These warnings will be too numerous
to be useful, except in thoroughly ANSIfied programs. */
extern int warn_write_strings;
extern int flag_const_strings;
/* Nonzero means warn about sizeof (function) or addition/subtraction
of function pointers. */
@ -465,6 +484,10 @@ extern int warn_cast_qual;
extern int warn_bad_function_cast;
/* Warn about functions which might be candidates for attribute noreturn. */
extern int warn_missing_noreturn;
/* Warn about traditional constructs whose meanings changed in ANSI C. */
extern int warn_traditional;
@ -489,6 +512,10 @@ extern int warn_main;
extern int flag_traditional;
/* Nonzero means use the ISO C9x dialect of C. */
extern int flag_isoc9x;
/* Nonzero means to allow single precision math even if we're generally
being traditional. */
extern int flag_allow_single_precision;
@ -509,6 +536,10 @@ extern int warn_sign_compare;
extern int warn_multichar;
/* Warn about long long. */
extern int warn_long_long;
/* Nonzero means we are reading code that came from a system header file. */
extern int system_header_p;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 94-95, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1989, 1992, 94-95, 97, 98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -39,6 +39,8 @@ Boston, MA 02111-1307, USA. */
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
#endif
#define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
/* Modes for each hard register that we can save. The smallest mode is wide
enough to save the entire contents of the register. When saving the
register because it is live we first try to save in multi-register modes.
@ -64,27 +66,31 @@ static enum insn_code
static enum insn_code
reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
/* Set of hard regs currently live (during scan of all insns). */
static HARD_REG_SET hard_regs_live;
/* Set of hard regs currently residing in save area (during insn scan). */
static HARD_REG_SET hard_regs_saved;
/* Set of hard regs which need to be restored before referenced. */
static HARD_REG_SET hard_regs_need_restore;
/* Number of registers currently in hard_regs_saved. */
int n_regs_saved;
static int n_regs_saved;
static void set_reg_live PROTO((rtx, rtx));
static void clear_reg_live PROTO((rtx));
static void restore_referenced_regs PROTO((rtx, rtx, enum machine_mode));
static int insert_save_restore PROTO((rtx, int, int,
enum machine_mode, int));
/* Computed by mark_referenced_regs, all regs referenced in a given
insn. */
static HARD_REG_SET referenced_regs;
/* Computed in mark_set_regs, holds all registers set by the current
instruction. */
static HARD_REG_SET this_insn_sets;
static void mark_set_regs PROTO((rtx, rtx));
static void mark_referenced_regs PROTO((rtx));
static int insert_save PROTO((struct insn_chain *, int, int,
HARD_REG_SET *));
static int insert_restore PROTO((struct insn_chain *, int, int,
int));
static void insert_one_insn PROTO((struct insn_chain *, int,
enum insn_code, rtx));
/* Initialize for caller-save.
@ -113,9 +119,9 @@ init_caller_save ()
{
if (call_used_regs[i] && ! call_fixed_regs[i])
{
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
for (j = 1; j <= MOVE_MAX_WORDS; j++)
{
regno_save_mode[i][j] = choose_hard_reg_mode (i, j);
regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j);
if (regno_save_mode[i][j] == VOIDmode && j == 1)
{
call_fixed_regs[i] = 1;
@ -170,7 +176,7 @@ init_caller_save ()
start_sequence ();
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
for (j = 1; j <= MOVE_MAX_WORDS; j++)
if (regno_save_mode[i][j] != VOIDmode)
{
rtx mem = gen_rtx_MEM (regno_save_mode[i][j], address);
@ -186,13 +192,14 @@ init_caller_save ()
/* Now extract both insns and see if we can meet their
constraints. */
ok = (reg_save_code[i][j] != -1 && reg_restore_code[i][j] != -1);
ok = (reg_save_code[i][j] != (enum insn_code)-1
&& reg_restore_code[i][j] != (enum insn_code)-1);
if (ok)
{
insn_extract (saveinsn);
ok = constrain_operands (reg_save_code[i][j], 1);
insn_extract (restinsn);
ok &= constrain_operands (reg_restore_code[i][j], 1);
extract_insn (saveinsn);
ok = constrain_operands (1);
extract_insn (restinsn);
ok &= constrain_operands (1);
}
if (! ok)
@ -219,7 +226,7 @@ init_save_areas ()
int i, j;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
for (j = 1; j <= MOVE_MAX_WORDS; j++)
regno_save_mem[i][j] = 0;
}
@ -229,13 +236,6 @@ init_save_areas ()
overestimate slightly (especially if some of these registers are later
used as spill registers), but it should not be significant.
Then perform register elimination in the addresses of the save area
locations; return 1 if all eliminated addresses are strictly valid.
We assume that our caller has set up the elimination table to the
worst (largest) possible offsets.
Set *PCHANGED to 1 if we had to allocate some memory for the save area.
Future work:
In the fallback case we should iterate backwards across all possible
@ -248,14 +248,11 @@ init_save_areas ()
machine independent since they might be saving non-consecutive
registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
int
setup_save_areas (pchanged)
int *pchanged;
void
setup_save_areas ()
{
int i, j, k;
HARD_REG_SET hard_regs_used;
int ok = 1;
/* Allocate space in the save area for the largest multi-register
pseudos first, then work backwards to single register
@ -283,10 +280,9 @@ setup_save_areas (pchanged)
in a manner which allows multi-register saves/restores to be done. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--)
for (j = MOVE_MAX_WORDS; j > 0; j--)
{
int ok = 1;
int do_save;
int do_save = 1;
/* If no mode exists for this size, try another. Also break out
if we have already saved this hard register. */
@ -294,7 +290,6 @@ setup_save_areas (pchanged)
continue;
/* See if any register in this group has been saved. */
do_save = 1;
for (k = 0; k < j; k++)
if (regno_save_mem[i + k][1])
{
@ -305,207 +300,171 @@ setup_save_areas (pchanged)
continue;
for (k = 0; k < j; k++)
if (! TEST_HARD_REG_BIT (hard_regs_used, i + k))
{
int regno = i + k;
ok &= (TEST_HARD_REG_BIT (hard_regs_used, regno) != 0);
do_save = 0;
break;
}
if (! do_save)
continue;
/* We have found an acceptable mode to store in. */
if (ok)
regno_save_mem[i][j]
= assign_stack_local (regno_save_mode[i][j],
GET_MODE_SIZE (regno_save_mode[i][j]), 0);
/* Setup single word save area just in case... */
for (k = 0; k < j; k++)
{
/* This should not depend on WORDS_BIG_ENDIAN.
The order of words in regs is the same as in memory. */
rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1],
XEXP (regno_save_mem[i][j], 0));
regno_save_mem[i][j]
= assign_stack_local (regno_save_mode[i][j],
GET_MODE_SIZE (regno_save_mode[i][j]), 0);
/* Setup single word save area just in case... */
for (k = 0; k < j; k++)
{
/* This should not depend on WORDS_BIG_ENDIAN.
The order of words in regs is the same as in memory. */
rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1],
XEXP (regno_save_mem[i][j], 0));
regno_save_mem[i+k][1]
= adj_offsettable_operand (temp, k * UNITS_PER_WORD);
}
*pchanged = 1;
regno_save_mem[i+k][1]
= adj_offsettable_operand (temp, k * UNITS_PER_WORD);
}
}
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
if (regno_save_mem[i][j] != 0)
ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]),
XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX), 0));
return ok;
}
/* Find the places where hard regs are live across calls and save them.
INSN_MODE is the mode to assign to any insns that we add. This is used
by reload to determine whether or not reloads or register eliminations
need be done on these insns. */
/* Find the places where hard regs are live across calls and save them. */
void
save_call_clobbered_regs (insn_mode)
enum machine_mode insn_mode;
save_call_clobbered_regs ()
{
rtx insn;
int b;
struct insn_chain *chain, *next;
for (b = 0; b < n_basic_blocks; b++)
CLEAR_HARD_REG_SET (hard_regs_saved);
n_regs_saved = 0;
for (chain = reload_insn_chain; chain != 0; chain = next)
{
regset regs_live = basic_block_live_at_start[b];
rtx prev_block_last = PREV_INSN (basic_block_head[b]);
int i, j;
int regno;
rtx insn = chain->insn;
enum rtx_code code = GET_CODE (insn);
/* Compute hard regs live at start of block -- this is the
real hard regs marked live, plus live pseudo regs that
have been renumbered to hard regs. No registers have yet been
saved because we restore all of them before the end of the basic
block. */
next = chain->next;
REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live);
CLEAR_HARD_REG_SET (hard_regs_saved);
CLEAR_HARD_REG_SET (hard_regs_need_restore);
n_regs_saved = 0;
if (chain->is_caller_save_insn)
abort ();
EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
{
if ((regno = reg_renumber[i]) >= 0)
for (j = regno;
j < regno + HARD_REGNO_NREGS (regno,
PSEUDO_REGNO_MODE (i));
j++)
SET_HARD_REG_BIT (hard_regs_live, j);
});
/* Now scan the insns in the block, keeping track of what hard
regs are live as we go. When we see a call, save the live
call-clobbered hard regs. */
for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (code) == 'i')
{
RTX_CODE code = GET_CODE (insn);
/* If some registers have been saved, see if INSN references
any of them. We must restore them before the insn if so. */
if (GET_RTX_CLASS (code) == 'i')
if (n_regs_saved)
{
rtx link;
int regno;
/* If some registers have been saved, see if INSN references
any of them. We must restore them before the insn if so. */
if (n_regs_saved)
restore_referenced_regs (PATTERN (insn), insn, insn_mode);
/* NB: the normal procedure is to first enliven any
registers set by insn, then deaden any registers that
had their last use at insn. This is incorrect now,
since multiple pseudos may have been mapped to the
same hard reg, and the death notes are ambiguous. So
it must be done in the other, safe, order. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
clear_reg_live (XEXP (link, 0));
/* When we reach a call, we need to save all registers that are
live, call-used, not fixed, and not already saved. We must
test at this point because registers that die in a CALL_INSN
are not live across the call and likewise for registers that
are born in the CALL_INSN.
If registers are filled with parameters for this function,
and some of these are also being set by this function, then
they will not appear to die (no REG_DEAD note for them),
to check if in fact they do, collect the set registers in
hard_regs_live first. */
if (code == CALL_INSN)
{
HARD_REG_SET this_call_sets;
{
HARD_REG_SET old_hard_regs_live;
/* Save the hard_regs_live information. */
COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live);
/* Now calculate hard_regs_live for this CALL_INSN
only. */
CLEAR_HARD_REG_SET (hard_regs_live);
note_stores (PATTERN (insn), set_reg_live);
COPY_HARD_REG_SET (this_call_sets, hard_regs_live);
/* Restore the hard_regs_live information. */
COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live);
}
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (call_used_regs[regno] && ! call_fixed_regs[regno]
&& TEST_HARD_REG_BIT (hard_regs_live, regno)
/* It must not be set by this instruction. */
&& ! TEST_HARD_REG_BIT (this_call_sets, regno)
&& ! TEST_HARD_REG_BIT (hard_regs_saved, regno))
regno += insert_save_restore (insn, 1, regno,
insn_mode, 0);
/* Put the information for this CALL_INSN on top of what
we already had. */
IOR_HARD_REG_SET (hard_regs_live, this_call_sets);
COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved);
/* Must recompute n_regs_saved. */
n_regs_saved = 0;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
n_regs_saved++;
}
if (code == JUMP_INSN)
/* Restore all registers if this is a JUMP_INSN. */
COPY_HARD_REG_SET (referenced_regs, hard_regs_saved);
else
{
note_stores (PATTERN (insn), set_reg_live);
#ifdef AUTO_INC_DEC
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
set_reg_live (XEXP (link, 0), NULL_RTX);
#endif
CLEAR_HARD_REG_SET (referenced_regs);
mark_referenced_regs (PATTERN (insn));
AND_HARD_REG_SET (referenced_regs, hard_regs_saved);
}
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_UNUSED)
clear_reg_live (XEXP (link, 0));
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (referenced_regs, regno))
regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS);
}
if (insn == basic_block_end[b])
break;
if (code == CALL_INSN)
{
rtx x;
int regno, nregs;
HARD_REG_SET hard_regs_to_save;
/* Use the register life information in CHAIN to compute which
regs are live before the call. */
REG_SET_TO_HARD_REG_SET (hard_regs_to_save, chain->live_before);
compute_use_by_pseudos (&hard_regs_to_save, chain->live_before);
/* Record all registers set in this call insn. These don't need
to be saved. */
CLEAR_HARD_REG_SET (this_insn_sets);
note_stores (PATTERN (insn), mark_set_regs);
/* Compute which hard regs must be saved before this call. */
AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets);
AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved);
AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set);
/* Registers used for function parameters need not be saved. */
for (x = CALL_INSN_FUNCTION_USAGE (insn); x != 0;
x = XEXP (x, 1))
{
rtx y;
if (GET_CODE (XEXP (x, 0)) != USE)
continue;
y = XEXP (XEXP (x, 0), 0);
if (GET_CODE (y) != REG)
abort ();
regno = REGNO (y);
if (REGNO (y) >= FIRST_PSEUDO_REGISTER)
abort ();
nregs = HARD_REGNO_NREGS (regno, GET_MODE (y));
while (nregs-- > 0)
CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs);
}
/* Neither do registers for which we find a death note. */
for (x = REG_NOTES (insn); x != 0; x = XEXP (x, 1))
{
rtx y = XEXP (x, 0);
if (REG_NOTE_KIND (x) != REG_DEAD)
continue;
if (GET_CODE (y) != REG)
abort ();
regno = REGNO (y);
if (regno >= FIRST_PSEUDO_REGISTER)
regno = reg_renumber[regno];
if (regno < 0)
continue;
nregs = HARD_REGNO_NREGS (regno, GET_MODE (y));
while (nregs-- > 0)
CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs);
}
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_to_save, regno))
regno += insert_save (chain, 1, regno, &hard_regs_to_save);
/* Must recompute n_regs_saved. */
n_regs_saved = 0;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
n_regs_saved++;
}
}
/* At the end of the basic block, we must restore any registers that
remain saved. If the last insn in the block is a JUMP_INSN, put
the restore before the insn, otherwise, put it after the insn. */
if (chain->next == 0 || chain->next->block > chain->block)
{
int regno;
/* At the end of the basic block, we must restore any registers that
remain saved. If the last insn in the block is a JUMP_INSN, put
the restore before the insn, otherwise, put it after the insn. */
if (n_regs_saved)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno))
regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN
? insn : NEXT_INSN (insn)), 0,
regno, insn_mode, MOVE_MAX / UNITS_PER_WORD);
/* If we added any insns at the start of the block, update the start
of the block to point at those insns. */
basic_block_head[b] = NEXT_INSN (prev_block_last);
}
if (n_regs_saved)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN,
regno, MOVE_MAX_WORDS);
}
}
}
/* Here from note_stores when an insn stores a value in a register.
Set the proper bit or bits in hard_regs_live. All pseudos that have
Set the proper bit or bits in this_insn_sets. All pseudos that have
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
static void
set_reg_live (reg, setter)
mark_set_regs (reg, setter)
rtx reg;
rtx setter ATTRIBUTE_UNUSED;
{
@ -526,105 +485,71 @@ set_reg_live (reg, setter)
endregno = regno + HARD_REGNO_NREGS (regno, mode);
for (i = regno; i < endregno; i++)
{
SET_HARD_REG_BIT (hard_regs_live, i);
CLEAR_HARD_REG_BIT (hard_regs_saved, i);
CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
}
SET_HARD_REG_BIT (this_insn_sets, i);
}
/* Here when a REG_DEAD note records the last use of a reg. Clear
the appropriate bit or bits in hard_regs_live. Again we can ignore
pseudos. */
/* Walk X and record all referenced registers in REFERENCED_REGS. */
static void
clear_reg_live (reg)
rtx reg;
{
register int regno, endregno, i;
if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
return;
regno = REGNO (reg);
endregno= regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
for (i = regno; i < endregno; i++)
{
CLEAR_HARD_REG_BIT (hard_regs_live, i);
CLEAR_HARD_REG_BIT (hard_regs_need_restore, i);
CLEAR_HARD_REG_BIT (hard_regs_saved, i);
}
}
/* If any register currently residing in the save area is referenced in X,
which is part of INSN, emit code to restore the register in front of INSN.
INSN_MODE is the mode to assign to any insns that we add. */
static void
restore_referenced_regs (x, insn, insn_mode)
mark_referenced_regs (x)
rtx x;
rtx insn;
enum machine_mode insn_mode;
{
enum rtx_code code = GET_CODE (x);
char *fmt;
int i, j;
if (code == CLOBBER)
return;
if (code == SET)
mark_referenced_regs (SET_SRC (x));
if (code == SET || code == CLOBBER)
{
x = SET_DEST (x);
code = GET_CODE (x);
if (code == REG || code == PC || code == CC0
|| (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
return;
}
if (code == MEM || code == SUBREG)
{
x = XEXP (x, 0);
code = GET_CODE (x);
}
if (code == REG)
{
int regno = REGNO (x);
int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno
: reg_renumber[regno]);
/* If this is a pseudo, scan its memory location, since it might
involve the use of another register, which might be saved. */
if (regno >= FIRST_PSEUDO_REGISTER
&& reg_equiv_mem[regno] != 0)
restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0),
insn, insn_mode);
else if (regno >= FIRST_PSEUDO_REGISTER
&& reg_equiv_address[regno] != 0)
restore_referenced_regs (reg_equiv_address[regno],
insn, insn_mode);
/* Otherwise if this is a hard register, restore any piece of it that
is currently saved. */
else if (regno < FIRST_PSEUDO_REGISTER)
if (hardregno >= 0)
{
int numregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
/* Save at most SAVEREGS at a time. This can not be larger than
MOVE_MAX, because that causes insert_save_restore to fail. */
int saveregs = MIN (numregs, MOVE_MAX / UNITS_PER_WORD);
int endregno = regno + numregs;
for (i = regno; i < endregno; i++)
if (TEST_HARD_REG_BIT (hard_regs_need_restore, i))
i += insert_save_restore (insn, 0, i, insn_mode, saveregs);
int nregs = HARD_REGNO_NREGS (hardregno, GET_MODE (x));
while (nregs-- > 0)
SET_HARD_REG_BIT (referenced_regs, hardregno + nregs);
}
/* If this is a pseudo that did not get a hard register, scan its
memory location, since it might involve the use of another
register, which might be saved. */
else if (reg_equiv_mem[regno] != 0)
mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0));
else if (reg_equiv_address[regno] != 0)
mark_referenced_regs (reg_equiv_address[regno]);
return;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
restore_referenced_regs (XEXP (x, i), insn, insn_mode);
mark_referenced_regs (XEXP (x, i));
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode);
mark_referenced_regs (XVECEXP (x, i, j));
}
}
/* Insert a sequence of insns to save or restore, SAVE_P says which,
REGNO. Place these insns in front of INSN. INSN_MODE is the mode
to assign to these insns. MAXRESTORE is the maximum number of registers
which should be restored during this call (when SAVE_P == 0). It should
never be less than 1 since we only work with entire registers.
/* Insert a sequence of insns to restore. Place these insns in front of
CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is
the maximum number of registers which should be restored during this call.
It should never be less than 1 since we only work with entire registers.
Note that we have verified in init_caller_save that we can do this
with a simple SET, so use it. Set INSN_CODE to what we save there
@ -635,13 +560,13 @@ restore_referenced_regs (x, insn, insn_mode)
Return the extra number of registers saved. */
static int
insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
rtx insn;
int save_p;
insert_restore (chain, before_p, regno, maxrestore)
struct insn_chain *chain;
int before_p;
int regno;
enum machine_mode insn_mode;
int maxrestore;
{
int i;
rtx pat = NULL_RTX;
enum insn_code code = CODE_FOR_nothing;
int numregs = 0;
@ -656,6 +581,128 @@ insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
if (regno_save_mem[regno][1] == 0)
abort ();
/* Get the pattern to emit and update our status.
See if we can restore `maxrestore' registers at once. Work
backwards to the single register case. */
for (i = maxrestore; i > 0; i--)
{
int j, k;
int ok = 1;
if (regno_save_mem[regno][i] == 0)
continue;
for (j = 0; j < i; j++)
if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
{
ok = 0;
break;
}
/* Must do this one restore at a time */
if (! ok)
continue;
pat = gen_rtx_SET (VOIDmode,
gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]),
regno),
regno_save_mem[regno][i]);
code = reg_restore_code[regno][i];
/* Clear status for all registers we restored. */
for (k = 0; k < i; k++)
{
CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
n_regs_saved--;
}
numregs = i;
break;
}
insert_one_insn (chain, before_p, code, pat);
/* Tell our callers how many extra registers we saved/restored */
return numregs - 1;
}
/* Like insert_restore above, but save registers instead. */
static int
insert_save (chain, before_p, regno, to_save)
struct insn_chain *chain;
int before_p;
int regno;
HARD_REG_SET *to_save;
{
int i;
rtx pat = NULL_RTX;
enum insn_code code = CODE_FOR_nothing;
int numregs = 0;
/* A common failure mode if register status is not correct in the RTL
is for this routine to be called with a REGNO we didn't expect to
save. That will cause us to write an insn with a (nil) SET_DEST
or SET_SRC. Instead of doing so and causing a crash later, check
for this common case and abort here instead. This will remove one
step in debugging such problems. */
if (regno_save_mem[regno][1] == 0)
abort ();
/* Get the pattern to emit and update our status.
See if we can save several registers with a single instruction.
Work backwards to the single register case. */
for (i = MOVE_MAX_WORDS; i > 0; i--)
{
int j, k;
int ok = 1;
if (regno_save_mem[regno][i] == 0)
continue;
for (j = 0; j < i; j++)
if (! TEST_HARD_REG_BIT (*to_save, regno + j))
{
ok = 0;
break;
}
/* Must do this one save at a time */
if (! ok)
continue;
pat = gen_rtx_SET (VOIDmode, regno_save_mem[regno][i],
gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]),
regno));
code = reg_save_code[regno][i];
/* Set hard_regs_saved for all the registers we saved. */
for (k = 0; k < i; k++)
{
SET_HARD_REG_BIT (hard_regs_saved, regno + k);
n_regs_saved++;
}
numregs = i;
break;
}
insert_one_insn (chain, before_p, code, pat);
/* Tell our callers how many extra registers we saved/restored */
return numregs - 1;
}
/* Emit a new caller-save insn and set the code. */
static void
insert_one_insn (chain, before_p, code, pat)
struct insn_chain *chain;
int before_p;
enum insn_code code;
rtx pat;
{
rtx insn = chain->insn;
struct insn_chain *new;
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an
@ -664,100 +711,47 @@ insert_save_restore (insn, save_p, regno, insn_mode, maxrestore)
reference CC0. Guard against non-INSN's like CODE_LABEL. */
if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
&& before_p
&& reg_referenced_p (cc0_rtx, PATTERN (insn)))
insn = prev_nonnote_insn (insn);
chain = chain->prev, insn = chain->insn;
#endif
/* Get the pattern to emit and update our status. */
if (save_p)
new = new_insn_chain ();
if (before_p)
{
int i, j, k;
int ok;
new->prev = chain->prev;
if (new->prev != 0)
new->prev->next = new;
else
reload_insn_chain = new;
/* See if we can save several registers with a single instruction.
Work backwards to the single register case. */
for (i = MOVE_MAX / UNITS_PER_WORD; i > 0; i--)
{
ok = 1;
if (regno_save_mem[regno][i] != 0)
for (j = 0; j < i; j++)
{
if (! call_used_regs[regno + j] || call_fixed_regs[regno + j]
|| ! TEST_HARD_REG_BIT (hard_regs_live, regno + j)
|| TEST_HARD_REG_BIT (hard_regs_saved, regno + j))
ok = 0;
}
else
continue;
/* Must do this one save at a time */
if (! ok)
continue;
pat = gen_rtx_SET (VOIDmode, regno_save_mem[regno][i],
gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]),
regno));
code = reg_save_code[regno][i];
/* Set hard_regs_saved for all the registers we saved. */
for (k = 0; k < i; k++)
{
SET_HARD_REG_BIT (hard_regs_saved, regno + k);
SET_HARD_REG_BIT (hard_regs_need_restore, regno + k);
n_regs_saved++;
}
numregs = i;
break;
}
chain->prev = new;
new->next = chain;
new->insn = emit_insn_before (pat, insn);
/* ??? It would be nice if we could exclude the already / still saved
registers from the live sets. */
COPY_REG_SET (new->live_before, chain->live_before);
COPY_REG_SET (new->live_after, chain->live_before);
if (chain->insn == BLOCK_HEAD (chain->block))
BLOCK_HEAD (chain->block) = new->insn;
}
else
{
int i, j, k;
int ok;
/* See if we can restore `maxrestore' registers at once. Work
backwards to the single register case. */
for (i = maxrestore; i > 0; i--)
{
ok = 1;
if (regno_save_mem[regno][i])
for (j = 0; j < i; j++)
{
if (! TEST_HARD_REG_BIT (hard_regs_need_restore, regno + j))
ok = 0;
}
else
continue;
/* Must do this one restore at a time */
if (! ok)
continue;
pat = gen_rtx_SET (VOIDmode,
gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]),
regno),
regno_save_mem[regno][i]);
code = reg_restore_code[regno][i];
/* Clear status for all registers we restored. */
for (k = 0; k < i; k++)
{
CLEAR_HARD_REG_BIT (hard_regs_need_restore, regno + k);
n_regs_saved--;
}
numregs = i;
break;
}
new->next = chain->next;
if (new->next != 0)
new->next->prev = new;
chain->next = new;
new->prev = chain;
new->insn = emit_insn_after (pat, insn);
/* ??? It would be nice if we could exclude the already / still saved
registers from the live sets, and observe REG_UNUSED notes. */
COPY_REG_SET (new->live_before, chain->live_after);
COPY_REG_SET (new->live_after, chain->live_after);
if (chain->insn == BLOCK_END (chain->block))
BLOCK_END (chain->block) = new->insn;
}
/* Emit the insn and set the code and mode. */
new->block = chain->block;
new->is_caller_save_insn = 1;
insn = emit_insn_before (pat, insn);
PUT_MODE (insn, insn_mode);
INSN_CODE (insn) = code;
/* Tell our callers how many extra registers we saved/restored */
return numregs - 1;
INSN_CODE (new->insn) = code;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Parse C expressions for CCCP.
Copyright (C) 1987, 1992, 94 - 97, 1998 Free Software Foundation.
Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@ -26,25 +26,16 @@ Boston, MA 02111-1307, USA.
%{
#include "config.h"
#ifdef __STDC__
# include <stdarg.h>
#else
# include <varargs.h>
#endif
#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
#include "system.h"
#include "intl.h"
#include <setjmp.h>
/* #define YYDEBUG 1 */
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
#include <locale.h>
#endif
#include "gansidecl.h"
#endif /* MULTIBYTE_CHARS */
typedef unsigned char U_CHAR;
@ -56,44 +47,12 @@ struct arglist {
int argno;
};
/* Find the largest host integer type and set its size and type.
Watch out: on some crazy hosts `long' is shorter than `int'. */
#ifndef HOST_WIDE_INT
# if HAVE_INTTYPES_H
# include <inttypes.h>
# define HOST_WIDE_INT intmax_t
# define unsigned_HOST_WIDE_INT uintmax_t
# else
# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
# define HOST_WIDE_INT int
# else
# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
# define HOST_WIDE_INT long
# else
# define HOST_WIDE_INT long long
# endif
# endif
# endif
#endif
#ifndef unsigned_HOST_WIDE_INT
#define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
#endif
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef HOST_BITS_PER_WIDE_INT
#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
#endif
HOST_WIDE_INT parse_c_expression PROTO((char *, int));
HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
static int yylex PROTO((void));
static void yyerror PROTO((char *)) __attribute__ ((noreturn));
static HOST_WIDE_INT expression_value;
static void yyerror PVPROTO((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
static HOST_WIDEST_INT expression_value;
#ifdef TEST_EXP_READER
static int expression_signedp;
#endif
@ -154,13 +113,13 @@ extern int c89;
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif
#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
: ~ (HOST_WIDE_INT) 0)
#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
: ~ (HOST_WIDEST_INT) 0)
#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
: ~ (HOST_WIDE_INT) 0)
#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
: ~ (HOST_WIDEST_INT) 0)
/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
@ -174,17 +133,17 @@ extern int c89;
struct constant;
GENERIC_PTR xmalloc PROTO((size_t));
HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
struct hashnode *lookup PROTO((U_CHAR *, int, int));
void error PRINTF_PROTO_1((char *, ...));
void pedwarn PRINTF_PROTO_1((char *, ...));
void warning PRINTF_PROTO_1((char *, ...));
void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
void verror PROTO((const char *, va_list));
void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
static int parse_number PROTO((int));
static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
static void integer_overflow PROTO((void));
/* `signedp' values */
@ -193,7 +152,7 @@ static void integer_overflow PROTO((void));
%}
%union {
struct constant {HOST_WIDE_INT value; int signedp;} integer;
struct constant {HOST_WIDEST_INT value; int signedp;} integer;
struct name {U_CHAR *address; int length;} name;
struct arglist *keywords;
}
@ -280,7 +239,7 @@ exp : exp '*' exp
integer_overflow ();
}
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
* $3.value); }
| exp '/' exp
{ if ($3.value == 0)
@ -297,7 +256,7 @@ exp : exp '*' exp
integer_overflow ();
}
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
/ $3.value); }
| exp '%' exp
{ if ($3.value == 0)
@ -310,7 +269,7 @@ exp : exp '*' exp
if ($$.signedp)
$$.value = $1.value % $3.value;
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
% $3.value); }
| exp '+' exp
{ $$.value = $1.value + $3.value;
@ -347,28 +306,28 @@ exp : exp '*' exp
if ($1.signedp & $3.signedp)
$$.value = $1.value <= $3.value;
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
<= $3.value); }
| exp GEQ exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value >= $3.value;
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
>= $3.value); }
| exp '<' exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value < $3.value;
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
< $3.value); }
| exp '>' exp
{ $$.signedp = SIGNED;
if ($1.signedp & $3.signedp)
$$.value = $1.value > $3.value;
else
$$.value = ((unsigned_HOST_WIDE_INT) $1.value
$$.value = ((unsigned HOST_WIDEST_INT) $1.value
> $3.value); }
| exp '&' exp
{ $$.value = $1.value & $3.value;
@ -451,7 +410,7 @@ parse_number (olen)
{
register char *p = lexptr;
register int c;
register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
register int base = 10;
register int len = olen;
register int overflow = 0;
@ -469,7 +428,7 @@ parse_number (olen)
}
}
max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
for (; len > 0; len--) {
c = *p++;
@ -498,12 +457,9 @@ parse_number (olen)
else {
if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
yyerror ("Floating point numbers not allowed in #if expressions");
else {
char *buf = (char *) alloca (p - lexptr + 40);
sprintf (buf, "missing white space after number `%.*s'",
else
yyerror ("missing white space after number `%.*s'",
(int) (p - lexptr - 1), lexptr);
yyerror (buf);
}
}
if (--len == 0)
@ -527,7 +483,7 @@ parse_number (olen)
pedwarn ("integer constant out of range");
/* If too big to be signed, consider it unsigned. */
if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
{
if (base == 10)
warning ("integer constant is so large that it is unsigned");
@ -540,7 +496,7 @@ parse_number (olen)
}
struct token {
char *operator;
const char *operator;
int token;
};
@ -568,7 +524,7 @@ yylex ()
register unsigned char *tokstart;
register struct token *toktab;
int wide_flag;
HOST_WIDE_INT mask;
HOST_WIDEST_INT mask;
retry:
@ -580,11 +536,7 @@ yylex ()
if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
lexptr += 2;
if (toktab->token == ERROR)
{
char *buf = (char *) alloca (40);
sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
yyerror (buf);
}
yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
return toktab->token;
}
@ -639,25 +591,20 @@ yylex ()
handles multicharacter constants and wide characters.
It is mostly copied from c-lex.c. */
{
register HOST_WIDE_INT result = 0;
register HOST_WIDEST_INT result = 0;
register int num_chars = 0;
int chars_seen = 0;
unsigned width = MAX_CHAR_TYPE_SIZE;
int max_chars;
char *token_buffer;
if (wide_flag)
{
width = MAX_WCHAR_TYPE_SIZE;
#ifdef MULTIBYTE_CHARS
max_chars = MB_CUR_MAX;
#else
max_chars = 1;
int longest_char = local_mb_cur_max ();
char *token_buffer = (char *) alloca (longest_char);
(void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
#endif
}
else
max_chars = MAX_LONG_TYPE_SIZE / width;
token_buffer = (char *) alloca (max_chars + 1);
max_chars = MAX_LONG_TYPE_SIZE / width;
if (wide_flag)
width = MAX_WCHAR_TYPE_SIZE;
while (1)
{
@ -666,72 +613,108 @@ yylex ()
if (c == '\'' || c == EOF)
break;
++chars_seen;
if (c == '\\')
{
c = parse_escape (&lexptr, mask);
}
else
{
#ifdef MULTIBYTE_CHARS
wchar_t wc;
int i;
int char_len = -1;
for (i = 1; i <= longest_char; ++i)
{
token_buffer[i - 1] = c;
char_len = local_mbtowc (& wc, token_buffer, i);
if (char_len != -1)
break;
c = *lexptr++;
}
if (char_len > 1)
{
/* mbtowc sometimes needs an extra char before accepting */
if (char_len < i)
lexptr--;
if (! wide_flag)
{
/* Merge character into result; ignore excess chars. */
for (i = 1; i <= char_len; ++i)
{
if (i > max_chars)
break;
if (width < HOST_BITS_PER_INT)
result = (result << width)
| (token_buffer[i - 1]
& ((1 << width) - 1));
else
result = token_buffer[i - 1];
}
num_chars += char_len;
continue;
}
}
else
{
if (char_len == -1)
warning ("Ignoring invalid multibyte character");
}
if (wide_flag)
c = wc;
#endif /* ! MULTIBYTE_CHARS */
}
num_chars++;
if (wide_flag)
{
if (chars_seen == 1) /* only keep the first one */
result = c;
continue;
}
/* Merge character into result; ignore excess chars. */
num_chars++;
if (num_chars <= max_chars)
{
if (width < HOST_BITS_PER_WIDE_INT)
result = (result << width) | c;
if (width < HOST_BITS_PER_INT)
result = (result << width) | (c & ((1 << width) - 1));
else
result = c;
token_buffer[num_chars - 1] = c;
}
}
token_buffer[num_chars] = 0;
if (c != '\'')
error ("malformatted character constant");
else if (num_chars == 0)
else if (chars_seen == 0)
error ("empty character constant");
else if (num_chars > max_chars)
{
num_chars = max_chars;
error ("character constant too long");
}
else if (num_chars != 1 && ! traditional)
else if (chars_seen != 1 && ! traditional)
warning ("multi-character character constant");
/* If char type is signed, sign-extend the constant. */
if (! wide_flag)
{
int num_bits = num_chars * width;
if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
if (num_bits == 0)
/* We already got an error; avoid invalid shift. */
yylval.integer.value = 0;
else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
sizeof ("__CHAR_UNSIGNED__") - 1, -1)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.integer.value
= result & (~ (unsigned_HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits));
= result & (~ (unsigned HOST_WIDEST_INT) 0
>> (HOST_BITS_PER_WIDEST_INT - num_bits));
else
yylval.integer.value
= result | ~(~ (unsigned_HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits));
= result | ~(~ (unsigned HOST_WIDEST_INT) 0
>> (HOST_BITS_PER_WIDEST_INT - num_bits));
}
else
{
#ifdef MULTIBYTE_CHARS
/* Set the initial shift state and convert the next sequence. */
result = 0;
/* In all locales L'\0' is zero and mbtowc will return zero,
so don't use it. */
if (num_chars > 1
|| (num_chars == 1 && token_buffer[0] != '\0'))
{
wchar_t wc;
(void) mbtowc (NULL_PTR, NULL_PTR, 0);
if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
result = wc;
else
pedwarn ("Ignoring invalid multibyte character");
}
#endif
yylval.integer.value = result;
}
}
@ -854,10 +837,10 @@ yylex ()
If \ is followed by 000, we return 0 and leave the string pointer
after the zeros. A value of 0 does not mean end of string. */
HOST_WIDE_INT
HOST_WIDEST_INT
parse_escape (string_ptr, result_mask)
char **string_ptr;
HOST_WIDE_INT result_mask;
HOST_WIDEST_INT result_mask;
{
register int c = *(*string_ptr)++;
switch (c)
@ -896,7 +879,7 @@ parse_escape (string_ptr, result_mask)
case '6':
case '7':
{
register HOST_WIDE_INT i = c - '0';
register HOST_WIDEST_INT i = c - '0';
register int count = 0;
while (++count < 3)
{
@ -918,7 +901,7 @@ parse_escape (string_ptr, result_mask)
}
case 'x':
{
register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
register int digits_found = 0, digit;
for (;;)
{
@ -952,15 +935,6 @@ parse_escape (string_ptr, result_mask)
}
}
static void
yyerror (s)
char *s;
{
error ("%s", s);
skip_evaluation = 0;
longjmp (parse_return_error, 1);
}
static void
integer_overflow ()
{
@ -968,31 +942,31 @@ integer_overflow ()
pedwarn ("integer overflow in preprocessor expression");
}
static HOST_WIDE_INT
static HOST_WIDEST_INT
left_shift (a, b)
struct constant *a;
unsigned_HOST_WIDE_INT b;
unsigned HOST_WIDEST_INT b;
{
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
if (b >= HOST_BITS_PER_WIDE_INT)
if (b >= HOST_BITS_PER_WIDEST_INT)
return 0;
else
return (unsigned_HOST_WIDE_INT) a->value << b;
return (unsigned HOST_WIDEST_INT) a->value << b;
}
static HOST_WIDE_INT
static HOST_WIDEST_INT
right_shift (a, b)
struct constant *a;
unsigned_HOST_WIDE_INT b;
unsigned HOST_WIDEST_INT b;
{
if (b >= HOST_BITS_PER_WIDE_INT)
return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
if (b >= HOST_BITS_PER_WIDEST_INT)
return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
else if (a->signedp)
return a->value >> b;
else
return (unsigned_HOST_WIDE_INT) a->value >> b;
return (unsigned HOST_WIDEST_INT) a->value >> b;
}
/* This page contains the entry point to this file. */
@ -1005,7 +979,7 @@ right_shift (a, b)
We do not support C comments. They should be removed before
this function is called. */
HOST_WIDE_INT
HOST_WIDEST_INT
parse_c_expression (string, warn_undefined)
char *string;
int warn_undefined;
@ -1027,6 +1001,27 @@ parse_c_expression (string, warn_undefined)
return expression_value; /* set by yyparse () */
}
static void
yyerror VPROTO ((const char * msgid, ...))
{
#ifndef ANSI_PROTOTYPES
const char * msgid;
#endif
va_list args;
VA_START (args, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (args, const char *);
#endif
verror (msgid, args);
va_end (args);
skip_evaluation = 0;
longjmp (parse_return_error, 1);
}
#ifdef TEST_EXP_READER
@ -1036,10 +1031,11 @@ extern int yydebug;
int pedantic;
int traditional;
int c89;
int main PROTO((int, char **));
static void initialize_random_junk PROTO((void));
static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
/* Main program for testing purposes. */
int
@ -1049,12 +1045,13 @@ main (argc, argv)
{
int n, c;
char buf[1024];
unsigned_HOST_WIDE_INT u;
unsigned HOST_WIDEST_INT u;
pedantic = 1 < argc;
traditional = 2 < argc;
c89 = 3 < argc;
#if YYDEBUG
yydebug = 3 < argc;
yydebug = 4 < argc;
#endif
initialize_random_junk ();
@ -1067,7 +1064,7 @@ main (argc, argv)
break;
parse_c_expression (buf, 1);
printf ("parser returned ");
u = (unsigned_HOST_WIDE_INT) expression_value;
u = (unsigned HOST_WIDEST_INT) expression_value;
if (expression_value < 0 && expression_signedp) {
u = -u;
printf ("-");
@ -1075,7 +1072,7 @@ main (argc, argv)
if (u == 0)
printf ("0");
else
print_unsigned_host_wide_int (u);
print_unsigned_host_widest_int (u);
if (! expression_signedp)
printf("u");
printf ("\n");
@ -1085,11 +1082,11 @@ main (argc, argv)
}
static void
print_unsigned_host_wide_int (u)
unsigned_HOST_WIDE_INT u;
print_unsigned_host_widest_int (u)
unsigned HOST_WIDEST_INT u;
{
if (u) {
print_unsigned_host_wide_int (u / 10);
print_unsigned_host_widest_int (u / 10);
putchar ('0' + (int) (u % 10));
}
}
@ -1137,65 +1134,66 @@ initialize_random_junk ()
}
void
error VPROTO ((char * msg, ...))
error VPROTO ((char * msgid, ...))
{
#ifndef __STDC__
char * msg;
#ifndef ANSI_PROTOTYPES
char * msgid;
#endif
va_list args;
VA_START (args, msg);
#ifndef __STDC__
msg = va_arg (args, char *);
VA_START (args, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (args, char *);
#endif
fprintf (stderr, "error: ");
vfprintf (stderr, msg, args);
vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
pedwarn VPROTO ((char * msg, ...))
pedwarn VPROTO ((char * msgid, ...))
{
#ifndef __STDC__
char * msg;
#ifndef ANSI_PROTOTYPES
char * msgid;
#endif
va_list args;
VA_START (args, msg);
#ifndef __STDC__
msg = va_arg (args, char *);
VA_START (args, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (args, char *);
#endif
fprintf (stderr, "pedwarn: ");
vfprintf (stderr, msg, args);
vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
void
warning VPROTO ((char * msg, ...))
warning VPROTO ((char * msgid, ...))
{
#ifndef __STDC__
char * msg;
#ifndef ANSI_PROTOTYPES
char * msgid;
#endif
va_list args;
VA_START (args, msg);
#ifndef __STDC__
msg = va_arg (args, char *);
VA_START (args, msgid);
#ifndef ANSI_PROTOTYPES
msgid = va_arg (args, char *);
#endif
fprintf (stderr, "warning: ");
vfprintf (stderr, msg, args);
vfprintf (stderr, _(msgid), args);
fprintf (stderr, "\n");
va_end (args);
}
int
check_assertion (name, sym_length, tokens_specified, tokens)
U_CHAR *name;
@ -1215,10 +1213,10 @@ lookup (name, len, hash)
return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
}
GENERIC_PTR
PTR
xmalloc (size)
size_t size;
size_t size;
{
return (GENERIC_PTR) malloc (size);
return (PTR) malloc (size);
}
#endif

File diff suppressed because it is too large Load Diff

36
contrib/gcc/collect2.h Normal file
View File

@ -0,0 +1,36 @@
/* Header file for collect/tlink routines.
Copyright (C) 1998 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.
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. */
#ifndef __COLLECT2_H__
#define __COLLECT2_H__
extern void do_tlink PARAMS ((char **, char **));
extern void collect_execute PARAMS ((char *, char **, char *));
extern void collect_exit PARAMS ((int)) ATTRIBUTE_NORETURN;
extern int collect_wait PARAMS ((char *));
extern void dump_file PARAMS ((char *));
extern int file_exists PARAMS ((char *));
#endif /* ! __COLLECT2_H__ */

View File

@ -75,16 +75,8 @@ Boston, MA 02111-1307, USA. */
combine anyway. */
#include "config.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
/* stdio.h must precede rtl.h for FFS. */
#include "system.h"
#include "rtl.h"
#include "rtl.h" /* stdio.h must precede rtl.h for FFS. */
#include "flags.h"
#include "regs.h"
#include "hard-reg-set.h"
@ -434,7 +426,7 @@ static int merge_outer_ops PROTO((enum rtx_code *, HOST_WIDE_INT *,
enum machine_mode, int *));
static rtx simplify_shift_const PROTO((rtx, enum rtx_code, enum machine_mode,
rtx, int));
static int recog_for_combine PROTO((rtx *, rtx, rtx *, int *));
static int recog_for_combine PROTO((rtx *, rtx, rtx *));
static rtx gen_lowpart_for_combine PROTO((enum machine_mode, rtx));
static rtx gen_rtx_combine PVPROTO((enum rtx_code code, enum machine_mode mode,
...));
@ -581,7 +573,7 @@ combine_instructions (f, nregs)
/* If INSN starts a new basic block, update our basic block number. */
if (this_basic_block + 1 < n_basic_blocks
&& basic_block_head[this_basic_block + 1] == insn)
&& BLOCK_HEAD (this_basic_block + 1) == insn)
this_basic_block++;
if (GET_CODE (insn) == CODE_LABEL)
@ -682,6 +674,9 @@ combine_instructions (f, nregs)
total_successes += combine_successes;
nonzero_sign_valid = 0;
/* Make recognizer allow volatile MEMs again. */
init_recog ();
}
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
@ -749,7 +744,7 @@ set_nonzero_bits_and_sign_copies (x, set)
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
/* If this register is undefined at the start of the file, we can't
say what its contents were. */
&& ! REGNO_REG_SET_P (basic_block_live_at_start[0], REGNO (x))
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x))
&& GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
{
if (set == 0 || GET_CODE (set) == CLOBBER)
@ -824,7 +819,8 @@ static int
can_combine_p (insn, i3, pred, succ, pdest, psrc)
rtx insn;
rtx i3;
rtx pred, succ;
rtx pred ATTRIBUTE_UNUSED;
rtx succ;
rtx *pdest, *psrc;
{
int i;
@ -958,8 +954,14 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
/* Don't substitute into an incremented register. */
|| FIND_REG_INC_NOTE (i3, dest)
|| (succ && FIND_REG_INC_NOTE (succ, dest))
#if 0
/* Don't combine the end of a libcall into anything. */
/* ??? This gives worse code, and appears to be unnecessary, since no
pass after flow uses REG_LIBCALL/REG_RETVAL notes. Local-alloc does
use REG_RETVAL notes for noconflict blocks, but other code here
makes sure that those insns don't disappear. */
|| find_reg_note (insn, REG_RETVAL, NULL_RTX)
#endif
/* Make sure that DEST is not used after SUCC but before I3. */
|| (succ && ! all_adjacent
&& reg_used_between_p (dest, succ, i3))
@ -1354,8 +1356,6 @@ try_combine (i3, i2, i1)
int i3_subst_into_i2 = 0;
/* Notes that I1, I2 or I3 is a MULT operation. */
int have_mult = 0;
/* Number of clobbers of SCRATCH we had to add. */
int i3_scratches = 0, i2_scratches = 0, other_scratches = 0;
int maxreg;
rtx temp;
@ -1371,7 +1371,12 @@ try_combine (i3, i2, i1)
if (GET_RTX_CLASS (GET_CODE (i3)) != 'i'
|| GET_RTX_CLASS (GET_CODE (i2)) != 'i'
|| (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i')
|| find_reg_note (i3, REG_LIBCALL, NULL_RTX))
#if 0
/* ??? This gives worse code, and appears to be unnecessary, since no
pass after flow uses REG_LIBCALL/REG_RETVAL notes. */
|| find_reg_note (i3, REG_LIBCALL, NULL_RTX)
#endif
)
return 0;
combine_attempts++;
@ -1827,8 +1832,7 @@ try_combine (i3, i2, i1)
mark_used_regs_combine (newpat);
/* Is the result of combination a valid instruction? */
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
/* If the result isn't valid, see if it is a PARALLEL of two SETs where
the second SET's destination is a register that is unused. In that case,
@ -1849,8 +1853,7 @@ try_combine (i3, i2, i1)
&& asm_noperands (newpat) < 0)
{
newpat = XVECEXP (newpat, 0, 0);
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
@ -1863,8 +1866,7 @@ try_combine (i3, i2, i1)
&& asm_noperands (newpat) < 0)
{
newpat = XVECEXP (newpat, 0, 1);
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
/* If we were combining three insns and the result is a simple SET
@ -1933,8 +1935,7 @@ try_combine (i3, i2, i1)
if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest);
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes,
&i2_scratches);
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
/* If I2 or I3 has multiple SETs, we won't know how to track
register status, so don't use these insns. If I2's destination
@ -1943,8 +1944,8 @@ try_combine (i3, i2, i1)
if (i2_code_number >= 0 && i2set && i3set
&& (next_real_insn (i2) == i3
|| ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
insn_code_number = recog_for_combine (&newi3pat, i3, &new_i3_notes,
&i3_scratches);
insn_code_number = recog_for_combine (&newi3pat, i3,
&new_i3_notes);
if (insn_code_number >= 0)
newpat = newi3pat;
@ -2031,14 +2032,12 @@ try_combine (i3, i2, i1)
newi2pat = gen_rtx_combine (SET, VOIDmode, newdest, *split);
SUBST (*split, newdest);
i2_code_number
= recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
/* If the split point was a MULT and we didn't have one before,
don't use one now. */
if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
}
@ -2092,12 +2091,10 @@ try_combine (i3, i2, i1)
newpat = XVECEXP (newpat, 0, 1);
SUBST (SET_SRC (newpat),
gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest));
i2_code_number
= recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
if (insn_code_number >= 0)
{
@ -2127,7 +2124,7 @@ try_combine (i3, i2, i1)
for (insn = NEXT_INSN (i3);
insn && (this_basic_block == n_basic_blocks - 1
|| insn != basic_block_head[this_basic_block + 1]);
|| insn != BLOCK_HEAD (this_basic_block + 1));
insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
@ -2184,12 +2181,10 @@ try_combine (i3, i2, i1)
newpat = XVECEXP (newpat, 0, 0);
}
i2_code_number
= recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches);
i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
if (i2_code_number >= 0)
insn_code_number
= recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
}
/* If it still isn't recognized, fail and change things back the way they
@ -2211,9 +2206,8 @@ try_combine (i3, i2, i1)
CLEAR_HARD_REG_SET (newpat_used_regs);
other_code_number
= recog_for_combine (&other_pat, undobuf.other_insn,
&new_other_notes, &other_scratches);
other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
&new_other_notes);
if (other_code_number < 0 && ! check_asm_operands (other_pat))
{
@ -2316,7 +2310,7 @@ try_combine (i3, i2, i1)
SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
for (temp = NEXT_INSN (i2);
temp && (this_basic_block == n_basic_blocks - 1
|| basic_block_head[this_basic_block] != temp);
|| BLOCK_HEAD (this_basic_block) != temp);
temp = NEXT_INSN (temp))
if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i')
for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
@ -2496,7 +2490,8 @@ try_combine (i3, i2, i1)
regno = REGNO (i2dest);
REG_N_SETS (regno)--;
if (REG_N_SETS (regno) == 0
&& ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
regno))
REG_N_REFS (regno) = 0;
}
}
@ -2518,7 +2513,8 @@ try_combine (i3, i2, i1)
{
REG_N_SETS (regno)--;
if (REG_N_SETS (regno) == 0
&& ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
regno))
REG_N_REFS (regno) = 0;
}
}
@ -2530,12 +2526,6 @@ try_combine (i3, i2, i1)
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies);
/* If we added any (clobber (scratch)), add them to the max for a
block. This is a very pessimistic calculation, since we might
have had them already and this might not be the worst block, but
it's not worth doing any better. */
max_scratch += i3_scratches + i2_scratches + other_scratches;
/* If I3 is now an unconditional jump, ensure that it has a
BARRIER following it since it may have initially been a
conditional jump. It may also be the last nonnote insn. */
@ -2747,7 +2737,7 @@ find_split_point (loc, insn)
if (BITS_BIG_ENDIAN)
pos = GET_MODE_BITSIZE (mode) - len - pos;
if (src == mask)
if ((unsigned HOST_WIDE_INT) src == mask)
SUBST (SET_SRC (x),
gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
else
@ -3514,9 +3504,8 @@ simplify_rtx (x, op0_mode, last, in_dest)
plus_constant (XEXP (inner, 0),
(SUBREG_WORD (x) * UNITS_PER_WORD
+ endian_offset)));
MEM_VOLATILE_P (x) = MEM_VOLATILE_P (inner);
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (inner);
MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (inner);
MEM_COPY_ATTRIBUTES (x, inner);
return x;
}
@ -3821,9 +3810,12 @@ simplify_rtx (x, op0_mode, last, in_dest)
return SUBREG_REG (XEXP (x, 0));
/* If we know that the value is already truncated, we can
replace the TRUNCATE with a SUBREG. */
if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
>= GET_MODE_BITSIZE (mode) + 1)
replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION is
nonzero for the corresponding modes. */
if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
&& num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
>= GET_MODE_BITSIZE (mode) + 1)
return gen_lowpart_for_combine (mode, XEXP (x, 0));
/* A truncate of a comparison can be replaced with a subreg if
@ -4164,7 +4156,7 @@ simplify_rtx (x, op0_mode, last, in_dest)
if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
== (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
== (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
&& op1 == const0_rtx
&& mode == GET_MODE (op0)
&& (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
@ -4692,9 +4684,8 @@ simplify_set (x)
&& exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
{
rtx pat = PATTERN (other_insn), note = 0;
int scratches;
if ((recog_for_combine (&pat, other_insn, &note, &scratches) < 0
if ((recog_for_combine (&pat, other_insn, &note) < 0
&& ! check_asm_operands (pat)))
{
PUT_CODE (*cc_use, old_code);
@ -5131,7 +5122,7 @@ simplify_logical (x, last)
when STORE_FLAG_VALUE is the sign bit. */
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
== (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
== (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
&& op1 == const_true_rtx
&& GET_RTX_CLASS (GET_CODE (op0)) == '<'
&& reversible_comparison_p (op0))
@ -5432,6 +5423,24 @@ expand_field_assignment (x)
compute_mode = GET_MODE (inner);
/* Don't attempt bitwise arithmetic on non-integral modes. */
if (! INTEGRAL_MODE_P (compute_mode))
{
enum machine_mode imode;
/* Something is probably seriously wrong if this matches. */
if (! FLOAT_MODE_P (compute_mode))
break;
/* Try to find an integral mode to pun with. */
imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0);
if (imode == BLKmode)
break;
compute_mode = imode;
inner = gen_lowpart_for_combine (imode, inner);
}
/* Compute a mask of LEN bits, if we can do this on the host machine. */
if (len < HOST_BITS_PER_WIDE_INT)
mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1);
@ -5588,8 +5597,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (inner);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (inner);
MEM_COPY_ATTRIBUTES (new, inner);
}
else if (GET_CODE (inner) == REG)
{
@ -5653,27 +5661,45 @@ make_extraction (mode, inner, pos, pos_rtx, len,
#ifdef HAVE_insv
if (in_dest)
{
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
pos_mode = insn_operand_mode[(int) CODE_FOR_insv][2];
extraction_mode = insn_operand_mode[(int) CODE_FOR_insv][3];
wanted_inner_reg_mode
= (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_insv][0]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_insv][3]);
}
#endif
#ifdef HAVE_extzv
if (! in_dest && unsignedp)
{
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
pos_mode = insn_operand_mode[(int) CODE_FOR_extzv][3];
extraction_mode = insn_operand_mode[(int) CODE_FOR_extzv][0];
wanted_inner_reg_mode
= (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extzv][1]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extzv][0]);
}
#endif
#ifdef HAVE_extv
if (! in_dest && ! unsignedp)
{
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
pos_mode = insn_operand_mode[(int) CODE_FOR_extv][3];
extraction_mode = insn_operand_mode[(int) CODE_FOR_extv][0];
wanted_inner_reg_mode
= (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extv][1]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extv][0]);
}
#endif
@ -5763,8 +5789,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
rtx newmem = gen_rtx_MEM (wanted_inner_mode,
plus_constant (XEXP (inner, 0), offset));
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (inner);
MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (inner);
MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (inner);
MEM_COPY_ATTRIBUTES (newmem, inner);
inner = newmem;
}
}
@ -6328,7 +6353,7 @@ force_to_mode (x, mode, mask, reg, just_select)
need it. */
if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) == mask)
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == mask)
x = XEXP (x, 0);
/* If it remains an AND, try making another AND with the bits
@ -6390,20 +6415,21 @@ force_to_mode (x, mode, mask, reg, just_select)
unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
sp_mask &= ~ (sp_alignment - 1);
if ((sp_mask & ~ mask) == 0
&& ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) != 0)
if ((sp_mask & ~ smask) == 0
&& ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
((INTVAL (XEXP (x, 1)) -
STACK_BIAS) & mask)
STACK_BIAS) & smask)
+ STACK_BIAS),
mode, mask, reg, next_select);
mode, smask, reg, next_select);
}
#endif
if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
&& (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0
&& (INTVAL (XEXP (x, 1)) & ~ smask) != 0)
return force_to_mode (plus_constant (XEXP (x, 0),
INTVAL (XEXP (x, 1)) & mask),
mode, mask, reg, next_select);
(INTVAL (XEXP (x, 1))
& smask)),
mode, smask, reg, next_select);
}
}
@ -6549,7 +6575,7 @@ force_to_mode (x, mode, mask, reg, just_select)
/* If we are just looking for the sign bit, we don't need this shift at
all, even if it has a variable count. */
if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
&& (mask == ((HOST_WIDE_INT) 1
&& (mask == ((unsigned HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (x)) - 1))))
return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
@ -7376,7 +7402,7 @@ simplify_and_const_int (x, mode, varop, constop)
else
{
if (GET_CODE (XEXP (x, 1)) != CONST_INT
|| INTVAL (XEXP (x, 1)) != constop)
|| (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop)
SUBST (XEXP (x, 1), GEN_INT (constop));
SUBST (XEXP (x, 0), varop);
@ -8292,7 +8318,8 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
op0 = NIL;
else if (const0 == 0 && op0 == AND)
op0 = SET;
else if (const0 == GET_MODE_MASK (mode) && op0 == AND)
else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
&& op0 == AND)
op0 = NIL;
/* If this would be an entire word for the target, but is not for
@ -8475,8 +8502,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
plus_constant (XEXP (varop, 0),
count / BITS_PER_UNIT));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (varop);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (varop);
MEM_COPY_ATTRIBUTES (new, varop);
varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND
: ZERO_EXTEND, mode, new);
count = 0;
@ -9066,18 +9092,14 @@ simplify_shift_const (x, code, result_mode, varop, count)
PNOTES is a pointer to a location where any REG_UNUSED notes added for
the CLOBBERs are placed.
PADDED_SCRATCHES is set to the number of (clobber (scratch)) patterns
we had to add.
The value is the final insn code from the pattern ultimately matched,
or -1. */
static int
recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
recog_for_combine (pnewpat, insn, pnotes)
rtx *pnewpat;
rtx insn;
rtx *pnotes;
int *padded_scratches;
{
register rtx pat = *pnewpat;
int insn_code_number;
@ -9085,8 +9107,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
int i;
rtx notes = 0;
*padded_scratches = 0;
/* If PAT is a PARALLEL, check to see if it contains the CLOBBER
we use to indicate that something didn't match. If we find such a
thing, force rejection. */
@ -9148,8 +9168,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches)
if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
&& ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
return -1;
else if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == SCRATCH)
(*padded_scratches)++;
notes = gen_rtx_EXPR_LIST (REG_UNUSED,
XEXP (XVECEXP (newpat, 0, i), 0), notes);
}
@ -9243,8 +9261,7 @@ gen_lowpart_for_combine (mode, x)
}
new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
MEM_COPY_ATTRIBUTES (new, x);
return new;
}
@ -9279,7 +9296,7 @@ gen_lowpart_for_combine (mode, x)
static rtx
gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...))
{
#ifndef __STDC__
#ifndef ANSI_PROTOTYPES
enum rtx_code code;
enum machine_mode mode;
#endif
@ -9293,7 +9310,7 @@ gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...))
VA_START (p, mode);
#ifndef __STDC__
#ifndef ANSI_PROTOTYPES
code = va_arg (p, enum rtx_code);
mode = va_arg (p, enum machine_mode);
#endif
@ -9553,7 +9570,7 @@ simplify_comparison (code, pop0, pop1)
for (tmode = GET_CLASS_NARROWEST_MODE
(GET_MODE_CLASS (GET_MODE (op0)));
tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
if (c0 == GET_MODE_MASK (tmode))
if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
{
op0 = gen_lowpart_for_combine (tmode, inner_op0);
op1 = gen_lowpart_for_combine (tmode, inner_op1);
@ -9628,7 +9645,7 @@ simplify_comparison (code, pop0, pop1)
|| code == LT || code == LTU)
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& exact_log2 (const_op) >= 0
&& nonzero_bits (op0, mode) == const_op)
&& nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op)
{
code = (code == EQ || code == GE || code == GEU ? NE : EQ);
op1 = const0_rtx, const_op = 0;
@ -9820,12 +9837,16 @@ simplify_comparison (code, pop0, pop1)
&& (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
{
if (BITS_BIG_ENDIAN)
{
#ifdef HAVE_extzv
i = (GET_MODE_BITSIZE
(insn_operand_mode[(int) CODE_FOR_extzv][1]) - 1 - i);
mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
if (mode == VOIDmode)
mode = word_mode;
i = (GET_MODE_BITSIZE (mode) - 1 - i);
#else
i = BITS_PER_WORD - 1 - i;
i = BITS_PER_WORD - 1 - i;
#endif
}
op0 = XEXP (op0, 2);
op1 = GEN_INT (i);
@ -9953,7 +9974,7 @@ simplify_comparison (code, pop0, pop1)
&& (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
<= HOST_BITS_PER_WIDE_INT)
&& ((unsigned HOST_WIDE_INT) const_op
< (((HOST_WIDE_INT) 1
< (((unsigned HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1)))))
{
op0 = XEXP (op0, 0);
@ -9977,7 +9998,7 @@ simplify_comparison (code, pop0, pop1)
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
&& (- INTVAL (XEXP (SUBREG_REG (op0), 1))
< GET_MODE_MASK (mode) / 2)
< (HOST_WIDE_INT)(GET_MODE_MASK (mode) / 2))
&& (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
&& (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
GET_MODE (SUBREG_REG (op0)))
@ -10181,7 +10202,7 @@ simplify_comparison (code, pop0, pop1)
&& GET_CODE (XEXP (op0, 1)) == CONST_INT
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
== (HOST_WIDE_INT) 1 << (mode_width - 1)))
== (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
{
op0 = XEXP (op0, 0);
code = (code == EQ ? GE : LT);
@ -10232,8 +10253,8 @@ simplify_comparison (code, pop0, pop1)
&& (INTVAL (XEXP (op0, 1)) & ~ mask) == 0
&& 0 == (~ GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
& INTVAL (XEXP (op0, 1)))
&& INTVAL (XEXP (op0, 1)) != mask
&& (INTVAL (XEXP (op0, 1))
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
&& ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
!= GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
{
@ -11012,7 +11033,7 @@ reg_dead_at_p (reg, insn)
else
{
for (block = 0; block < n_basic_blocks; block++)
if (insn == basic_block_head[block])
if (insn == BLOCK_HEAD (block))
break;
if (block == n_basic_blocks)
@ -11020,7 +11041,7 @@ reg_dead_at_p (reg, insn)
}
for (i = reg_dead_regno; i < reg_dead_endregno; i++)
if (REGNO_REG_SET_P (basic_block_live_at_start[block], i))
if (REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start, i))
return 0;
return 1;
@ -11413,6 +11434,17 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
place = i3;
break;
case REG_EH_REGION:
/* This note must remain with the call. It should not be possible
for both I2 and I3 to be a call. */
if (GET_CODE (i3) == CALL_INSN)
place = i3;
else if (i2 && GET_CODE (i2) == CALL_INSN)
place = i2;
else
abort ();
break;
case REG_UNUSED:
/* Any clobbers for i3 may still exist, and so we must process
REG_UNUSED notes from that insn.
@ -11476,7 +11508,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
case REG_INC:
case REG_NO_CONFLICT:
case REG_LABEL:
/* These notes say something about how a register is used. They must
be present on any use of the register in I2 or I3. */
if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
@ -11491,6 +11522,30 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
}
break;
case REG_LABEL:
/* This can show up in several ways -- either directly in the
pattern, or hidden off in the constant pool with (or without?)
a REG_EQUAL note. */
/* ??? Ignore the without-reg_equal-note problem for now. */
if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
|| ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX))
&& GET_CODE (XEXP (tem, 0)) == LABEL_REF
&& XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))
place = i3;
if (i2
&& (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
|| ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX))
&& GET_CODE (XEXP (tem, 0)) == LABEL_REF
&& XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))))
{
if (place)
place2 = i2;
else
place = i2;
}
break;
case REG_WAS_0:
/* It is too much trouble to try to see if this note is still
correct in all situations. It is better to simply delete it. */
@ -11578,6 +11633,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
{
rtx set = single_set (tem);
rtx inner_dest = 0;
#ifdef HAVE_cc0
rtx cc0_setter = NULL_RTX;
#endif
if (set != 0)
for (inner_dest = SET_DEST (set);
@ -11588,10 +11646,21 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
;
/* Verify that it was the set, and not a clobber that
modified the register. */
modified the register.
CC0 targets must be careful to maintain setter/user
pairs. If we cannot delete the setter due to side
effects, mark the user with an UNUSED note instead
of deleting it. */
if (set != 0 && ! side_effects_p (SET_SRC (set))
&& rtx_equal_p (XEXP (note, 0), inner_dest))
&& rtx_equal_p (XEXP (note, 0), inner_dest)
#ifdef HAVE_cc0
&& (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
|| ((cc0_setter = prev_cc0_setter (tem)) != NULL
&& sets_cc0_p (PATTERN (cc0_setter)) > 0))
#endif
)
{
/* Move the notes and links of TEM elsewhere.
This might delete other dead insns recursively.
@ -11607,6 +11676,23 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
PUT_CODE (tem, NOTE);
NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (tem) = 0;
#ifdef HAVE_cc0
/* Delete the setter too. */
if (cc0_setter)
{
PATTERN (cc0_setter) = pc_rtx;
distribute_notes (REG_NOTES (cc0_setter),
cc0_setter, cc0_setter,
NULL_RTX, NULL_RTX, NULL_RTX);
distribute_links (LOG_LINKS (cc0_setter));
PUT_CODE (cc0_setter, NOTE);
NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (cc0_setter) = 0;
}
#endif
}
/* If the register is both set and used here, put the
REG_DEAD note here, but place a REG_UNUSED note
@ -11672,9 +11758,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
tem);
/* If this insn was emitted between blocks, then update
basic_block_head of the current block to include it. */
if (basic_block_end[this_basic_block - 1] == tem)
basic_block_head[this_basic_block] = place;
BLOCK_HEAD of the current block to include it. */
if (BLOCK_END (this_basic_block - 1) == tem)
BLOCK_HEAD (this_basic_block) = place;
}
}
@ -11873,7 +11959,7 @@ distribute_links (links)
for (insn = NEXT_INSN (XEXP (link, 0));
(insn && (this_basic_block == n_basic_blocks - 1
|| basic_block_head[this_basic_block + 1] != insn));
|| BLOCK_HEAD (this_basic_block + 1) != insn));
insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
&& reg_overlap_mentioned_p (reg, PATTERN (insn)))
@ -11935,7 +12021,7 @@ void
dump_combine_stats (file)
FILE *file;
{
fprintf
fnotice
(file,
";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
combine_attempts, combine_merges, combine_extras, combine_successes);
@ -11945,7 +12031,7 @@ void
dump_combine_total_stats (file)
FILE *file;
{
fprintf
fnotice
(file,
"\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
total_attempts, total_merges, total_extras, total_successes);

View File

@ -1,10 +1,22 @@
/* config.in. Generated automatically from configure.in by autoheader. */
/* Define if you can safely include both <string.h> and <strings.h>. */
#undef STRING_WITH_STRINGS
/* Define if printf supports "%p". */
#undef HAVE_PRINTF_PTR
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
/* Define to 1 if NLS is requested. */
#undef ENABLE_NLS
/* Define as 1 if you have catgets and don't want to use GNU gettext. */
#undef HAVE_CATGETS
/* Define as 1 if you have gettext and don't want to use GNU gettext. */
#undef HAVE_GETTEXT
/* Define if your cpp understands the stringify operator. */
#undef HAVE_CPP_STRINGIFY
@ -18,9 +30,22 @@
/* Define if your assembler supports .balign and .p2align. */
#undef HAVE_GAS_BALIGN_AND_P2ALIGN
/* Define if your assembler supports .subsection and .subsection -1 starts
emitting at the beginning of your section */
#undef HAVE_GAS_SUBSECTION_ORDERING
/* Define if your assembler uses the old HImode fild and fist notation. */
#undef HAVE_GAS_FILDS_FISTS
/* Define if you have a working <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define if your locale.h file contains LC_MESSAGES. */
#undef HAVE_LC_MESSAGES
/* Define as 1 if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Whether malloc must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_MALLOC
@ -54,6 +79,9 @@
/* Whether atol must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOL
/* Whether atof must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_ATOF
/* Whether sbrk must be declared even if <stdlib.h> is included. */
#undef NEED_DECLARATION_SBRK
@ -63,6 +91,12 @@
/* Whether strerror must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRERROR
/* Whether strsignal must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRSIGNAL
/* Whether strstr must be declared even if <string.h> is included. */
#undef NEED_DECLARATION_STRSTR
/* Whether getcwd must be declared even if <unistd.h> is included. */
#undef NEED_DECLARATION_GETCWD
@ -75,15 +109,79 @@
/* Whether setrlimit must be declared even if <sys/resource.h> is included. */
#undef NEED_DECLARATION_SETRLIMIT
/* Define if you want expensive run-time checks. */
#undef ENABLE_CHECKING
/* Whether putc_unlocked must be declared even if <stdio.h> is included. */
#undef NEED_DECLARATION_PUTC_UNLOCKED
/* Whether fputs_unlocked must be declared even if <stdio.h> is included. */
#undef NEED_DECLARATION_FPUTS_UNLOCKED
/* Define to enable the use of a default assembler. */
#undef DEFAULT_ASSEMBLER
/* Define to enable the use of a default linker. */
#undef DEFAULT_LINKER
/* Define if host mkdir takes a single argument. */
#undef MKDIR_TAKES_ONE_ARG
/* Define to the name of the distribution. */
#undef PACKAGE
/* Define to the version of the distribution. */
#undef VERSION
/* Define if using alloca.c. */
#undef C_ALLOCA
/* Define to empty if the keyword does not work. */
#undef const
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
#undef CRAY_STACKSEG_END
/* Define if you have alloca, as a function or macro. */
#undef HAVE_ALLOCA
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define if you have <vfork.h>. */
#undef HAVE_VFORK_H
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef pid_t
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#undef STACK_DIRECTION
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
@ -93,6 +191,18 @@
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define vfork as fork if vfork does not work. */
#undef vfork
/* Define if you have the __argz_count function. */
#undef HAVE___ARGZ_COUNT
/* Define if you have the __argz_next function. */
#undef HAVE___ARGZ_NEXT
/* Define if you have the __argz_stringify function. */
#undef HAVE___ARGZ_STRINGIFY
/* Define if you have the atoll function. */
#undef HAVE_ATOLL
@ -111,6 +221,21 @@
/* Define if you have the bzero function. */
#undef HAVE_BZERO
/* Define if you have the dcgettext function. */
#undef HAVE_DCGETTEXT
/* Define if you have the fputc_unlocked function. */
#undef HAVE_FPUTC_UNLOCKED
/* Define if you have the fputs_unlocked function. */
#undef HAVE_FPUTS_UNLOCKED
/* Define if you have the getcwd function. */
#undef HAVE_GETCWD
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the getrlimit function. */
#undef HAVE_GETRLIMIT
@ -126,39 +251,78 @@
/* Define if you have the kill function. */
#undef HAVE_KILL
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP
/* Define if you have the popen function. */
#undef HAVE_POPEN
/* Define if you have the putc_unlocked function. */
#undef HAVE_PUTC_UNLOCKED
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the rindex function. */
#undef HAVE_RINDEX
/* Define if you have the setenv function. */
#undef HAVE_SETENV
/* Define if you have the setlocale function. */
#undef HAVE_SETLOCALE
/* Define if you have the setrlimit function. */
#undef HAVE_SETRLIMIT
/* Define if you have the stpcpy function. */
#undef HAVE_STPCPY
/* Define if you have the strcasecmp function. */
#undef HAVE_STRCASECMP
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the strdup function. */
#undef HAVE_STRDUP
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strrchr function. */
#undef HAVE_STRRCHR
/* Define if you have the strsignal function. */
#undef HAVE_STRSIGNAL
/* Define if you have the strtoul function. */
#undef HAVE_STRTOUL
/* Define if you have the sysconf function. */
#undef HAVE_SYSCONF
/* Define if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define if you have the <direct.h> header file. */
#undef HAVE_DIRECT_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define if you have the <nl_types.h> header file. */
#undef HAVE_NL_TYPES_H
/* Define if you have the <stab.h> header file. */
#undef HAVE_STAB_H
@ -183,20 +347,20 @@
/* Define if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <sys/times.h> header file. */
#undef HAVE_SYS_TIMES_H
/* Define if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <wait.h> header file. */
#undef HAVE_WAIT_H
/* Define if you have the i library (-li). */
#undef HAVE_LIBI

View File

@ -0,0 +1,252 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha
running Windows/NT.
Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
Donn Terry, Softway Systems, Inc.
From code
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
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.
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. */
/* cpp handles __STDC__ */
/* The three "Alpha" defines on the first such line are from the CLAXP spec */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES " \
-D__INTERIX \
-D__OPENNT \
-D__Alpha_AXP -D_M_ALPHA -D_ALPHA_ \
-D__alpha -D__alpha__\
-D__stdcall= \
-D__cdecl= \
-Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(alpha) -Amachine(alpha)"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
-remap \
%{posix:-D_POSIX_SOURCE} \
-idirafter %$INTERIX_ROOT/usr/include"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (alpha Interix)");
/* alpha.h sets this, but it doesn't apply to us */
#undef OBJECT_FORMAT_ECOFF
#undef OBJECT_FORMAT_COFF
/* LINK_SPEC */
/* MD_STARTFILE_PREFIX */
/* ASM_OUTPUT_LOOP_ALIGN; ASM_OUTPUT_ALIGN_CODE */
/* Codegen macro overrides for NT internal conventions */
/* the below are ecoff specific... we don't need them, so
undef them (they'll get a default later) */
#undef PUT_SDB_BLOCK_START
#undef PUT_SDB_BLOCK_END
/* the following are OSF linker (not gld) specific... we don't want them */
#undef HAS_INIT_SECTION
#undef LD_INIT_SWITCH
#undef LD_FINI_SWITCH
/* The following are needed for C++, but also needed for profiling */
/* Support const sections and the ctors and dtors sections for g++.
Note that there appears to be two different ways to support const
sections at the moment. You can either #define the symbol
READONLY_DATA_SECTION (giving it some code which switches to the
readonly data section) or else you can #define the symbols
EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and
SELECT_RTX_SECTION. We do both here just to be on the safe side. */
#define USE_CONST_SECTION 1
#define CONST_SECTION_ASM_OP ".rdata"
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
Note that we want to give these sections the SHF_WRITE attribute
because these sections will actually contain data (i.e. tables of
addresses of functions in the current root executable or shared library
file) and, in the case of a shared library, the relocatable addresses
will have to be properly resolved/relocated (and then written into) by
the dynamic linker when it actually attaches the given shared library
to the executing process. (Note that on SVR4, you may wish to use the
`-z text' option to the ELF linker, when building a shared library, as
an additional check that you are doing everything right. But if you do
use the `-z text' option when building a shared library, you will get
errors unless the .ctors and .dtors sections are marked as writable
via the SHF_WRITE attribute.) */
#define CTORS_SECTION_ASM_OP ".ctors"
#define DTORS_SECTION_ASM_OP ".dtors"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
should override this definition in the target-specific file which
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
definition in the target-specific file which includes this file. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CONST_SECTION_FUNCTION \
CTORS_SECTION_FUNCTION \
DTORS_SECTION_FUNCTION
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION() const_section ()
extern void text_section ();
#define CONST_SECTION_FUNCTION \
void \
const_section () \
{ \
if (!USE_CONST_SECTION) \
text_section(); \
else if (in_section != in_const) \
{ \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \
in_section = in_const; \
} \
}
#define CTORS_SECTION_FUNCTION \
void \
ctors_section () \
{ \
if (in_section != in_ctors) \
{ \
fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
in_section = in_ctors; \
} \
}
#define DTORS_SECTION_FUNCTION \
void \
dtors_section () \
{ \
if (in_section != in_dtors) \
{ \
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
in_section = in_dtors; \
} \
}
#define INT_ASM_OP ".long"
/* A C statement (sans semicolon) to output an element in the table of
global constructors. */
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* A C statement (sans semicolon) to output an element in the table of
global destructors. */
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* The linker will take care of this, and having them causes problems with
ld -r (specifically -rU). */
#define CTOR_LISTS_DEFINED_EXTERNALLY 1
#define SET_ASM_OP ".set"
/* Output a definition (implements alias) */
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do \
{ \
fprintf ((FILE), "\t"); \
assemble_name (FILE, LABEL1); \
fprintf (FILE, "="); \
assemble_name (FILE, LABEL2); \
fprintf (FILE, "\n"); \
} \
while (0)
/* We use the defaults, so undef the null definitions */
#undef PUT_SDB_FUNCTION_START
#undef PUT_SDB_FUNCTION_END
#undef PUT_SDB_EPILOGUE_END
#define HOST_PTR_PRINTF "%p"
#define HOST_PTR_AS_INT unsigned long
#define PCC_BITFIELD_TYPE_MATTERS 1
#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec)
#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
/* DWARF2 Unwinding doesn't work with exception handling yet. */
#undef DWARF2_UNWIND_INFO
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
On NT (according to the spec) anything except strings/array that fits
in 64 bits is returned in the registers (this appears to differ from
the rest of the Alpha family). */
#undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \
(TREE_CODE (TYPE) == ARRAY_TYPE || int_size_in_bytes(TYPE) > 8)
#define ASM_LOAD_ADDR(loc, reg) " lda " #reg "," #loc "\n"
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
{ \
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
fprintf (FILE, "\t.set noat\n"); \
fprintf (FILE, "\t.globl\t__fltused\n"); \
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
/* The current Interix assembler (consistent with the DEC documentation)
uses a=b NOT .set a,b; .set is for assembler options. */
#undef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
#define ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL(FILE, SY, HI, LO) \
do { \
assemble_name (FILE, SY); \
fputc ('=', FILE); \
assemble_name (FILE, HI); \
fputc ('-', FILE); \
assemble_name (FILE, LO); \
} while (0)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@ -95,73 +95,76 @@ extern enum alpha_fp_trap_mode alpha_fptm;
/* This means that floating-point support exists in the target implementation
of the Alpha architecture. This is usually the default. */
#define MASK_FP 1
#define MASK_FP (1 << 0)
#define TARGET_FP (target_flags & MASK_FP)
/* This means that floating-point registers are allowed to be used. Note
that Alpha implementations without FP operations are required to
provide the FP registers. */
#define MASK_FPREGS 2
#define MASK_FPREGS (1 << 1)
#define TARGET_FPREGS (target_flags & MASK_FPREGS)
/* This means that gas is used to process the assembler file. */
#define MASK_GAS 4
#define MASK_GAS (1 << 2)
#define TARGET_GAS (target_flags & MASK_GAS)
/* This means that we should mark procedures as IEEE conformant. */
#define MASK_IEEE_CONFORMANT 8
#define MASK_IEEE_CONFORMANT (1 << 3)
#define TARGET_IEEE_CONFORMANT (target_flags & MASK_IEEE_CONFORMANT)
/* This means we should be IEEE-compliant except for inexact. */
#define MASK_IEEE 16
#define MASK_IEEE (1 << 4)
#define TARGET_IEEE (target_flags & MASK_IEEE)
/* This means we should be fully IEEE-compliant. */
#define MASK_IEEE_WITH_INEXACT 32
#define MASK_IEEE_WITH_INEXACT (1 << 5)
#define TARGET_IEEE_WITH_INEXACT (target_flags & MASK_IEEE_WITH_INEXACT)
/* This means we must construct all constants rather than emitting
them as literal data. */
#define MASK_BUILD_CONSTANTS 128
#define MASK_BUILD_CONSTANTS (1 << 6)
#define TARGET_BUILD_CONSTANTS (target_flags & MASK_BUILD_CONSTANTS)
/* This means we handle floating points in VAX F- (float)
or G- (double) Format. */
#define MASK_FLOAT_VAX 512
#define MASK_FLOAT_VAX (1 << 7)
#define TARGET_FLOAT_VAX (target_flags & MASK_FLOAT_VAX)
/* This means that the processor has byte and half word loads and stores
(the BWX extension). */
#define MASK_BWX 1024
#define MASK_BWX (1 << 8)
#define TARGET_BWX (target_flags & MASK_BWX)
/* This means that the processor has the CIX extension. */
#define MASK_CIX 2048
#define TARGET_CIX (target_flags & MASK_CIX)
/* This means that the processor has the MAX extension. */
#define MASK_MAX 4096
#define MASK_MAX (1 << 9)
#define TARGET_MAX (target_flags & MASK_MAX)
/* This means that the processor has the FIX extension. */
#define MASK_FIX (1 << 10)
#define TARGET_FIX (target_flags & MASK_FIX)
/* This means that the processor has the CIX extension. */
#define MASK_CIX (1 << 11)
#define TARGET_CIX (target_flags & MASK_CIX)
/* This means that the processor is an EV5, EV56, or PCA56. This is defined
only in TARGET_CPU_DEFAULT. */
#define MASK_CPU_EV5 8192
#define MASK_CPU_EV5 (1 << 28)
/* Likewise for EV6. */
#define MASK_CPU_EV6 16384
#define MASK_CPU_EV6 (1 << 29)
/* This means we support the .arch directive in the assembler. Only
defined in TARGET_CPU_DEFAULT. */
#define MASK_SUPPORT_ARCH 32768
#define MASK_SUPPORT_ARCH (1 << 30)
#define TARGET_SUPPORT_ARCH (target_flags & MASK_SUPPORT_ARCH)
/* These are for target os support and cannot be changed at runtime. */
@ -185,26 +188,32 @@ extern enum alpha_fp_trap_mode alpha_fptm;
where VALUE is the bits to set or minus the bits to clear.
An empty string NAME is used to identify the default VALUE. */
#define TARGET_SWITCHES \
{ {"no-soft-float", MASK_FP}, \
{"soft-float", - MASK_FP}, \
{"fp-regs", MASK_FPREGS}, \
{"no-fp-regs", - (MASK_FP|MASK_FPREGS)}, \
{"alpha-as", -MASK_GAS}, \
{"gas", MASK_GAS}, \
{"ieee-conformant", MASK_IEEE_CONFORMANT}, \
{"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT}, \
{"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT}, \
{"build-constants", MASK_BUILD_CONSTANTS}, \
{"float-vax", MASK_FLOAT_VAX}, \
{"float-ieee", -MASK_FLOAT_VAX}, \
{"bwx", MASK_BWX}, \
{"no-bwx", -MASK_BWX}, \
{"cix", MASK_CIX}, \
{"no-cix", -MASK_CIX}, \
{"max", MASK_MAX}, \
{"no-max", -MASK_MAX}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} }
#define TARGET_SWITCHES \
{ {"no-soft-float", MASK_FP, "Use hardware fp"}, \
{"soft-float", - MASK_FP, "Do not use hardware fp"}, \
{"fp-regs", MASK_FPREGS, "Use fp registers"}, \
{"no-fp-regs", - (MASK_FP|MASK_FPREGS), "Do not use fp registers"}, \
{"alpha-as", -MASK_GAS, "Do not assume GAS"}, \
{"gas", MASK_GAS, "Assume GAS"}, \
{"ieee-conformant", MASK_IEEE_CONFORMANT, \
"Request IEEE-conformant math library routines (OSF/1)"}, \
{"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT, \
"Emit IEEE-conformant code, without inexact exceptions"}, \
{"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \
"Emit IEEE-conformant code, with inexact exceptions"}, \
{"build-constants", MASK_BUILD_CONSTANTS, \
"Do not emit complex integer constants to read-only memory"}, \
{"float-vax", MASK_FLOAT_VAX, "Use VAX fp"}, \
{"float-ieee", -MASK_FLOAT_VAX, "Do not use VAX fp"}, \
{"bwx", MASK_BWX, "Emit code for the byte/word ISA extension"}, \
{"no-bwx", -MASK_BWX, ""}, \
{"max", MASK_MAX, "Emit code for the motion video ISA extension"}, \
{"no-max", -MASK_MAX, ""}, \
{"fix", MASK_FIX, "Emit code for the fp move and sqrt ISA extension"}, \
{"no-fix", -MASK_FIX, ""}, \
{"cix", MASK_CIX, "Emit code for the counting ISA extension"}, \
{"no-cix", -MASK_CIX, ""}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} }
#define TARGET_DEFAULT MASK_FP|MASK_FPREGS
@ -229,19 +238,24 @@ extern enum alpha_fp_trap_mode alpha_fptm;
extern char *m88k_short_data;
#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
extern char *alpha_cpu_string; /* For -mcpu= */
extern char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
extern char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
extern char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
extern char *alpha_mlat_string; /* For -mmemory-latency= */
extern const char *alpha_cpu_string; /* For -mcpu= */
extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
extern const char *alpha_mlat_string; /* For -mmemory-latency= */
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string}, \
{"fp-rounding-mode=", &alpha_fprm_string}, \
{"fp-trap-mode=", &alpha_fptm_string}, \
{"trap-precision=", &alpha_tp_string}, \
{"memory-latency=", &alpha_mlat_string}, \
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string, \
"Generate code for a given CPU"}, \
{"fp-rounding-mode=", &alpha_fprm_string, \
"Control the generated fp rounding mode"}, \
{"fp-trap-mode=", &alpha_fptm_string, \
"Control the IEEE trap mode"}, \
{"trap-precision=", &alpha_tp_string, \
"Control the precision given to fp exceptions"}, \
{"memory-latency=", &alpha_mlat_string, \
"Tune expected memory latency"}, \
}
/* Attempt to describe CPU characteristics to the preprocessor. */
@ -249,6 +263,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */
/* Corresponding to amask... */
#define CPP_AM_BWX_SPEC "-D__alpha_bwx__ -Acpu(bwx)"
#define CPP_AM_MAX_SPEC "-D__alpha_max__ -Acpu(max)"
#define CPP_AM_FIX_SPEC "-D__alpha_fix__ -Acpu(fix)"
#define CPP_AM_CIX_SPEC "-D__alpha_cix__ -Acpu(cix)"
/* Corresponding to implver... */
@ -261,7 +276,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */
#define CPP_CPU_EV5_SPEC "%(cpp_im_ev5)"
#define CPP_CPU_EV56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx)"
#define CPP_CPU_PCA56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx) %(cpp_am_max)"
#define CPP_CPU_EV6_SPEC "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_cix)"
#define CPP_CPU_EV6_SPEC "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix)"
#ifndef CPP_CPU_DEFAULT_SPEC
# if TARGET_CPU_DEFAULT & MASK_CPU_EV6
@ -311,6 +326,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */
#define EXTRA_SPECS \
{ "cpp_am_bwx", CPP_AM_BWX_SPEC }, \
{ "cpp_am_max", CPP_AM_MAX_SPEC }, \
{ "cpp_am_fix", CPP_AM_FIX_SPEC }, \
{ "cpp_am_cix", CPP_AM_CIX_SPEC }, \
{ "cpp_im_ev4", CPP_IM_EV4_SPEC }, \
{ "cpp_im_ev5", CPP_IM_EV5_SPEC }, \
@ -483,7 +499,7 @@ extern void override_options ();
Alpha we'll get better performance by aligning on an octaword
boundary. */
#define ALIGN_LABEL_AFTER_BARRIER(FILE) \
#define LABEL_ALIGN_AFTER_BARRIER(FILE) \
(optimize > 0 && write_symbols != SDB_DEBUG ? 4 : 0)
/* No data type wants to be aligned rounder than this. */
@ -613,17 +629,20 @@ extern void override_options ();
registers can hold 32-bit and 64-bit integers as well, but not 16-bit
or 8-bit values. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO) < 32 || ((MODE) != QImode && (MODE) != HImode))
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO) >= 32 && (REGNO) <= 62 \
? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
: 1)
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */
/* A C expression that is nonzero if a value of mode
MODE1 is accessible in mode MODE2 without copying.
This asymmetric test is true when MODE1 could be put
in an FP register but MODE2 could not. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
((MODE1) == QImode || (MODE1) == HImode \
? (MODE2) == QImode || (MODE2) == HImode \
(HARD_REGNO_MODE_OK (32, (MODE1)) \
? HARD_REGNO_MODE_OK (32, (MODE2)) \
: 1)
/* Specify the registers used for certain standard purposes.
@ -771,11 +790,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
'S' is a 6-bit constant (valid for a shift insn). */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) != AND \
((C) == 'Q' ? normal_memory_operand (OP, VOIDmode) \
: (C) == 'R' ? current_file_function_operand (OP, Pmode) \
: (C) == 'S' ? (GET_CODE (OP) == CONST_INT \
&& (unsigned HOST_WIDE_INT) INTVAL (OP) < 64) \
: 0)
extern int normal_memory_operand ();
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
@ -807,7 +827,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
&& (((CLASS) == FLOAT_REGS \
&& ((MODE) == SImode || (MODE) == HImode || (MODE) == QImode)) \
|| (((MODE) == QImode || (MODE) == HImode) \
&& ! TARGET_BWX && unaligned_memory_operand (IN, MODE)))) \
&& ! TARGET_BWX && ! aligned_memory_operand (IN, MODE)))) \
? GENERAL_REGS \
: ((CLASS) == FLOAT_REGS && GET_CODE (IN) == MEM \
&& GET_CODE (XEXP (IN, 0)) == AND) ? GENERAL_REGS \
@ -835,10 +855,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
: NO_REGS)
/* If we are copying between general and FP registers, we need a memory
location unless the CIX extension is available. */
location unless the FIX extension is available. */
#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
(! TARGET_CIX && (CLASS1) != (CLASS2))
(! TARGET_FIX && (CLASS1) != (CLASS2))
/* Specify the mode to be used for memory when a secondary memory
location is needed. If MODE is floating-point, use it. Otherwise,
@ -871,7 +891,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
(((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS) \
? 2 \
: TARGET_CIX ? 3 : 4+2*alpha_memory_latency)
: TARGET_FIX ? 3 : 4+2*alpha_memory_latency)
/* A C expressions returning the cost of moving data of MODE from a register to
or from memory.
@ -989,26 +1009,25 @@ extern int alpha_memory_latency;
On Alpha the value is found in $0 for integer functions and
$f0 for floating-point functions. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx (REG, \
((INTEGRAL_TYPE_P (VALTYPE) \
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE)) \
? word_mode : TYPE_MODE (VALTYPE), \
((TARGET_FPREGS \
&& (TREE_CODE (VALTYPE) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
? 32 : 0))
#define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE)) \
? word_mode : TYPE_MODE (VALTYPE), \
((TARGET_FPREGS \
&& (TREE_CODE (VALTYPE) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
? 32 : 0))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
gen_rtx (REG, MODE, \
(TARGET_FPREGS \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
? 32 : 0))
#define LIBCALL_VALUE(MODE) \
gen_rtx_REG (MODE, \
(TARGET_FPREGS \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
? 32 : 0))
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
@ -1182,6 +1201,10 @@ extern struct rtx_def *alpha_builtin_saveregs ();
extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1;
extern int alpha_compare_fp_p;
/* Define the information needed to modify the epilogue for EH. */
extern struct rtx_def *alpha_eh_epilogue_sp_ofs;
/* Make (or fake) .linkage entry for function call.
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
extern void alpha_need_linkage ();
@ -1293,6 +1316,7 @@ do { \
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8)
extern void alpha_initialize_trampoline ();
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame.
@ -1302,6 +1326,9 @@ do { \
#define RETURN_ADDR_RTX alpha_return_addr
extern struct rtx_def *alpha_return_addr ();
/* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
/* Initialize data used by insn expanders. This is called from insn_emit,
once for every function before code is generated. */
@ -1310,11 +1337,11 @@ extern void alpha_init_expanders ();
/* Addressing modes, and classification of registers for them. */
/* #define HAVE_POST_INCREMENT */
/* #define HAVE_POST_DECREMENT */
/* #define HAVE_POST_INCREMENT 0 */
/* #define HAVE_POST_DECREMENT 0 */
/* #define HAVE_PRE_DECREMENT */
/* #define HAVE_PRE_INCREMENT */
/* #define HAVE_PRE_DECREMENT 0 */
/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@ -1365,18 +1392,32 @@ extern void alpha_init_expanders ();
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) 0
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \
(REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
/* ??? Nonzero if X is the frame pointer, or some virtual register
that may eliminate to the frame pointer. These will be allowed to
have offsets greater than 32K. This is done because register
elimination offsets will change the hi/lo split, and if we split
before reload, we will require additional instructions. */
#define REG_OK_FP_BASE_P(X) \
(REGNO (X) == 31 || REGNO (X) == 63 \
|| (REGNO (X) >= FIRST_PSEUDO_REGISTER \
&& REGNO (X) < LAST_VIRTUAL_REGISTER))
#else
/* Nonzero if X is a hard reg that can be used as an index. */
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
#define REG_OK_FP_BASE_P(X) 0
#endif
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
@ -1391,16 +1432,34 @@ extern void alpha_init_expanders ();
First define the basic valid address. */
#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \
{ if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \
goto ADDR; \
if (CONSTANT_ADDRESS_P (X)) \
goto ADDR; \
if (GET_CODE (X) == PLUS \
&& REG_P (XEXP (X, 0)) \
&& REG_OK_FOR_BASE_P (XEXP (X, 0)) \
&& CONSTANT_ADDRESS_P (XEXP (X, 1))) \
goto ADDR; \
#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \
{ \
rtx tmp = (X); \
if (GET_CODE (tmp) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (tmp)) \
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \
tmp = SUBREG_REG (tmp); \
if (REG_P (tmp) && REG_OK_FOR_BASE_P (tmp)) \
goto ADDR; \
if (CONSTANT_ADDRESS_P (X)) \
goto ADDR; \
if (GET_CODE (X) == PLUS) \
{ \
tmp = XEXP (X, 0); \
if (GET_CODE (tmp) == SUBREG \
&& (GET_MODE_SIZE (GET_MODE (tmp)) \
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \
tmp = SUBREG_REG (tmp); \
if (REG_P (tmp)) \
{ \
if (REG_OK_FP_BASE_P (tmp) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT) \
goto ADDR; \
if (REG_OK_FOR_BASE_P (tmp) \
&& CONSTANT_ADDRESS_P (XEXP (X, 1))) \
goto ADDR; \
} \
} \
}
/* Now accept the simple address, or, for DImode only, an AND of a simple
@ -1596,9 +1655,11 @@ do { \
#define MOVE_MAX 8
/* Controls how many units are moved by expr.c before resorting to movstr.
Without byte/word accesses, we want no more than one; with, several single
byte accesses are better. */
/* If a memory-to-memory move would take MOVE_RATIO or more simple
move-instruction pairs, we will do a movstr or libcall instead.
Without byte/word accesses, we want no more than four instructions;
with, several single byte accesses are better. */
#define MOVE_RATIO (TARGET_BWX ? 7 : 2)
@ -1693,6 +1754,12 @@ do { \
/* The EV4 is dual issue; EV5/EV6 are quad issue. */
#define ISSUE_RATE (alpha_cpu == PROCESSOR_EV4 ? 2 : 4)
/* Describe the fact that MULTI instructions are multiple instructions
and so to assume they don't pair with anything. */
#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
if (recog_memoized (INSN) < 0 || get_attr_type (INSN) == TYPE_MULTI) \
(CAN_ISSUE_MORE) = 0
/* Compute the cost of computing a constant rtl expression RTX
whose rtx-code is CODE. The body of this macro is a portion
of a switch statement. If the code is computed here,
@ -1970,7 +2037,7 @@ literal_section () \
This is suitable for output with `assemble_name'. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*$%s%d", PREFIX, NUM)
sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM))
/* Check a floating-point value for validity for a particular machine mode. */
@ -2078,6 +2145,11 @@ literal_section () \
} \
while (0)
/* To get unaligned data, we have to turn off auto alignment. */
#define UNALIGNED_SHORT_ASM_OP ".align 0\n\t.word"
#define UNALIGNED_INT_ASM_OP ".align 0\n\t.long"
#define UNALIGNED_DOUBLE_INT_ASM_OP ".align 0\n\t.quad"
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
@ -2237,41 +2309,22 @@ do { \
/* Print a memory address as an operand to reference that memory location. */
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
{ rtx addr = (ADDR); \
int basereg = 31; \
HOST_WIDE_INT offset = 0; \
\
if (GET_CODE (addr) == AND) \
addr = XEXP (addr, 0); \
\
if (GET_CODE (addr) == REG) \
basereg = REGNO (addr); \
else if (GET_CODE (addr) == CONST_INT) \
offset = INTVAL (addr); \
else if (GET_CODE (addr) == PLUS \
&& GET_CODE (XEXP (addr, 0)) == REG \
&& GET_CODE (XEXP (addr, 1)) == CONST_INT) \
basereg = REGNO (XEXP (addr, 0)), offset = INTVAL (XEXP (addr, 1)); \
else \
abort (); \
\
fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, offset); \
fprintf (FILE, "($%d)", basereg); \
}
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
print_operand_address((FILE), (ADDR))
/* Define the codes that are matched by predicates in alpha.c. */
#define PREDICATE_CODES \
{"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"cint8_operand", {CONST_INT, CONSTANT_P_RTX}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"sext_add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \
{"cint8_operand", {CONST_INT}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \
{"sext_add_operand", {SUBREG, REG, CONST_INT}}, \
{"const48_operand", {CONST_INT}}, \
{"and_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"or_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"or_operand", {SUBREG, REG, CONST_INT}}, \
{"mode_mask_operand", {CONST_INT}}, \
{"mul8_operand", {CONST_INT}}, \
{"mode_width_operand", {CONST_INT}}, \
@ -2284,14 +2337,16 @@ do { \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"call_operand", {REG, SYMBOL_REF}}, \
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \
SYMBOL_REF, CONST, LABEL_REF}}, \
{"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \
SYMBOL_REF, CONST, LABEL_REF}}, \
{"aligned_memory_operand", {MEM}}, \
{"unaligned_memory_operand", {MEM}}, \
{"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \
{"any_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}},
{"hard_fp_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
{"reg_no_subreg_operand", {REG}},
/* Tell collect that the object format is ECOFF. */
#define OBJECT_FORMAT_COFF
@ -2462,6 +2517,7 @@ extern int current_file_function_operand ();
extern int alpha_sa_size ();
extern int alpha_adjust_cost ();
extern void print_operand ();
extern void print_operand_address ();
extern int reg_or_0_operand ();
extern int reg_or_8bit_operand ();
extern int mul8_operand ();
@ -2482,6 +2538,7 @@ extern int divmod_operator ();
extern int call_operand ();
extern int reg_or_cint_operand ();
extern int hard_fp_register_operand ();
extern int reg_not_elim_operand ();
extern void alpha_set_memflags ();
extern int aligned_memory_operand ();
extern void get_aligned_mem ();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha
running Windows/NT.
Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
Derived from code
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
Donn Terry, Softway Systems, Inc.
This file contains the code-generation stuff common to the 32-bit
versions of the DEC/Compaq Alpha architecture. It is shared by
Interix and NT/Win32 ports. It should not contain compile-time
or run-time dependent environment values (such as compiler options
or anything containing a file or pathname.)
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.
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. */
#undef TARGET_WINDOWS_NT
#define TARGET_WINDOWS_NT 1
/* WinNT (and thus Interix) use unsigned int */
#define SIZE_TYPE "unsigned int"
/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
#undef POINTER_SIZE
#define POINTER_SIZE 32
#define POINTERS_EXTEND_UNSIGNED 0
/* We don't change Pmode to the "obvious" SI mode... the above appears
to affect the in-memory size; we want the registers to stay DImode
to match the md file */
/* "long" is 32 bits. */
#undef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE 32
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts.
The trampoline should set the static chain pointer to value placed
into the trampoline and should branch to the specified routine. */
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) \
{ \
fprintf (FILE, "\tbr $27,$LTRAMPP\n"); \
fprintf (FILE, "$LTRAMPP:\n\tldl $1,12($27)\n"); \
fprintf (FILE, "\tldl $27,16($27)\n"); \
fprintf (FILE, "\tjmp $31,($27),0\n"); \
fprintf (FILE, "\t.long 0,0\n"); \
}
/* Length in units of the trampoline for entering a nested function. */
#undef TRAMPOLINE_SIZE
#define TRAMPOLINE_SIZE 24
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
#undef INITIALIZE_TRAMPOLINE
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 20, 16, 12)
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
#undef ASM_OUTPUT_MI_THUNK
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
do { \
char *op, *fn_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0); \
int reg; \
\
/* Mark end of prologue. */ \
output_end_prologue (FILE); \
\
/* Rely on the assembler to macro expand a large delta. */ \
reg = aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) ? 17 : 16; \
fprintf (FILE, "\tlda $%d,%ld($%d)\n", reg, (long)(DELTA), reg); \
\
op = "jsr"; \
if (current_file_function_operand (XEXP (DECL_RTL (FUNCTION), 0))) \
op = "br"; \
fprintf (FILE, "\t%s $31,", op); \
assemble_name (FILE, fn_name); \
fputc ('\n', FILE); \
} while (0)

View File

@ -50,6 +50,8 @@ __CTOR_LIST__:
__DTOR_LIST__:
.quad -1
.section .eh_frame,"aw"
__EH_FRAME_BEGIN__:
#
# Fragment of the ELF _fini routine that invokes our dtor cleanup.
@ -67,10 +69,25 @@ __DTOR_LIST__:
1: ldgp $29,0($29)
jsr $26,__do_global_dtors_aux
# Ideally this call would go in crtend.o, except that we can't
# get hold of __EH_FRAME_BEGIN__ there.
jsr $26,__do_frame_takedown
# Must match the alignment we got from crti.o else we get
# zero-filled holes in our _fini function and then SIGILL.
.align 3
#
# Fragment of the ELF _init routine that sets up the frame info.
#
.section .init,"ax"
br $29,1f
1: ldgp $29,0($29)
jsr $26,__do_frame_setup
.align 3
#
# Invoke our destructors in order.
#
@ -78,7 +95,7 @@ __DTOR_LIST__:
.data
# Support recursive calls to exit.
9: .quad __DTOR_LIST__
$ptr: .quad __DTOR_LIST__
.text
@ -86,15 +103,14 @@ __DTOR_LIST__:
.ent __do_global_dtors_aux
__do_global_dtors_aux:
ldgp $29,0($27)
lda $30,-16($30)
.frame $30,16,$26,0
stq $9,8($30)
stq $26,0($30)
.mask 0x4000200,-16
.prologue 1
.prologue 0
lda $9,9b
lda $9,$ptr
br 1f
0: stq $1,0($9)
jsr $26,($27)
@ -109,3 +125,68 @@ __do_global_dtors_aux:
ret
.end __do_global_dtors_aux
#
# Install our frame info.
#
# ??? How can we rationally keep this size correct?
.section .bss
.type $object,@object
.align 3
$object:
.zero 48
.size $object, 48
.text
.align 3
.ent __do_frame_setup
__do_frame_setup:
ldgp $29,0($27)
lda $30,-16($30)
.frame $30,16,$26,0
stq $26,0($30)
.mask 0x4000000,-16
.prologue 1
lda $1,__register_frame_info
beq $1,0f
lda $16,__EH_FRAME_BEGIN__
lda $17,$object
jsr $26,__register_frame_info
ldq $26,0($30)
0: lda $30,16($30)
ret
.end __do_frame_setup
#
# Remove our frame info.
#
.align 3
.ent __do_frame_takedown
__do_frame_takedown:
ldgp $29,0($27)
lda $30,-16($30)
.frame $30,16,$26,0
stq $26,0($30)
.mask 0x4000000,-16
.prologue 1
lda $1,__deregister_frame_info
beq $1,0f
lda $16,__EH_FRAME_BEGIN__
jsr $26,__deregister_frame_info
ldq $26,0($30)
0: lda $30,16($30)
ret
.end __do_frame_takedown
.weak __register_frame_info
.weak __deregister_frame_info

View File

@ -50,6 +50,9 @@ __CTOR_END__:
__DTOR_END__:
.quad 0
.section .eh_frame,"aw"
__FRAME_END__:
.quad 0
#
# Fragment of the ELF _init routine that invokes our ctor startup

View File

@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF.
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@tamu.edu).
This file is part of GNU CC.
@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */
#define OBJECT_FORMAT_ELF
#define DBX_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
@ -34,7 +35,7 @@ Boston, MA 02111-1307, USA. */
#define CC1_SPEC "%{G*}"
#undef ASM_SPEC
#define ASM_SPEC "%{G*} %{relax:-relax}"
#define ASM_SPEC "%{G*} %{relax:-relax} %{gdwarf*:-no-mdebug}"
#undef LINK_SPEC
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
@ -49,18 +50,21 @@ Boston, MA 02111-1307, USA. */
/* Output at beginning of assembler file. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
{ \
alpha_write_verstamp (FILE); \
output_file_directive (FILE, main_input_filename); \
do { \
if (write_symbols != DWARF2_DEBUG) \
{ \
alpha_write_verstamp (FILE); \
output_file_directive (FILE, main_input_filename); \
} \
fprintf (FILE, "\t.set noat\n"); \
fprintf (FILE, "\t.set noreorder\n"); \
if (TARGET_BWX | TARGET_MAX | TARGET_CIX) \
fprintf (FILE, "\t.set noreorder\n"); \
if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
{ \
fprintf (FILE, "\t.arch %s\n", \
(alpha_cpu == PROCESSOR_EV6 ? "ev6" \
: TARGET_MAX ? "pca56" : "ev56")); \
} \
}
} while (0)
extern void output_file_directive ();
@ -79,8 +83,9 @@ extern void output_file_directive ();
#else
#define ASM_FILE_END(FILE) \
do { \
fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
IDENT_ASM_OP, version_string); \
if (!flag_no_ident) \
fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
IDENT_ASM_OP, version_string); \
} while (0)
#endif
@ -434,20 +439,23 @@ void FN () \
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
&& !size_directive_output) \
{ \
size_directive_output = 1; \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, name); \
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
} \
} while (0)
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
&& !size_directive_output) \
{ \
size_directive_output = 1; \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, name); \
putc (',', FILE); \
fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, \
int_size_in_bytes (TREE_TYPE (DECL))); \
putc ('\n', FILE); \
} \
} while (0)
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
@ -518,3 +526,9 @@ do { \
/* We support #pragma. */
#define HANDLE_SYSV_PRAGMA
/* Undo the auto-alignment stuff from alpha.h. ELF has unaligned data
pseudos natively. */
#undef UNALIGNED_SHORT_ASM_OP
#undef UNALIGNED_INT_ASM_OP
#undef UNALIGNED_DOUBLE_INT_ASM_OP

View File

@ -0,0 +1,325 @@
/* DEC Alpha division and remainder support.
Copyright (C) 1994, 1999 Free Software Foundation, Inc.
This file 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 with other programs, and to distribute
those programs 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 another program.)
This file 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 this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* This had to be written in assembler because the division functions
use a non-standard calling convention.
This file provides an implementation of __divqu, __divq, __divlu,
__divl, __remqu, __remq, __remlu and __reml. CPP macros control
the exact operation.
Operation performed: $27 := $24 o $25, clobber $28, return address to
caller in $23, where o one of the operations.
The following macros need to be defined:
SIZE, the number of bits, 32 or 64.
TYPE, either UNSIGNED or SIGNED
OPERATION, either DIVISION or REMAINDER
SPECIAL_CALLING_CONVENTION, 0 or 1. It is useful for debugging to
define this to 0. That removes the `__' prefix to make the function
name not collide with the existing libc.a names, and uses the
standard Alpha procedure calling convention.
*/
#ifndef SPECIAL_CALLING_CONVENTION
#define SPECIAL_CALLING_CONVENTION 1
#endif
#ifdef L_divl
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __divl
#else
#define FUNCTION_NAME divl
#endif
#define SIZE 32
#define TYPE SIGNED
#define OPERATION DIVISION
#endif
#ifdef L_divlu
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __divlu
#else
#define FUNCTION_NAME divlu
#endif
#define SIZE 32
#define TYPE UNSIGNED
#define OPERATION DIVISION
#endif
#ifdef L_divq
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __divq
#else
#define FUNCTION_NAME divq
#endif
#define SIZE 64
#define TYPE SIGNED
#define OPERATION DIVISION
#endif
#ifdef L_divqu
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __divqu
#else
#define FUNCTION_NAME divqu
#endif
#define SIZE 64
#define TYPE UNSIGNED
#define OPERATION DIVISION
#endif
#ifdef L_reml
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __reml
#else
#define FUNCTION_NAME reml
#endif
#define SIZE 32
#define TYPE SIGNED
#define OPERATION REMAINDER
#endif
#ifdef L_remlu
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __remlu
#else
#define FUNCTION_NAME remlu
#endif
#define SIZE 32
#define TYPE UNSIGNED
#define OPERATION REMAINDER
#endif
#ifdef L_remq
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __remq
#else
#define FUNCTION_NAME remq
#endif
#define SIZE 64
#define TYPE SIGNED
#define OPERATION REMAINDER
#endif
#ifdef L_remqu
#if SPECIAL_CALLING_CONVENTION
#define FUNCTION_NAME __remqu
#else
#define FUNCTION_NAME remqu
#endif
#define SIZE 64
#define TYPE UNSIGNED
#define OPERATION REMAINDER
#endif
#define tmp0 $3
#define tmp1 $28
#define cnt $1
#define result_sign $2
#if SPECIAL_CALLING_CONVENTION
#define N $24
#define D $25
#define Q RETREG
#define RETREG $27
#else
#define N $16
#define D $17
#define Q RETREG
#define RETREG $0
#endif
/* Misc symbols to make alpha assembler easier to read. */
#define zero $31
#define sp $30
/* Symbols to make interface nicer. */
#define UNSIGNED 0
#define SIGNED 1
#define DIVISION 0
#define REMAINDER 1
.set noreorder
.set noat
.text
.align 3
.globl FUNCTION_NAME
.ent FUNCTION_NAME
FUNCTION_NAME:
.frame $30,0,$26,0
.prologue 0
/* Under the special calling convention, we have to preserve all register
values but $23 and $28. */
#if SPECIAL_CALLING_CONVENTION
lda sp,-64(sp)
#if OPERATION == DIVISION
stq N,0(sp)
#endif
stq D,8(sp)
stq cnt,16(sp)
stq result_sign,24(sp)
stq tmp0,32(sp)
#endif
/* If we are computing the remainder, move N to the register that is used
for the return value, and redefine what register is used for N. */
#if OPERATION == REMAINDER
bis N,N,RETREG
#undef N
#define N RETREG
#endif
/* Perform conversion from 32 bit types to 64 bit types. */
#if SIZE == 32
#if TYPE == SIGNED
/* If there are problems with the signed case, add these instructions.
The caller should already have done this.
addl N,0,N # sign extend N
addl D,0,D # sign extend D
*/
#else /* UNSIGNED */
zap N,0xf0,N # zero extend N (caller required to sign extend)
zap D,0xf0,D # zero extend D
#endif
#endif
/* Check for divide by zero. */
bne D,$34
lda $16,-2(zero)
call_pal 0xaa
$34:
#if TYPE == SIGNED
#if OPERATION == DIVISION
xor N,D,result_sign
#else
bis N,N,result_sign
#endif
/* Get the absolute values of N and D. */
subq zero,N,tmp0
cmovlt N,tmp0,N
subq zero,D,tmp0
cmovlt D,tmp0,D
#endif
/* Compute CNT = ceil(log2(N)) - ceil(log2(D)). This is the number of
divide iterations we will have to perform. Should you wish to optimize
this, check a few bits at a time, preferably using zap/zapnot. Be
careful though, this code runs fast fro the most common cases, when the
quotient is small. */
bge N,$35
bis zero,1,cnt
blt D,$40
.align 3
$39: addq D,D,D
addl cnt,1,cnt
bge D,$39
br zero,$40
$35: cmpult N,D,tmp0
bis zero,zero,cnt
bne tmp0,$42
.align 3
$44: addq D,D,D
cmpult N,D,tmp0
addl cnt,1,cnt
beq tmp0,$44
$42: srl D,1,D
$40:
subl cnt,1,cnt
/* Actual divide. Could be optimized with unrolling. */
#if OPERATION == DIVISION
bis zero,zero,Q
#endif
blt cnt,$46
.align 3
$49: cmpule D,N,tmp1
subq N,D,tmp0
srl D,1,D
subl cnt,1,cnt
cmovne tmp1,tmp0,N
#if OPERATION == DIVISION
addq Q,Q,Q
bis Q,tmp1,Q
#endif
bge cnt,$49
$46:
/* The result is now in RETREG. NOTE! It was written to RETREG using
either N or Q as a synonym! */
/* Change the sign of the result as needed. */
#if TYPE == SIGNED
subq zero,RETREG,tmp0
cmovlt result_sign,tmp0,RETREG
#endif
/* Restore clobbered registers. */
#if SPECIAL_CALLING_CONVENTION
#if OPERATION == DIVISION
ldq N,0(sp)
#endif
ldq D,8(sp)
ldq cnt,16(sp)
ldq result_sign,24(sp)
ldq tmp0,32(sp)
lda sp,64(sp)
#endif
/* Sign extend an *unsigned* 32 bit result, as required by the Alpha
conventions. */
#if TYPE == UNSIGNED && SIZE == 32
/* This could be avoided by adding some CPP hair to the divide loop.
It is probably not worth the added complexity. */
addl RETREG,0,RETREG
#endif
#if SPECIAL_CALLING_CONVENTION
ret zero,($23),1
#else
ret zero,($26),1
#endif
.end FUNCTION_NAME

View File

@ -17,13 +17,14 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ECOFF)");
#undef SUB_CPP_PREDEFINES
#define SUB_CPP_PREDEFINES "-D__ECOFF__"
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "-D__ECOFF__"
#undef LINK_SPEC
#define LINK_SPEC "-G 8 %{O*:-O3} %{!O*:-O1}"

View File

@ -17,7 +17,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ELF)");

View File

@ -17,14 +17,16 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-Dlinux -Dunix -Asystem(linux) -D_LONGLONG -D__alpha__ " SUB_CPP_PREDEFINES
"-Dlinux -Dunix -Asystem(linux) -D_LONGLONG -D__alpha__ " \
SUB_CPP_PREDEFINES
#undef LIB_SPEC
#define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}"

View File

@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Alpha NetBSD/ELF)");

View File

@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS)

View File

@ -30,9 +30,19 @@ Boston, MA 02111-1307, USA. */
-Dunix -D__osf__ -D_LONGLONG -DSYSTYPE_BSD \
-D_SYSTYPE_BSD -Asystem(unix) -Asystem(xpg4)"
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
instead of PTHREAD_USE_D4 since both have the same effect and the former
doesn't invade the users' namespace. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC \
"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}"
/* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */
#define LIB_SPEC "%{p:-lprof1 -lpdf} %{pg:-lprof1 -lpdf} %{a:-lprof2} -lc"
#define LIB_SPEC \
"%{p|pg:-lprof1%{pthread|threads:_r} -lpdf} %{a:-lprof2} \
%{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc"
/* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are
optimizing, -O1 if we are not. Pass -shared, -non_shared or

View File

@ -0,0 +1,6 @@
# All alphas get an IEEE complaint set of libraries.
MULTILIB_OPTIONS = mieee
MULTILIB_DIRNAMES = ieee
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib

View File

@ -0,0 +1,16 @@
# t-interix
# System headers will track gcc's needs.
# Even LANG_EXTRA_HEADERS may be temporary.
USER_H=$(LANG_EXTRA_HEADERS)
# We don't want this one either.
INSTALL_ASSERT_H=
CROSS_LIBGCC1 = libgcc1-asm.a
LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = alpha/lib1funcs.asm
LIB1ASMFUNCS = _divqu _divq _divlu _divl _remqu _remq _remlu _reml

View File

@ -439,10 +439,6 @@ extern int vms_valid_decl_attribute_p ();
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
fprintf (FILE, "\t.align %d\n", LOG);
#define UNALIGNED_SHORT_ASM_OP ".word"
#define UNALIGNED_INT_ASM_OP ".long"
#define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
#define ASM_OUTPUT_SECTION(FILE,SECTION) \
(strcmp (SECTION, ".text") == 0) \
? text_section () \

View File

@ -36,11 +36,11 @@ Boston, MA 02111-1307, USA. */
#undef LIB_SPEC
#define LIB_SPEC ""
/* VxWorks uses object files, not loadable images. make linker just
combine objects. */
/* VxWorks uses object files, not loadable images. Make linker just combine
objects. Also show using 32 bit mode and set start of text to 0. */
#undef LINK_SPEC
#define LINK_SPEC "-r"
#define LINK_SPEC "-r -taso -T 0"
/* VxWorks provides the functionality of crt0.o and friends itself. */

View File

@ -0,0 +1,45 @@
/* Configuration for GNU compiler
for an DEC/Compaq Alpha
Copyright (C) 1999 Free Software Foundation, Inc.
Donn Terry, Softway Systems, Inc.
derived from code by Douglas B. Rupp (drupp@cs.washington.edu)
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.
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. */
#include <alpha/xm-alpha.h>
#undef HOST_BITS_PER_LONG
#define HOST_BITS_PER_LONG 32
#define HOST_BITS_PER_WIDE_INT 64
#ifdef __GNUC__
# define HOST_WIDE_INT long long
#else
# define HOST_WIDE_INT __int64
#endif
#define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
#ifdef __GNUC__
# define HOST_WIDEST_INT long long
#else
# define HOST_WIDEST_INT __int64
#endif
#define HOST_WIDEST_INT_PRINT_DEC "%lld"
#define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu"
#define HOST_WIDEST_INT_PRINT_HEX "0x%llx"

View File

@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA. */
#if defined(__GNUC__) && !defined(USE_C_ALLOCA)
#define alloca __builtin_alloca
#else
#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS)
#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS) && !defined(__INTERIX)
#include <alloca.h>
#else
extern void *alloca ();

View File

@ -49,8 +49,8 @@ Boston, MA 02111-1307, USA. */
#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
fprintf (FILE, \
"\t.text\n\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO)
asm_fprintf (FILE, \
"\t.text\n\t.stabs \"\",%d,0,0,%LLetext\n%LLetext:\n", N_SO)
/* Like block addresses, stabs line numbers are relative to the
current function. */

109
contrib/gcc/config/dbxelf.h Normal file
View File

@ -0,0 +1,109 @@
/* Definitions needed when using stabs embedded in ELF sections.
Copyright (C) 1999 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.
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. */
/* This file may be included by any ELF target which wishes to
support -gstabs generating stabs in sections, as produced by gas
and understood by gdb. */
#ifndef __DBX_ELF_H
#define __DBX_ELF_H
/* Output DBX (stabs) debugging information if doing -gstabs. */
#undef DBX_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO
/* Make LBRAC and RBRAC addresses relative to the start of the
function. The native Solaris stabs debugging format works this
way, gdb expects it, and it reduces the number of relocation
entries... */
#undef DBX_BLOCKS_FUNCTION_RELATIVE
#define DBX_BLOCKS_FUNCTION_RELATIVE 1
/* ... but, to make this work, functions must appear prior to line info. */
#undef DBX_FUNCTION_FIRST
#define DBX_FUNCTION_FIRST
/* When generating stabs debugging, use N_BINCL entries. */
#undef DBX_USE_BINCL
#define DBX_USE_BINCL
/* There is no limit to the length of stabs strings. */
#ifndef DBX_CONTIN_LENGTH
#define DBX_CONTIN_LENGTH 0
#endif
/* When using stabs, gcc2_compiled must be a stabs entry, not an
ordinary symbol, or gdb won't see it. Furthermore, since gdb reads
the input piecemeal, starting with each N_SO, it's a lot easier if
the gcc2 flag symbol is *after* the N_SO rather than before it. So
we emit an N_OPT stab there. */
#define ASM_IDENTIFY_GCC(FILE) \
do \
{ \
if (write_symbols != DBX_DEBUG) \
fputs ("gcc2_compiled.:\n", FILE); \
} \
while (0)
#define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) \
do \
{ \
if (write_symbols == DBX_DEBUG) \
fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \
} \
while (0)
/* Like block addresses, stabs line numbers are relative to the
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
do \
{ \
static int sym_lineno = 1; \
char temp[256]; \
ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
fprintf (FILE, ".stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
putc ('-', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
sym_lineno += 1; \
} \
while (0)
/* Generate a blank trailing N_SO to mark the end of the .o file, since
we can't depend upon the linker to mark .o file boundaries with
embedded stabs. */
#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
asm_fprintf (FILE, \
"\t.text\n\t.stabs \"\",%d,0,0,%LLetext\n%LLetext:\n", N_SO)
#endif /* __DBX_ELF_H */

704
contrib/gcc/config/elfos.h Normal file
View File

@ -0,0 +1,704 @@
/* elfos.h -- operating system specific defines to be used when
targeting GCC for some generic ELF system
Copyright (C) 1991, 1994, 1995, 1999 Free Software Foundation, Inc.
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
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.
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. */
/* For the sake of libgcc2.c, indicate target supports atexit. */
#define HAVE_ATEXIT
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend.o%s"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared: \
%{!symbolic: \
%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}\
crtbegin.o%s"
/* Attach a special .ident directive to the end of the file to identify
the version of GCC which compiled this code. The format of the
.ident string is patterned after the ones produced by native svr4
C compilers. */
#define IDENT_ASM_OP ".ident"
#define ASM_FILE_END(FILE) \
do { \
if (!flag_no_ident) \
fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \
IDENT_ASM_OP, version_string); \
} while (0)
/* Output #ident as a .ident. */
#define ASM_OUTPUT_IDENT(FILE, NAME) \
fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
/* Use periods rather than dollar signs in special g++ assembler names. */
#define NO_DOLLAR_IN_LABEL
/* Writing `int' for a bitfield forces int alignment for the structure. */
#define PCC_BITFIELD_TYPE_MATTERS 1
/* Implicit library calls should use memcpy, not bcopy, etc. */
#define TARGET_MEM_FUNCTIONS
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA
/* System V Release 4 uses DWARF debugging info. */
#define DWARF_DEBUGGING_INFO
/* All ELF targets can support DWARF-2. */
#define DWARF2_DEBUGGING_INFO
/* Also allow them to support STABS debugging. */
#include "dbxelf.h"
/* The GNU tools operate better with stabs. Since we don't have
any native tools to be compatible with, default to stabs. */
#ifndef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#endif
#undef ASM_BYTE_OP
#define ASM_BYTE_OP ".byte"
#undef SET_ASM_OP
#define SET_ASM_OP ".set"
/* This is how to begin an assembly language file. Most svr4 assemblers want
at least a .file directive to come first, and some want to see a .version
directive come right after that. Here we just establish a default
which generates only the .file directive. If you need a .version
directive for any specific target, you should override this definition
in the target-specific file which includes this one. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
output_file_directive ((FILE), main_input_filename)
/* This is how to allocate empty space in some section. The .zero
pseudo-op is used for this on most svr4 assemblers. */
#define SKIP_ASM_OP ".zero"
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE))
/* This is how to output a reference to a user-level label named NAME.
`assemble_name' uses this.
For System V Release 4 the convention is *not* to prepend a leading
underscore onto user-level symbol names. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME)
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
For most svr4 systems, the convention is that any symbol which begins
with a period is not put into the linker symbol table by the assembler. */
#undef ASM_OUTPUT_INTERNAL_LABEL
#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
do { \
fprintf (FILE, ".%s%d:\n", PREFIX, NUM); \
} while (0)
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
This is suitable for output with `assemble_name'.
For most svr4 systems, the convention is that any symbol which begins
with a period is not put into the linker symbol table by the assembler. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \
do { \
sprintf (LABEL, "*.%s%d", PREFIX, NUM); \
} while (0)
/* Output the label which precedes a jumptable. Note that for all svr4
systems where we actually generate jumptables (which is to say every
svr4 target except i386, where we use casesi instead) we put the jump-
tables into the .rodata section and since other stuff could have been
put into the .rodata section prior to any given jumptable, we have to
make sure that the location counter for the .rodata section gets pro-
perly re-aligned prior to the actual beginning of the jump table. */
#define ALIGN_ASM_OP ".align"
#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
ASM_OUTPUT_ALIGN ((FILE), 2);
#endif
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,JUMPTABLE) \
do { \
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
} while (0)
/* The standard SVR4 assembler seems to require that certain builtin
library routines (e.g. .udiv) be explicitly declared as .globl
in each assembly file where they are referenced. */
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
/* This says how to output assembler code to declare an
uninitialized external linkage data object. Under SVR4,
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#define COMMON_ASM_OP ".comm"
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
do { \
fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
/* This says how to output assembler code to declare an
uninitialized internal linkage data object. Under SVR4,
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#define LOCAL_ASM_OP ".local"
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), "\n"); \
ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \
} while (0)
/* This is the pseudo-op used to generate a 32-bit word of data with a
specific value in some section. This is the same for all known svr4
assemblers. */
#define INT_ASM_OP ".long"
/* This is the pseudo-op used to generate a contiguous sequence of byte
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */
#undef ASCII_DATA_ASM_OP
#define ASCII_DATA_ASM_OP ".ascii"
/* Support const sections and the ctors and dtors sections for g++.
Note that there appears to be two different ways to support const
sections at the moment. You can either #define the symbol
READONLY_DATA_SECTION (giving it some code which switches to the
readonly data section) or else you can #define the symbols
EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and
SELECT_RTX_SECTION. We do both here just to be on the safe side. */
#define USE_CONST_SECTION 1
#define CONST_SECTION_ASM_OP ".section\t.rodata"
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
Note that we want to give these sections the SHF_WRITE attribute
because these sections will actually contain data (i.e. tables of
addresses of functions in the current root executable or shared library
file) and, in the case of a shared library, the relocatable addresses
will have to be properly resolved/relocated (and then written into) by
the dynamic linker when it actually attaches the given shared library
to the executing process. (Note that on SVR4, you may wish to use the
`-z text' option to the ELF linker, when building a shared library, as
an additional check that you are doing everything right. But if you do
use the `-z text' option when building a shared library, you will get
errors unless the .ctors and .dtors sections are marked as writable
via the SHF_WRITE attribute.) */
#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
/* On svr4, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let
crtstuff.c and other files know this by defining the following symbols.
The definitions say how to change sections to the .init and .fini
sections. This is the same for all known svr4 assemblers. */
#define INIT_SECTION_ASM_OP ".section\t.init"
#define FINI_SECTION_ASM_OP ".section\t.fini"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
should override this definition in the target-specific file which
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
definition in the target-specific file which includes this file. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CONST_SECTION_FUNCTION \
CTORS_SECTION_FUNCTION \
DTORS_SECTION_FUNCTION
#define READONLY_DATA_SECTION() const_section ()
extern void text_section ();
#define CONST_SECTION_FUNCTION \
void \
const_section () \
{ \
if (!USE_CONST_SECTION) \
text_section(); \
else if (in_section != in_const) \
{ \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \
in_section = in_const; \
} \
}
#define CTORS_SECTION_FUNCTION \
void \
ctors_section () \
{ \
if (in_section != in_ctors) \
{ \
fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
in_section = in_ctors; \
} \
}
#define DTORS_SECTION_FUNCTION \
void \
dtors_section () \
{ \
if (in_section != in_dtors) \
{ \
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
in_section = in_dtors; \
} \
}
/* Switch into a generic section.
This is currently only used to support section attributes. */
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
do { \
static struct section_info \
{ \
struct section_info *next; \
char *name; \
enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
} *sections; \
struct section_info *s; \
char *mode; \
enum sect_enum type; \
\
for (s = sections; s; s = s->next) \
if (!strcmp (NAME, s->name)) \
break; \
\
if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
type = SECT_EXEC, mode = "ax"; \
else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
type = SECT_RO, mode = "a"; \
else \
type = SECT_RW, mode = "aw"; \
\
if (s == 0) \
{ \
s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
strcpy (s->name, NAME); \
s->type = type; \
s->next = sections; \
sections = s; \
fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode); \
} \
else \
{ \
if (DECL && s->type != type) \
error_with_decl (DECL, "%s causes a section type conflict"); \
\
fprintf (FILE, ".section\t%s\n", NAME); \
} \
} while (0)
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
#define UNIQUE_SECTION(DECL,RELOC) \
do { \
int len; \
char *name, *string, *prefix; \
\
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
\
if (! DECL_ONE_ONLY (DECL)) \
{ \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
prefix = ".text."; \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \
prefix = ".rodata."; \
else \
prefix = ".data."; \
} \
else if (TREE_CODE (DECL) == FUNCTION_DECL) \
prefix = ".gnu.linkonce.t."; \
else if (DECL_READONLY_SECTION (DECL, RELOC)) \
prefix = ".gnu.linkonce.r."; \
else \
prefix = ".gnu.linkonce.d."; \
\
len = strlen (name) + strlen (prefix); \
string = alloca (len + 1); \
sprintf (string, "%s%s", prefix, name); \
\
DECL_SECTION_NAME (DECL) = build_string (len, string); \
} while (0)
/* A C statement (sans semicolon) to output an element in the table of
global constructors. */
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* A C statement (sans semicolon) to output an element in the table of
global destructors. */
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
the initial value of DECL requires link-time relocations. */
#define SELECT_SECTION(DECL,RELOC) \
{ \
if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (! flag_writable_strings) \
const_section (); \
else \
data_section (); \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if ((flag_pic && RELOC) \
|| !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
|| !DECL_INITIAL (DECL) \
|| (DECL_INITIAL (DECL) != error_mark_node \
&& !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
data_section (); \
else \
const_section (); \
} \
else \
const_section (); \
}
/* A C statement or statements to switch to the appropriate
section for output of RTX in mode MODE. RTX is some kind
of constant in RTL. The argument MODE is redundant except
in the case of a `const_int' rtx. Currently, these always
go into the const section. */
#undef SELECT_RTX_SECTION
#define SELECT_RTX_SECTION(MODE,RTX) const_section()
/* Define the strings used for the special svr4 .type and .size directives.
These strings generally do not vary from one system running svr4 to
another, but if a given system (e.g. m88k running svr) needs to use
different pseudo-op names for these, they may be overridden in the
file which includes this one. */
#define TYPE_ASM_OP ".type"
#define SIZE_ASM_OP ".size"
/* This is how we tell the assembler that a symbol is weak. */
#define ASM_WEAKEN_LABEL(FILE,NAME) \
do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
fputc ('\n', FILE); } while (0)
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
expect various different forms for this operand. The one given here
is just a default. You may need to override it in your machine-
specific tm.h file (depending upon the particulars of your assembler). */
#define TYPE_OPERAND_FMT "@%s"
/* Write the extra assembler code needed to declare a function's result.
Most svr4 assemblers don't require any special declaration of the
result value, but there are exceptions. */
#ifndef ASM_DECLARE_RESULT
#define ASM_DECLARE_RESULT(FILE, RESULT)
#endif
/* These macros generate the special .type and .size directives which
are used to set the corresponding fields of the linker symbol table
entries in an ELF object file under SVR4. These macros also output
the starting labels for the relevant functions/objects. */
/* Write the extra assembler code needed to declare a function properly.
Some svr4 assemblers need to also have something extra said about the
function's return value. We allow for that here. */
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { \
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
putc ('\n', FILE); \
ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
} while (0)
/* Write the extra assembler code needed to declare an object properly. */
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
putc ('\n', FILE); \
size_directive_output = 0; \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \
{ \
size_directive_output = 1; \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
} \
ASM_OUTPUT_LABEL(FILE, NAME); \
} while (0)
/* Output the size directive for a decl in rest_of_decl_compilation
in the case where we did not do so before the initializer.
Once we find the error_mark_node, we know that the value of
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
&& DECL_INITIAL (DECL) == error_mark_node \
&& !size_directive_output) \
{ \
size_directive_output = 1; \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, name); \
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \
} \
} while (0)
/* This is how to declare the size of a function. */
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
do { \
if (!flag_inhibit_size_directive) \
{ \
char label[256]; \
static int labelno; \
labelno++; \
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
fprintf (FILE, "-"); \
assemble_name (FILE, (FNAME)); \
putc ('\n', FILE); \
} \
} while (0)
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
corresponds to a particular byte value [0..255]. For any
given byte value, if the value in the corresponding table
position is zero, the given character can be output directly.
If the table value is 1, the byte must be output as a \ooo
octal escape. If the tables value is anything else, then the
byte value should be output as a \ followed by the value
in the table. Note that we can use standard UN*X escape
sequences for many control characters, but we don't use
\a to represent BEL because some svr4 assemblers (e.g. on
the i386) don't know about that. Also, we don't use \v
since some versions of gas, such as 2.2 did not accept it. */
#define ESCAPES \
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
/* Some svr4 assemblers have a limit on the number of characters which
can appear in the operand of a .string directive. If your assembler
has such a limitation, you should define STRING_LIMIT to reflect that
limit. Note that at least some svr4 assemblers have a limit on the
actual number of bytes in the double-quoted string, and that they
count each character in an escape sequence as one byte. Thus, an
escape sequence like \377 would count as four bytes.
If your target assembler doesn't support the .string directive, you
should define this to zero.
*/
#define STRING_LIMIT ((unsigned) 256)
#define STRING_ASM_OP ".string"
/* The routine used to output NUL terminated strings. We use a special
version of this for most svr4 targets because doing so makes the
generated assembly code more compact (and thus faster to assemble)
as well as more readable, especially for targets like the i386
(where the only alternative is to output character sequences as
comma separated lists of numbers). */
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
do \
{ \
register unsigned char *_limited_str = (unsigned char *) (STR); \
register unsigned ch; \
fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \
for (; ch = *_limited_str; _limited_str++) \
{ \
register int escape; \
switch (escape = ESCAPES[ch]) \
{ \
case 0: \
putc (ch, (FILE)); \
break; \
case 1: \
fprintf ((FILE), "\\%03o", ch); \
break; \
default: \
putc ('\\', (FILE)); \
putc (escape, (FILE)); \
break; \
} \
} \
fprintf ((FILE), "\"\n"); \
} \
while (0)
/* The routine used to output sequences of byte values. We use a special
version of this for most svr4 targets because doing so makes the
generated assembly code more compact (and thus faster to assemble)
as well as more readable. Note that if we find subparts of the
character sequence which end with NUL (and which are shorter than
STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
register unsigned char *_ascii_bytes = (unsigned char *) (STR); \
register unsigned char *limit = _ascii_bytes + (LENGTH); \
register unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
register unsigned char *p; \
if (bytes_in_chunk >= 60) \
{ \
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
continue; \
if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \
{ \
if (bytes_in_chunk > 0) \
{ \
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
_ascii_bytes = p; \
} \
else \
{ \
register int escape; \
register unsigned ch; \
if (bytes_in_chunk == 0) \
fprintf ((FILE), "\t%s\t\"", ASCII_DATA_ASM_OP); \
switch (escape = ESCAPES[ch = *_ascii_bytes]) \
{ \
case 0: \
putc (ch, (FILE)); \
bytes_in_chunk++; \
break; \
case 1: \
fprintf ((FILE), "\\%03o", ch); \
bytes_in_chunk += 4; \
break; \
default: \
putc ('\\', (FILE)); \
putc (escape, (FILE)); \
bytes_in_chunk += 2; \
break; \
} \
} \
} \
if (bytes_in_chunk > 0) \
fprintf ((FILE), "\"\n"); \
} \
while (0)
/* All SVR4 targets use the ELF object file format. */
#define OBJECT_FORMAT_ELF

View File

@ -37,7 +37,7 @@
#undef FLT_MAX_10_EXP
#define FLT_MAX_10_EXP 38
#ifdef __SH3E__
#if defined (__SH3E__) || defined (__SH4_SINGLE_ONLY__)
/* Number of base-FLT_RADIX digits in the significand of a double */
#undef DBL_MANT_DIG

View File

@ -156,8 +156,8 @@ __floatsixf (){ abort(); }
#else /* !EXTENDED_FLOAT_STUBS, rest of file */
typedef SFtype __attribute__ ((mode (SF)));
typedef DFtype __attribute__ ((mode (DF)));
typedef float SFtype __attribute__ ((mode (SF)));
typedef float DFtype __attribute__ ((mode (DF)));
typedef int HItype __attribute__ ((mode (HI)));
typedef int SItype __attribute__ ((mode (SI)));
@ -460,7 +460,6 @@ pack_d ( fp_number_type * src)
else if (fraction == 0)
{
exp = 0;
sign = 0;
}
else
{
@ -735,7 +734,7 @@ _fpadd_parts (fp_number_type * a,
{
tfraction = a_fraction - b_fraction;
}
if (tfraction > 0)
if (tfraction >= 0)
{
tmp->sign = 0;
tmp->normal_exp = a_normal_exp;
@ -1000,8 +999,7 @@ multiply (FLO_type arg_a, FLO_type arg_b)
#if defined(L_div_sf) || defined(L_div_df)
static INLINE fp_number_type *
_fpdiv_parts (fp_number_type * a,
fp_number_type * b,
fp_number_type * tmp)
fp_number_type * b)
{
fractype bit;
fractype numerator;
@ -1093,13 +1091,12 @@ divide (FLO_type arg_a, FLO_type arg_b)
{
fp_number_type a;
fp_number_type b;
fp_number_type tmp;
fp_number_type *res;
unpack_d ((FLO_union_type *) & arg_a, &a);
unpack_d ((FLO_union_type *) & arg_b, &b);
res = _fpdiv_parts (&a, &b, &tmp);
res = _fpdiv_parts (&a, &b);
return pack_d (res);
}
@ -1332,7 +1329,7 @@ si_to_float (SItype arg_a)
{
/* Special case for minint, since there is no +ve integer
representation for it */
if (arg_a == 0x80000000)
if (arg_a == (SItype) 0x80000000)
{
return -2147483648.0;
}

View File

@ -1,5 +1,5 @@
/* Definitions for IBM PS2 running AIX/386.
Copyright (C) 1988, 1996 Free Software Foundation, Inc.
Copyright (C) 1988, 1996, 1998 Free Software Foundation, Inc.
Contributed by Minh Tran-Le <TRANLE@intellicorp.com>.
This file is part of GNU CC.
@ -58,9 +58,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
do { fprintf (FILE, "\t.file\t"); \
output_quoted_string (FILE, dump_base_name); \
fprintf (FILE, "\n"); \
do { output_file_directive (FILE, main_input_filename); \
if (optimize) \
ASM_FILE_START_1 (FILE); \
else \

View File

@ -49,9 +49,7 @@ Boston, MA 02111-1307, USA. */
??? I am skeptical of this -- RMS. */
#define ASM_FILE_START(FILE) \
do { fprintf (FILE, "\t.file\t"); \
output_quoted_string (FILE, dump_base_name); \
fprintf (FILE, "\n"); \
do { output_file_directive (FILE, main_input_filename); \
} while (0)
/* This was suggested, but it shouldn't be right for DBX output. -- RMS

View File

@ -3,7 +3,7 @@
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL.
Copyright (C) 1998 Free Software Foundation, Inc.
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \
-D__MINGW32__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__MINGW32__=0.2 -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
-D_stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
@ -38,5 +38,3 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{mdll:dllcrt1%O%s} %{!mdll:crt1%O%s}"
#undef MATH_LIBRARY
#define MATH_LIBRARY "-lcrtdll"

View File

@ -0,0 +1,32 @@
/* stuff needed for libgcc1 on win32. */
#ifdef L_chkstk
.global ___chkstk
.global __alloca
___chkstk:
__alloca:
pushl %ecx /* save temp */
movl %esp,%ecx /* get sp */
addl $0x8,%ecx /* and point to return addr */
probe: cmpl $0x1000,%eax /* > 4k ?*/
jb done
subl $0x1000,%ecx /* yes, move pointer down 4k*/
orl $0x0,(%ecx) /* probe there */
subl $0x1000,%eax /* decrement count */
jmp probe /* and do it again */
done: subl %eax,%ecx
orl $0x0,(%ecx) /* less that 4k, just peek here */
movl %esp,%eax
movl %ecx,%esp /* decrement stack */
movl (%eax),%ecx /* recover saved temp */
movl 4(%eax),%eax /* get return address */
jmp *%eax
#endif

View File

@ -0,0 +1,525 @@
/* Operating system specific defines to be used when targeting GCC for
hosting on Windows NT 3.x, using a Unix style C library and tools,
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
Copyright (C) 1995, 1996, 1997, 1998, 1999 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.
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. */
#define YES_UNDERSCORES
#define DBX_DEBUGGING_INFO
#define SDB_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#include "i386/gas.h"
#include "dbxcoff.h"
/* Augment TARGET_SWITCHES with the cygwin/no-cygwin options. */
#define MASK_WIN32 0x40000000 /* Use -lming32 interface */
#define MASK_CYGWIN 0x20000000 /* Use -lcygwin interface */
#define MASK_WINDOWS 0x10000000 /* Use windows interface */
#define MASK_DLL 0x08000000 /* Use dll interface */
#define MASK_NOP_FUN_DLLIMPORT 0x20000 /* Ignore dllimport for functions */
#define TARGET_WIN32 (target_flags & MASK_WIN32)
#define TARGET_CYGWIN (target_flags & MASK_CYGWIN)
#define TARGET_WINDOWS (target_flags & MASK_WINDOWS)
#define TARGET_DLL (target_flags & MASK_DLL)
#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "cygwin", MASK_CYGWIN, "Use the Cygwin interface" }, \
{ "no-cygwin", MASK_WIN32, "Use the Mingw32 interface" }, \
{ "windows", MASK_WINDOWS, "Create GUI application" }, \
{ "console", -MASK_WINDOWS, "Create console application" }, \
{ "dll", MASK_DLL, "Generate code for a DLL" }, \
{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, "Ignore dllimport for functions" }, \
{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" },
/* Support the __declspec keyword by turning them into attributes.
We currently only support: dllimport and dllexport.
Note that the current way we do this may result in a collision with
predefined attributes later on. This can be solved by using one attribute,
say __declspec__, and passing args to it. The problem with that approach
is that args are not accumulated: each new appearance would clobber any
existing args. */
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
#define CPP_PREDEFINES "-Di386 -D_WIN32 \
-DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
want to allow things to be added to it when installing new versions of
GCC without making a new CYGWIN.DLL, so we leave it. Profiling is handled
by calling the init function from the prologue. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{mdll: %{mno-cygwin:dllcrt1%O%s}} \
%{!mdll: %{!mno-cygwin:crt0%O%s} \
%{mno-cygwin:crt1%O%s} %{pg:gcrt0%O%s}}"
#undef CPP_SPEC
#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
%{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__} \
%{mno-cygwin:-iwithprefixbefore \
../../../../%(mingw_include_path)/include/mingw32 -D__MINGW32__=0.2}"
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
specification name, and a string constant that used by the GNU CC driver
program.
Do not define this macro if it does not need to do anything. */
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "mingw_include_path", DEFAULT_TARGET_MACHINE }
/* We have to dynamic link to get to the system DLLs. All of libc, libm and
the Unix stuff is in cygwin.dll. The import library is called
'libcygwin.a'. For Windows applications, include more libraries, but
always include kernel32. We'd like to specific subsystem windows to
ld, but that doesn't work just yet. */
#undef LIB_SPEC
#define LIB_SPEC "%{pg:-lgmon} \
%{!mno-cygwin:-lcygwin} \
%{mno-cygwin:-lmingw32 -lmoldname -lcrtdll} \
%{mwindows:-lgdi32 -lcomdlg32} \
-luser32 -lkernel32 -ladvapi32 -lshell32"
#define LINK_SPEC "%{mwindows:--subsystem windows} \
%{mconsole:--subsystem console} \
%{mdll:--dll -e _DllMainCRTStartup@12}"
#define SIZE_TYPE "unsigned int"
#define PTRDIFF_TYPE "int"
#define WCHAR_UNSIGNED 1
#define WCHAR_TYPE_SIZE 16
#define WCHAR_TYPE "short unsigned int"
#define HAVE_ATEXIT 1
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to DECL. */
extern int i386_pe_valid_decl_attribute_p ();
#undef VALID_MACHINE_DECL_ATTRIBUTE
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
i386_pe_valid_decl_attribute_p (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
is a valid machine specific attribute for TYPE.
The attributes in ATTRIBUTES have previously been assigned to TYPE. */
#undef VALID_MACHINE_TYPE_ATTRIBUTE
#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \
i386_pe_valid_type_attribute_p (TYPE, ATTRIBUTES, IDENTIFIER, ARGS)
extern int i386_pe_valid_type_attribute_p ();
extern union tree_node *i386_pe_merge_decl_attributes ();
#define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
i386_pe_merge_decl_attributes ((OLD), (NEW))
/* Used to implement dllexport overriding dllimport semantics. It's also used
to handle vtables - the first pass won't do anything because
DECL_CONTEXT (DECL) will be 0 so i386_pe_dll{ex,im}port_p will return 0.
It's also used to handle dllimport override semantics. */
#if 0
#define REDO_SECTION_INFO_P(DECL) \
((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \
|| (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL)))
#else
#define REDO_SECTION_INFO_P(DECL) 1
#endif
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_ctor, in_dtor, in_drectve
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CTOR_SECTION_FUNCTION \
DTOR_SECTION_FUNCTION \
DRECTVE_SECTION_FUNCTION \
SWITCH_TO_SECTION_FUNCTION
#define CTOR_SECTION_FUNCTION \
void \
ctor_section () \
{ \
if (in_section != in_ctor) \
{ \
fprintf (asm_out_file, "\t.section .ctor\n"); \
in_section = in_ctor; \
} \
}
#define DTOR_SECTION_FUNCTION \
void \
dtor_section () \
{ \
if (in_section != in_dtor) \
{ \
fprintf (asm_out_file, "\t.section .dtor\n"); \
in_section = in_dtor; \
} \
}
#define DRECTVE_SECTION_FUNCTION \
void \
drectve_section () \
{ \
if (in_section != in_drectve) \
{ \
fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
in_section = in_drectve; \
} \
}
/* Switch to SECTION (an `enum in_section').
??? This facility should be provided by GCC proper.
The problem is that we want to temporarily switch sections in
ASM_DECLARE_OBJECT_NAME and then switch back to the original section
afterwards. */
#define SWITCH_TO_SECTION_FUNCTION \
void \
switch_to_section (section, decl) \
enum in_section section; \
tree decl; \
{ \
switch (section) \
{ \
case in_text: text_section (); break; \
case in_data: data_section (); break; \
case in_named: named_section (decl, NULL, 0); break; \
case in_ctor: ctor_section (); break; \
case in_dtor: dtor_section (); break; \
case in_drectve: drectve_section (); break; \
default: abort (); break; \
} \
}
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* Don't allow flag_pic to propagate since gas may produce invalid code
otherwise. */
#undef SUBTARGET_OVERRIDE_OPTIONS
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
if (flag_pic) \
{ \
warning ("-f%s ignored for target (all code is position independent)",\
(flag_pic > 1) ? "PIC" : "pic"); \
flag_pic = 0; \
} \
} while (0) \
/* Define this macro if references to a symbol must be treated
differently depending on something about the variable or
function named by the symbol (such as what section it is in).
On i386 running Windows NT, modify the assembler name with a suffix
consisting of an atsign (@) followed by string of digits that represents
the number of bytes of arguments passed to the function, if it has the
attribute STDCALL.
In addition, we must mark dll symbols specially. Definitions of
dllexport'd objects install some info in the .drectve section.
References to dllimport'd objects are fetched indirectly via
_imp__. If both are declared, dllexport overrides. This is also
needed to implement one-only vtables: they go into their own
section and we need to set DECL_SECTION_NAME so we do that here.
Note that we can be called twice on the same decl. */
extern void i386_pe_encode_section_info ();
#ifdef ENCODE_SECTION_INFO
#undef ENCODE_SECTION_INFO
#endif
#define ENCODE_SECTION_INFO(DECL) i386_pe_encode_section_info (DECL)
/* Utility used only in this file. */
#define I386_PE_STRIP_ENCODING(SYM_NAME) \
((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
trailing @[NUM] encoded by ENCODE_SECTION_INFO. */
#undef STRIP_NAME_ENCODING
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
do { \
char *_p; \
char *_name = I386_PE_STRIP_ENCODING (SYMBOL_NAME); \
for (_p = _name; *_p && *_p != '@'; ++_p) \
; \
if (*_p == '@') \
{ \
int _len = _p - _name; \
(VAR) = (char *) alloca (_len + 1); \
strncpy ((VAR), _name, _len); \
(VAR)[_len] = '\0'; \
} \
else \
(VAR) = _name; \
} while (0)
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \
I386_PE_STRIP_ENCODING (NAME)) \
/* Output a common block. */
#undef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME); \
if (! i386_pe_dllimport_name_p (NAME)) \
{ \
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
fprintf ((STREAM), ", %d\t%s %d\n", \
(ROUNDED), ASM_COMMENT_START, (SIZE)); \
} \
} while (0)
/* Output the label for an initialized variable. */
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME); \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} while (0)
/* Emit code to check the stack when allocating more that 4000
bytes in one go. */
#define CHECK_STACK_LIMIT 4000
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387 and needs stack probes */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE)
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
/* Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
without user intervention. For instance, under Microsoft Windows
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
extern void i386_pe_unique_section ();
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
/* A C statement to output something to the assembler file to switch to section
NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
NULL_TREE. Some target formats do not support arbitrary sections. Do not
define this macro in such cases. */
#undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
do { \
static struct section_info \
{ \
struct section_info *next; \
char *name; \
enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
} *sections; \
struct section_info *s; \
char *mode; \
enum sect_enum type; \
\
for (s = sections; s; s = s->next) \
if (!strcmp (NAME, s->name)) \
break; \
\
if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
type = SECT_EXEC, mode = "x"; \
else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
type = SECT_RO, mode = ""; \
else \
type = SECT_RW, mode = "w"; \
\
if (s == 0) \
{ \
s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
strcpy (s->name, NAME); \
s->type = type; \
s->next = sections; \
sections = s; \
fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
/* Functions may have been compiled at various levels of \
optimization so we can't use `same_size' here. Instead, \
have the linker pick one. */ \
if ((DECL) && DECL_ONE_ONLY (DECL)) \
fprintf (STREAM, "\t.linkonce %s\n", \
TREE_CODE (DECL) == FUNCTION_DECL \
? "discard" : "same_size"); \
} \
else \
{ \
fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
} \
} while (0)
/* Write the extra assembler code needed to declare a function
properly. If we are generating SDB debugging information, this
will happen automatically, so we only need to handle other cases. */
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do \
{ \
if (i386_pe_dllexport_name_p (NAME)) \
i386_pe_record_exported_symbol (NAME); \
if (write_symbols != SDB_DEBUG) \
i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
ASM_OUTPUT_LABEL (FILE, NAME); \
} \
while (0)
/* Add an external function to the list of functions to be declared at
the end of the file. */
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
do \
{ \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
i386_pe_record_external_function (NAME); \
} \
while (0)
/* Declare the type properly for any external libcall. */
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
/* Output function declarations at the end of the file. */
#define ASM_FILE_END(FILE) \
i386_pe_asm_file_end (FILE)
#undef ASM_COMMENT_START
#define ASM_COMMENT_START " #"
/* DWARF2 Unwinding doesn't work with exception handling yet. */
#define DWARF2_UNWIND_INFO 0
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
#define SUBTARGET_PROLOGUE \
if (profile_flag \
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),\
"main") == 0) \
{ \
rtx xops[1]; \
xops[0] = gen_rtx_MEM (FUNCTION_MODE, \
gen_rtx (SYMBOL_REF, Pmode, "_monstartup")); \
if (do_rtl) \
emit_call_insn (gen_rtx (CALL, VOIDmode, xops[0], const0_rtx)); \
else \
output_asm_insn (AS1 (call,%P1), xops); \
}
/* External function declarations. */
#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif
#ifdef BUFSIZ /* stdio.h has been included, ok to use FILE * */
#define STDIO_PROTO(ARGS) PROTO(ARGS)
#else
#define STDIO_PROTO(ARGS) ()
#endif
extern void i386_pe_record_external_function PROTO((char *));
extern void i386_pe_declare_function_type STDIO_PROTO((FILE *, char *, int));
extern void i386_pe_record_exported_symbol PROTO((char *));
extern void i386_pe_asm_file_end STDIO_PROTO((FILE *));
/* For Win32 ABI compatibility */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 0
/* No data type wants to be aligned rounder than this. */
#undef BIGGEST_ALIGNMENT
#define BIGGEST_ALIGNMENT 128
/* A bitfield declared as `int' forces `int' alignment for the struct. */
#undef PCC_BITFIELDS_TYPE_MATTERS
#define PCC_BITFIELDS_TYPE_MATTERS 0
/* Enable alias attribute support. */
#ifndef SET_ASM_OP
#define SET_ASM_OP "\t.set"
#endif

View File

@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <time.h>
#include "i386/i386.c"
@ -29,6 +30,7 @@ struct option
char *string;
int *variable;
int on_value;
char *description;
};
static int

View File

@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* for now, we are just like the sysv4 version with a
few hacks
@ -25,7 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "i386/sysv4.h"
#ifndef VERSION_INFO2
#define VERSION_INFO2 "$Revision: 1.3 $"
#define VERSION_INFO2 "$Revision: 1.6 $"
#endif
#ifndef VERSION_STRING
@ -46,7 +47,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define MASK_NOLEGEND 0x20000000 /* Discard legend information */
#define MASK_EXTERNAL_LEGEND 0x10000000 /* Make external legends */
#define MASK_IDENTIFY_REVISION 0x08000000 /* Emit 'ident' to .s */
#define MASK_WARN_PASS_STRUCT 0x04000000 /* Emit 'ident' to .s */
#define MASK_WARN_PASS_STRUCT 0x04000000 /* Warn when structures are passed */
#define TARGET_STANDARD (target_flags & MASK_STANDARD)
#define TARGET_NOLEGEND (target_flags & MASK_NOLEGEND)
@ -56,12 +57,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "standard", MASK_STANDARD }, \
{ "legend", -MASK_NOLEGEND }, \
{ "no-legend", MASK_NOLEGEND }, \
{ "external-legend", MASK_EXTERNAL_LEGEND }, \
{ "identify-revision", MASK_IDENTIFY_REVISION }, \
{ "warn-passed-structs", MASK_WARN_PASS_STRUCT },
{ "standard", MASK_STANDARD, "Retain standard MXDB information" }, \
{ "legend", -MASK_NOLEGEND, "Retain legend information" }, \
{ "no-legend", MASK_NOLEGEND, "" }, \
{ "external-legend", MASK_EXTERNAL_LEGEND, "Generate external legend information" }, \
{ "identify-revision", MASK_IDENTIFY_REVISION, "Emit identifying info in .s file" }, \
{ "warn-passed-structs", MASK_WARN_PASS_STRUCT, "Warn when a function arg is a structure" },
#undef DWARF_DEBUGGING_INFO
#define DWARF_DEBUGGING_INFO
@ -123,7 +124,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
do { \
extern int flag_signed_bitfields; \
flag_signed_bitfields = 0; \
abort_helper (); \
optimization_options (LEVEL,SIZE); \
} while (0)
@ -219,23 +219,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#endif /* CROSS_COMPILE */
#if !defined (no_abort) || defined (CRT_BEGIN) || defined (CRT_END)
#undef abort
char insn; int insn_; char * file_; int line_;
#define abort() \
(insn_ = (int) insn, \
file_ = __FILE__, \
line_ = __LINE__, \
fancy_abort ())
#define abort_helper() \
do { \
extern void abort_aux (); \
atexit (abort_aux); \
} while (0)
#define _abort_aux
#endif /* no abort */
/* The maximum alignment which the object file format can support.
page alignment would seem to be enough */
#undef MAX_OFILE_ALIGNMENT

View File

@ -0,0 +1,41 @@
/* Configuration for an i386 running RTEMS on top of MS-DOS with
DJGPP v2.x.
Copyright (C) 1996,1999 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
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.
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. */
#include "i386/djgpp.h"
/* Specify predefined symbols in preprocessor. */
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DDJGPP=2 -DMSDOS \
-Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386) \
-Asystem(rtems)"
/* Generate calls to memcpy, memcmp and memset. */
#ifndef TARGET_MEM_FUNCTIONS
#define TARGET_MEM_FUNCTIONS
#endif
/* end of i386/djgpp-rtems.h */

View File

@ -0,0 +1,161 @@
/* Configuration for an i386 running MS-DOS with DJGPP.
Copyright (C) 1997, 1998, 1999 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.
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. */
#include "dbxcoff.h"
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
#define HANDLE_SYSV_PRAGMA
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#define YES_UNDERSCORES
#include "i386/gas.h"
/* Enable alias attribute support. */
#ifndef SET_ASM_OP
#define SET_ASM_OP "\t.set"
#endif
/* Search for as.exe and ld.exe in DJGPP's binary directory. */
#define MD_EXEC_PREFIX "$DJDIR/bin/"
/* Correctly handle absolute filename detection in cp/xref.c */
#define FILE_NAME_ABSOLUTE_P(NAME) \
(((NAME)[0] == '/') || ((NAME)[0] == '\\') || \
(((NAME)[0] >= 'A') && ((NAME)[0] <= 'z') && ((NAME)[1] == ':')))
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DDJGPP=2 -DMSDOS \
-Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)"
/* We need to override link_command_spec in gcc.c so support -Tdjgpp.djl.
This cannot be done in LINK_SPECS as that LINK_SPECS is processed
before library search directories are known by the linker.
This avoids problems when specs file is not available. An alternate way,
suggested by Robert Hoehne, is to use SUBTARGET_EXTRA_SPECS instead.
*/
#undef LINK_COMMAND_SPEC
#define LINK_COMMAND_SPEC \
"%{!fsyntax-only: \
%{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
\t%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
\t%{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
\t%{static:} %{L*} %D %o\
\t%{!nostdlib:%{!nodefaultlibs:%G %L %G}}\
\t%{!A:%{!nostdlib:%{!nostartfiles:%E}}}\
\t-Tdjgpp.djl %{T*}}}}}}}\n\
%{!c:%{!M:%{!MM:%{!E:%{!S:stubify %{v} %{o*:%*} %{!o*:a.out} }}}}}"
/* Always just link in 'libc.a'. */
#undef LIB_SPEC
#define LIB_SPEC "-lc"
/* Pick the right startup code depending on the -pg flag. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s}"
/* Make sure that gcc will not look for .h files in /usr/local/include
unless user explicitly requests it. */
#undef LOCAL_INCLUDE_DIR
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_ctor, in_dtor
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CTOR_SECTION_FUNCTION \
DTOR_SECTION_FUNCTION
#define CTOR_SECTION_FUNCTION \
void \
ctor_section () \
{ \
if (in_section != in_ctor) \
{ \
fprintf (asm_out_file, "\t.section .ctor\n"); \
in_section = in_ctor; \
} \
}
#define DTOR_SECTION_FUNCTION \
void \
dtor_section () \
{ \
if (in_section != in_dtor) \
{ \
fprintf (asm_out_file, "\t.section .dtor\n"); \
in_section = in_dtor; \
} \
}
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* Allow (eg) __attribute__((section "locked")) to work */
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)\
do { \
fprintf (FILE, "\t.section %s\n", NAME); \
} while (0)
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtor_section (); \
fprintf (FILE, "%s\t", ASM_LONG); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
do { \
output_file_directive (FILE, main_input_filename); \
} while (0)
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
if ((LOG) != 0) fprintf ((FILE), "\t.p2align %d\n", LOG)
/* djgpp has atexit (). */
#undef HAVE_ATEXIT
#define HAVE_ATEXIT
/* djgpp automatically calls its own version of __main, so don't define one
in libgcc, nor call one in main(). */
#define HAS_INIT_SECTION

View File

@ -3,6 +3,7 @@
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
Adapted from GNU/Linux version by John Polstra.
Continued development by David O'Brien <obrien@freebsd.org>
This file is part of GNU CC.
@ -34,6 +35,23 @@ Boston, MA 02111-1307, USA. */
libraries compiled with the native cc, so undef it. */
#undef NO_DOLLAR_IN_LABEL
/* Use more efficient ``thunks'' to implement C++ vtables. */
#undef DEFAULT_VTABLE_THUNKS
#define DEFAULT_VTABLE_THUNKS 1
/* Override the default comment-starter of "/". */
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
#undef SET_ASM_OP
#define SET_ASM_OP ".set"
/* This is how to output an element of a case-vector that is relative.
This is only used for PIC code. See comments by the `casesi' insn in
i386.md for an explanation of the expression this outputs. */
@ -45,6 +63,10 @@ Boston, MA 02111-1307, USA. */
necessary when compiling PIC code. */
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
/* Use stabs instead of DWARF debug format. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
/* Copy this from the svr4 specifications... */
/* Define the register numbers to be used in Dwarf debugging information.
The SVR4 reference port C compiler uses the following register numbers
@ -113,23 +135,15 @@ Boston, MA 02111-1307, USA. */
: ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
: (-1))
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
/* Tell final.c that we don't need a label passed to mcount. */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
{ \
if (flag_pic) \
{ \
fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \
LPREFIX, (LABELNO)); \
fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \
} \
fprintf (FILE, "\tcall *.mcount@GOT(%%ebx)\n"); \
else \
{ \
fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \
fprintf (FILE, "\tcall mcount\n"); \
} \
fprintf (FILE, "\tcall .mcount\n"); \
}
#undef SIZE_TYPE
@ -140,6 +154,9 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_UNSIGNED
#define WCHAR_UNSIGNED 0
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
@ -150,21 +167,53 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}"
#undef LIB_SPEC
#if 1
/* We no longer link with libc_p.a or libg.a by default. If you
* want to profile or debug the C library, please add
* -lc_p or -ggdb to LDFLAGS at the link time, respectively.
*/
#define LIB_SPEC \
"%{!shared: %{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} \
%{!ggdb:-lc} %{ggdb:-lg}}"
#else
#define LIB_SPEC \
/* This defines which switch letters take arguments. On FreeBSD, most of
the normal cases (defined in gcc.c) apply, and we also have -h* and
-z* options (for the linker) (comming from svr4).
We also have -R (alias --rpath), no -z, --soname (-h), --assert etc. */
#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) \
|| (CHAR) == 'h' \
|| (CHAR) == 'z' \
|| (CHAR) == 'R')
/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add
the magical crtbegin.o file (see crtstuff.c) which provides part
of the support for getting C++ file-scope static object constructed
before entering `main'. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
#endif
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} \
%{!profile:crt1.o%s}}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
/* Provide a ENDFILE_SPEC appropriate for FreeBSD. Here we tack on
the magical crtend.o file (see crtstuff.c) which provides part of
the support for getting C++ file-scope static object constructed
before entering `main', followed by a normal "finalizer" file,
`crtn.o'. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
/* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate
libc, depending on whether we're doing profiling or need threads support.
(simular to the default, except no -lg, and no -p. */
#undef LIB_SPEC
#define LIB_SPEC "%{!shared: \
%{!pg:%{!pthread:%{!kthread:-lc} \
%{kthread:-lpthread -lc}} \
%{pthread:-lc_r}} \
%{pg:%{!pthread:%{!kthread:-lc_p} \
%{kthread:-lpthread_p -lc_p}} \
%{pthread:-lc_r_p}}}"
/* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support
for the special GCC options -static and -shared, which allow us to
@ -181,15 +230,17 @@ Boston, MA 02111-1307, USA. */
done. */
#undef LINK_SPEC
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
%{!ibcs: \
#define LINK_SPEC "-m elf_i386 \
%{Wl,*:%*} \
%{v:-V} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
%{static:-static}}}"
/* Get perform_* macros to build libgcc.a. */
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
/* A C statement to output to the stdio stream FILE an assembler
command to advance the location counter to a multiple of 1<<LOG
@ -199,7 +250,8 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
if ((LOG)!=0) \
if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
if ((LOG) != 0) {\
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
#endif

View File

@ -94,9 +94,10 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
# define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
if ((LOG)!=0) \
if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
if ((LOG) != 0) {\
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
}
#endif
/* A C statement or statements which output an assembler instruction

View File

@ -3,13 +3,24 @@
/* This does it mostly for us. */
#include <i386/linux.h>
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -Acpu(i386) -Amachine(i386) \
-Dunix -Asystem(unix) -DMACH -Asystem(mach) -D__GNU__ -Asystem(gnu)"
/* Get machine-independent configuration parameters for the GNU system. */
#include <gnu.h>
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 GNU)");
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__ELF__ -D__i386__ -DMACH -Asystem(mach) \
-Dunix -Asystem(unix) -Asystem(posix) -D__GNU__ -Asystem(gnu)"
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu) \
%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} %{bsd:-D_BSD_SOURCE}"
#undef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu)"
#undef LINK_SPEC
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
@ -18,6 +29,10 @@
%{!dynamic-linker:-dynamic-linker /lib/ld.so}} \
%{static:-static}}"
/* Get machine-independent configuration parameters for the GNU system. */
#include <gnu.h>
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{!static: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
%{static:crt0.o%s}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"

View File

@ -22,14 +22,20 @@ Boston, MA 02111-1307, USA. */
#include "i386/gas.h"
#include "dbxcoff.h"
/* Specify predefined symbols in preprocessor. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386"
/* We want to be able to get DBX debugging information via -gstabs. */
#undef DBX_DEBUGGING_INFO
#define SDB_DEBUGGING_INFO
#define DBX_DEBUGGING_INFO
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
/* Support the ctors and dtors sections for g++. */

View File

@ -0,0 +1,575 @@
/* Target definitions for GNU compiler for Intel 80386 running Interix
Parts Copyright (C) 1991, 1999 Free Software Foundation, Inc.
Parts:
by Douglas B. Rupp (drupp@cs.washington.edu).
by Ron Guilmette (rfg@netcom.com).
by Donn Terry (donn@softway.com).
by Mumit Khan (khan@xraylith.wisc.edu).
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.
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. */
#define YES_UNDERSCORES
/* YES_UNDERSCORES must preceed gas.h */
#include <i386/gas.h>
/* The rest must follow. */
#define DBX_DEBUGGING_INFO
#define SDB_DEBUGGING_INFO
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
#define HANDLE_SYSV_PRAGMA
#undef HANDLE_PRAGMA_WEAK /* until the link format can handle it */
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387 and needs stack probes
We also align doubles to 64-bits for MSVC default compatability */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE | \
MASK_ALIGN_DOUBLE)
#undef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT 2 /* 486 */
#define WCHAR_UNSIGNED 1
#define WCHAR_TYPE_SIZE 16
#define WCHAR_TYPE "short unsigned int"
/* WinNT (and thus Interix) use unsigned int */
#define SIZE_TYPE "unsigned int"
#define ASM_LOAD_ADDR(loc, reg) " leal " #loc "," #reg "\n"
/* For the sake of libgcc2.c, indicate target supports atexit. */
#define HAVE_ATEXIT
/* cpp handles __STDC__ */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES " \
-D__INTERIX \
-D__OPENNT \
-D_M_IX86=300 -D_X86_=1 \
-D__stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(i386) -Amachine(i386)"
#undef CPP_SPEC
/* Write out the correct language type definition for the header files.
Unless we have assembler language, write out the symbols for C.
cpp_cpu is an Intel specific variant. See i386.h
mieee is an Alpha specific variant. Cross polination a bad idea.
*/
#define CPP_SPEC "\
%{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}} \
%{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
%{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
%{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
%{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \
-remap \
%(cpp_cpu) \
%{posix:-D_POSIX_SOURCE} \
-idirafter %$INTERIX_ROOT/usr/include"
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386 Interix)");
/* The global __fltused is necessary to cause the printf/scanf routines
for outputting/inputting floating point numbers to be loaded. Since this
is kind of hard to detect, we just do it all the time. */
#ifdef ASM_FILE_START
#undef ASM_FILE_START
#endif
#define ASM_FILE_START(FILE) \
do { fprintf (FILE, "\t.file\t"); \
output_quoted_string (FILE, dump_base_name); \
fprintf (FILE, "\n"); \
fprintf (FILE, ".global\t__fltused\n"); \
} while (0)
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
corresponds to a particular byte value [0..255]. For any
given byte value, if the value in the corresponding table
position is zero, the given character can be output directly.
If the table value is 1, the byte must be output as a \ooo
octal escape. If the tables value is anything else, then the
byte value should be output as a \ followed by the value
in the table. Note that we can use standard UN*X escape
sequences for many control characters, but we don't use
\a to represent BEL because some svr4 assemblers (e.g. on
the i386) don't know about that. Also, we don't use \v
since some versions of gas, such as 2.2 did not accept it. */
#define ESCAPES \
"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\
\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1"
/* Some svr4 assemblers have a limit on the number of characters which
can appear in the operand of a .string directive. If your assembler
has such a limitation, you should define STRING_LIMIT to reflect that
limit. Note that at least some svr4 assemblers have a limit on the
actual number of bytes in the double-quoted string, and that they
count each character in an escape sequence as one byte. Thus, an
escape sequence like \377 would count as four bytes.
If your target assembler doesn't support the .string directive, you
should define this to zero.
*/
#define STRING_LIMIT ((unsigned) 256)
#define STRING_ASM_OP ".string"
/* The routine used to output NUL terminated strings. We use a special
version of this for most svr4 targets because doing so makes the
generated assembly code more compact (and thus faster to assemble)
as well as more readable, especially for targets like the i386
(where the only alternative is to output character sequences as
comma separated lists of numbers). */
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
do \
{ \
register unsigned char *_limited_str = (unsigned char *) (STR); \
register unsigned ch; \
fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \
for (; (ch = *_limited_str); _limited_str++) \
{ \
register int escape = ESCAPES[ch]; \
switch (escape) \
{ \
case 0: \
putc (ch, (FILE)); \
break; \
case 1: \
fprintf ((FILE), "\\%03o", ch); \
break; \
default: \
putc ('\\', (FILE)); \
putc (escape, (FILE)); \
break; \
} \
} \
fprintf ((FILE), "\"\n"); \
} \
while (0)
/* The routine used to output sequences of byte values. We use a special
version of this for most svr4 targets because doing so makes the
generated assembly code more compact (and thus faster to assemble)
as well as more readable. Note that if we find subparts of the
character sequence which end with NUL (and which are shorter than
STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
register unsigned char *_ascii_bytes = (unsigned char *) (STR); \
register unsigned char *limit = _ascii_bytes + (LENGTH); \
register unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
register unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
bytes_in_chunk = 0; \
} \
for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
continue; \
if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \
{ \
if (bytes_in_chunk > 0) \
{ \
fputc ('\n', (FILE)); \
bytes_in_chunk = 0; \
} \
ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
_ascii_bytes = p; \
} \
else \
{ \
if (bytes_in_chunk == 0) \
fprintf ((FILE), "\t.byte\t"); \
else \
fputc (',', (FILE)); \
fprintf ((FILE), "0x%02x", *_ascii_bytes); \
bytes_in_chunk += 5; \
} \
} \
if (bytes_in_chunk > 0) \
fprintf ((FILE), "\n"); \
} \
while (0)
/* This is how to output an element of a case-vector that is relative.
This is only used for PIC code. See comments by the `casesi' insn in
i386.md for an explanation of the expression this outputs.
PE format differs on what PC-relative offsets look like (see
coff_i386_rtype_to_howto), and we need to compensate (by one word) here. */
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
fprintf (FILE, "\t.long __GLOBAL_OFFSET_TABLE_+[.-%s%d+4]\n", LPREFIX, VALUE)
/* Indicate that jump tables go in the text section. This is
necessary when compiling PIC code. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
/* Emit code to check the stack when allocating more that 4000
bytes in one go. */
#define CHECK_STACK_LIMIT 0x1000
/* the following are OSF linker (not gld) specific... we don't want them */
#undef HAS_INIT_SECTION
#undef LD_INIT_SWITCH
#undef LD_FINI_SWITCH
/* The following are needed for C++, but also needed for profiling */
/* Support const sections and the ctors and dtors sections for g++.
Note that there appears to be two different ways to support const
sections at the moment. You can either #define the symbol
READONLY_DATA_SECTION (giving it some code which switches to the
readonly data section) or else you can #define the symbols
EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and
SELECT_RTX_SECTION. We do both here just to be on the safe side. */
#define USE_CONST_SECTION 1
#define CONST_SECTION_ASM_OP ".section\t.rdata,\"r\""
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
Note that we want to give these sections the SHF_WRITE attribute
because these sections will actually contain data (i.e. tables of
addresses of functions in the current root executable or shared library
file) and, in the case of a shared library, the relocatable addresses
will have to be properly resolved/relocated (and then written into) by
the dynamic linker when it actually attaches the given shared library
to the executing process. (Note that on SVR4, you may wish to use the
`-z text' option to the ELF linker, when building a shared library, as
an additional check that you are doing everything right. But if you do
use the `-z text' option when building a shared library, you will get
errors unless the .ctors and .dtors sections are marked as writable
via the SHF_WRITE attribute.) */
#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"x\""
#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"x\""
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
should override this definition in the target-specific file which
includes this file. */
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_const, in_ctors, in_dtors
/* A default list of extra section function definitions. For targets
that use additional sections (e.g. .tdesc) you should override this
definition in the target-specific file which includes this file. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CONST_SECTION_FUNCTION \
CTORS_SECTION_FUNCTION \
DTORS_SECTION_FUNCTION
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION() const_section ()
extern void text_section ();
#define CONST_SECTION_FUNCTION \
void \
const_section () \
{ \
if (!USE_CONST_SECTION) \
text_section(); \
else if (in_section != in_const) \
{ \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \
in_section = in_const; \
} \
}
#define CTORS_SECTION_FUNCTION \
void \
ctors_section () \
{ \
if (in_section != in_ctors) \
{ \
fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
in_section = in_ctors; \
} \
}
#define DTORS_SECTION_FUNCTION \
void \
dtors_section () \
{ \
if (in_section != in_dtors) \
{ \
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
in_section = in_dtors; \
} \
}
#if 0
/* Currently gas chokes on this; that's not too hard to fix, but there's
not a lot of impeteus to do it, either. If it is done, gas will have
to handle long section name escapes (which are defined in the COFF/PE
document as /nnn where nnn is a string table index). The benefit:
section attributes and -ffunction-sections, neither of which seem to
be critical. */
/* gas may have been fixed? bfd was. */
/* Switch into a generic section.
This is currently only used to support section attributes.
We make the section read-only and executable for a function decl,
read-only for a const data decl, and writable for a non-const data decl. */
#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \
fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
(DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
(DECL) && TREE_READONLY (DECL) ? "a" : "aw")
#endif
#define INT_ASM_OP ".long"
/* The MS compilers take alignment as a number of bytes, so we do as well */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG))
/* A C statement (sans semicolon) to output an element in the table of
global constructors. */
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* A C statement (sans semicolon) to output an element in the table of
global destructors. */
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtors_section (); \
fprintf (FILE, "\t%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
/* The linker will take care of this, and having them causes problems with
ld -r (specifically -rU). */
#define CTOR_LISTS_DEFINED_EXTERNALLY 1
#define SET_ASM_OP ".set"
/* Output a definition (implements alias) */
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do \
{ \
fprintf ((FILE), "\t%s\t", SET_ASM_OP); \
assemble_name (FILE, LABEL1); \
fprintf (FILE, ","); \
assemble_name (FILE, LABEL2); \
fprintf (FILE, "\n"); \
} \
while (0)
#define HOST_PTR_PRINTF "%p"
#define HOST_PTR_AS_INT unsigned long
#define PCC_BITFIELD_TYPE_MATTERS 1
#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec)
#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
/* The following two flags are usually "off" for i386, because some non-gnu
tools (for the i386) don't handle them. However, we don't have that
problem, so.... */
/* Forward references to tags are allowed. */
#define SDB_ALLOW_FORWARD_REFERENCES
/* Unknown tags are also allowed. */
#define SDB_ALLOW_UNKNOWN_REFERENCES
/* The integer half of this list needs to be constant. However, there's
a lot of disagreement about what the floating point adjustments should
be. We pick one that works with gdb. (The underlying problem is
what to do about the segment registers. Since we have access to them
from /proc, we'll allow them to be accessed in gdb, even tho the
gcc compiler can't generate them. (There's some evidence that
MSVC does, but possibly only for certain special "canned" sequences.) */
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) \
((n) == 0 ? 0 \
: (n) == 1 ? 2 \
: (n) == 2 ? 1 \
: (n) == 3 ? 3 \
: (n) == 4 ? 6 \
: (n) == 5 ? 7 \
: (n) == 6 ? 5 \
: (n) == 7 ? 4 \
: ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+8 \
: (-1))
/* Define this macro if references to a symbol must be treated
differently depending on something about the variable or
function named by the symbol (such as what section it is in).
Apply stddef, handle (as yet unimplemented) pic.
stddef renaming does NOT apply to Alpha. */
char *gen_stdcall_suffix ();
#undef ENCODE_SECTION_INFO
#define ENCODE_SECTION_INFO(DECL) \
do \
{ \
if (flag_pic) \
{ \
rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \
SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
= (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|| ! TREE_PUBLIC (DECL)); \
} \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
if (lookup_attribute ("stdcall", \
TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \
XEXP (DECL_RTL (DECL), 0) = \
gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (DECL)); \
} \
while (0)
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
trailing @[NUM] encoded by ENCODE_SECTION_INFO. */
#undef STRIP_NAME_ENCODING
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
do { \
char *_p; \
char *_name = SYMBOL_NAME; \
for (_p = _name; *_p && *_p != '@'; ++_p) \
; \
if (*_p == '@') \
{ \
int _len = _p - _name; \
(VAR) = (char *) alloca (_len + 1); \
strncpy ((VAR), _name, _len); \
(VAR)[_len] = '\0'; \
} \
else \
(VAR) = _name; \
} while (0)
#if 0
/* Turn this back on when the linker is updated to handle grouped
.data$ sections correctly. See corresponding note in i386/interix.c.
MK. */
/* Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
without user intervention. For instance, under Microsoft Windows
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
extern void i386_pe_unique_section ();
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
/* A C statement to output something to the assembler file to switch to section
NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
NULL_TREE. Some target formats do not support arbitrary sections. Do not
define this macro in such cases. */
#undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
do { \
static struct section_info \
{ \
struct section_info *next; \
char *name; \
enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
} *sections; \
struct section_info *s; \
char *mode; \
enum sect_enum type; \
\
for (s = sections; s; s = s->next) \
if (!strcmp (NAME, s->name)) \
break; \
\
if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
type = SECT_EXEC, mode = "x"; \
else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
type = SECT_RO, mode = "r"; \
else \
type = SECT_RW, mode = "w"; \
\
if (s == 0) \
{ \
s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
strcpy (s->name, NAME); \
s->type = type; \
s->next = sections; \
sections = s; \
fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
/* Functions may have been compiled at various levels of \
optimization so we can't use `same_size' here. Instead, \
have the linker pick one. */ \
if ((DECL) && DECL_ONE_ONLY (DECL)) \
fprintf (STREAM, "\t.linkonce %s\n", \
TREE_CODE (DECL) == FUNCTION_DECL \
? "discard" : "same_size"); \
} \
else \
{ \
fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
} \
} while (0)
#endif /* 0 */
/* DWARF2 Unwinding doesn't work with exception handling yet. */
#define DWARF2_UNWIND_INFO 0
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C

File diff suppressed because it is too large Load Diff

View File

@ -155,62 +155,67 @@ extern int target_flags;
#define TARGET_486 (ix86_cpu == PROCESSOR_I486)
#define TARGET_PENTIUM (ix86_cpu == PROCESSOR_PENTIUM)
#define TARGET_PENTIUMPRO (ix86_cpu == PROCESSOR_PENTIUMPRO)
#define TARGET_USE_LEAVE (ix86_cpu == PROCESSOR_I386)
#define TARGET_PUSH_MEMORY (ix86_cpu == PROCESSOR_I386)
#define TARGET_ZERO_EXTEND_WITH_AND (ix86_cpu != PROCESSOR_I386 \
&& ix86_cpu != PROCESSOR_PENTIUMPRO)
#define TARGET_DOUBLE_WITH_ADD (ix86_cpu != PROCESSOR_I386)
#define TARGET_USE_BIT_TEST (ix86_cpu == PROCESSOR_I386)
#define TARGET_UNROLL_STRLEN (ix86_cpu != PROCESSOR_I386)
#define TARGET_USE_Q_REG (ix86_cpu == PROCESSOR_PENTIUM \
|| ix86_cpu == PROCESSOR_PENTIUMPRO)
#define TARGET_USE_ANY_REG (ix86_cpu == PROCESSOR_I486)
#define TARGET_CMOVE (ix86_arch == PROCESSOR_PENTIUMPRO)
#define TARGET_DEEP_BRANCH_PREDICTION (ix86_cpu == PROCESSOR_PENTIUMPRO)
#define TARGET_K6 (ix86_cpu == PROCESSOR_K6)
#define CPUMASK (1 << ix86_cpu)
extern const int x86_use_leave, x86_push_memory, x86_zero_extend_with_and;
extern const int x86_use_bit_test, x86_cmove, x86_deep_branch;
extern const int x86_unroll_strlen, x86_use_q_reg, x86_use_any_reg;
extern const int x86_double_with_add;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
#define TARGET_ZERO_EXTEND_WITH_AND (x86_zero_extend_with_and & CPUMASK)
#define TARGET_USE_BIT_TEST (x86_use_bit_test & CPUMASK)
#define TARGET_UNROLL_STRLEN (x86_unroll_strlen & CPUMASK)
#define TARGET_USE_Q_REG (x86_use_q_reg & CPUMASK)
#define TARGET_USE_ANY_REG (x86_use_any_reg & CPUMASK)
#define TARGET_CMOVE (x86_cmove & (1 << ix86_arch))
#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK)
#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
#define TARGET_SWITCHES \
{ { "80387", MASK_80387 }, \
{ "no-80387", -MASK_80387 }, \
{ "hard-float", MASK_80387 }, \
{ "soft-float", -MASK_80387 }, \
{ "no-soft-float", MASK_80387 }, \
{ "386", 0 }, \
{ "no-386", 0 }, \
{ "486", 0 }, \
{ "no-486", 0 }, \
{ "pentium", 0 }, \
{ "pentiumpro", 0 }, \
{ "rtd", MASK_RTD }, \
{ "no-rtd", -MASK_RTD }, \
{ "align-double", MASK_ALIGN_DOUBLE }, \
{ "no-align-double", -MASK_ALIGN_DOUBLE }, \
{ "svr3-shlib", MASK_SVR3_SHLIB }, \
{ "no-svr3-shlib", -MASK_SVR3_SHLIB }, \
{ "ieee-fp", MASK_IEEE_FP }, \
{ "no-ieee-fp", -MASK_IEEE_FP }, \
{ "fp-ret-in-387", MASK_FLOAT_RETURNS }, \
{ "no-fp-ret-in-387", -MASK_FLOAT_RETURNS }, \
{ "no-fancy-math-387", MASK_NO_FANCY_MATH_387 }, \
{ "fancy-math-387", -MASK_NO_FANCY_MATH_387 }, \
{ "omit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER }, \
{ "no-omit-leaf-frame-pointer",-MASK_OMIT_LEAF_FRAME_POINTER }, \
{ "no-wide-multiply", MASK_NO_WIDE_MULTIPLY }, \
{ "wide-multiply", -MASK_NO_WIDE_MULTIPLY }, \
{ "schedule-prologue", MASK_SCHEDULE_PROLOGUE }, \
{ "no-schedule-prologue", -MASK_SCHEDULE_PROLOGUE }, \
{ "debug-addr", MASK_DEBUG_ADDR }, \
{ "no-debug-addr", -MASK_DEBUG_ADDR }, \
{ "move", -MASK_NO_MOVE }, \
{ "no-move", MASK_NO_MOVE }, \
{ "debug-arg", MASK_DEBUG_ARG }, \
{ "no-debug-arg", -MASK_DEBUG_ARG }, \
{ "stack-arg-probe", MASK_STACK_PROBE }, \
{ "no-stack-arg-probe", -MASK_STACK_PROBE }, \
{ "windows", 0 }, \
{ "dll", 0 }, \
{ { "80387", MASK_80387, "Use hardware fp" }, \
{ "no-80387", -MASK_80387, "Do not use hardware fp" },\
{ "hard-float", MASK_80387, "Use hardware fp" }, \
{ "soft-float", -MASK_80387, "Do not use hardware fp" },\
{ "no-soft-float", MASK_80387, "Use hardware fp" }, \
{ "386", 0, "Same as -mcpu=i386" }, \
{ "486", 0, "Same as -mcpu=i486" }, \
{ "pentium", 0, "Same as -mcpu=pentium" }, \
{ "pentiumpro", 0, "Same as -mcpu=pentiumpro" }, \
{ "rtd", MASK_RTD, "Alternate calling convention" },\
{ "no-rtd", -MASK_RTD, "Use normal calling convention" },\
{ "align-double", MASK_ALIGN_DOUBLE, "Align some doubles on dword boundary" },\
{ "no-align-double", -MASK_ALIGN_DOUBLE, "Align doubles on word boundary" }, \
{ "svr3-shlib", MASK_SVR3_SHLIB, "Uninitialized locals in .bss" }, \
{ "no-svr3-shlib", -MASK_SVR3_SHLIB, "Uninitialized locals in .data" }, \
{ "ieee-fp", MASK_IEEE_FP, "Use IEEE math for fp comparisons" }, \
{ "no-ieee-fp", -MASK_IEEE_FP, "Do not use IEEE math for fp comparisons" }, \
{ "fp-ret-in-387", MASK_FLOAT_RETURNS, "Return values of functions in FPU registers" }, \
{ "no-fp-ret-in-387", -MASK_FLOAT_RETURNS , "Do not return values of functions in FPU registers"}, \
{ "no-fancy-math-387", MASK_NO_FANCY_MATH_387, "Do not generate sin, cos, sqrt for 387" }, \
{ "fancy-math-387", -MASK_NO_FANCY_MATH_387, "Generate sin, cos, sqrt for FPU"}, \
{ "omit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER, "Omit the frame pointer in leaf functions" }, \
{ "no-omit-leaf-frame-pointer",-MASK_OMIT_LEAF_FRAME_POINTER, "" }, \
{ "no-wide-multiply", MASK_NO_WIDE_MULTIPLY, "multiplies of 32 bits constrained to 32 bits" }, \
{ "wide-multiply", -MASK_NO_WIDE_MULTIPLY, "multiplies of 32 bits are 64 bits" }, \
{ "schedule-prologue", MASK_SCHEDULE_PROLOGUE, "Schedule function prologues" }, \
{ "no-schedule-prologue", -MASK_SCHEDULE_PROLOGUE, "" }, \
{ "debug-addr", MASK_DEBUG_ADDR, 0 /* intentionally undoc */ }, \
{ "no-debug-addr", -MASK_DEBUG_ADDR, 0 /* intentionally undoc */ }, \
{ "move", -MASK_NO_MOVE, "Generate mem-mem moves" }, \
{ "no-move", MASK_NO_MOVE, "Don't generate mem-mem moves" }, \
{ "debug-arg", MASK_DEBUG_ARG, 0 /* intentionally undoc */ }, \
{ "no-debug-arg", -MASK_DEBUG_ARG, 0 /* intentionally undoc */ }, \
{ "stack-arg-probe", MASK_STACK_PROBE, "Enable stack probing" }, \
{ "no-stack-arg-probe", -MASK_STACK_PROBE, "" }, \
{ "windows", 0, 0 /* intentionally undoc */ }, \
{ "dll", 0, 0 /* intentionally undoc */ }, \
SUBTARGET_SWITCHES \
{ "", MASK_SCHEDULE_PROLOGUE | TARGET_DEFAULT}}
{ "", MASK_SCHEDULE_PROLOGUE | TARGET_DEFAULT, 0 }}
/* Which processor to schedule for. The cpu attribute defines a list that
mirrors this list, so changes to i386.md must be made at the same time. */
@ -219,7 +224,8 @@ enum processor_type
{PROCESSOR_I386, /* 80386 */
PROCESSOR_I486, /* 80486DX, 80486SX, 80486DX[24] */
PROCESSOR_PENTIUM,
PROCESSOR_PENTIUMPRO};
PROCESSOR_PENTIUMPRO,
PROCESSOR_K6};
#define PROCESSOR_I386_STRING "i386"
#define PROCESSOR_I486_STRING "i486"
@ -227,28 +233,20 @@ enum processor_type
#define PROCESSOR_PENTIUM_STRING "pentium"
#define PROCESSOR_I686_STRING "i686"
#define PROCESSOR_PENTIUMPRO_STRING "pentiumpro"
#define PROCESSOR_K6_STRING "k6"
extern enum processor_type ix86_cpu;
extern int ix86_arch;
/* Define the default processor. This is overridden by other tm.h files. */
#define PROCESSOR_DEFAULT \
((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_I486) \
? PROCESSOR_I486 \
: ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUM) \
? PROCESSOR_PENTIUM \
: ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUMPRO) \
? PROCESSOR_PENTIUMPRO \
: PROCESSOR_I386
#define PROCESSOR_DEFAULT (enum processor_type) TARGET_CPU_DEFAULT
#define PROCESSOR_DEFAULT_STRING \
((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_I486) \
? PROCESSOR_I486_STRING \
: ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUM) \
? PROCESSOR_PENTIUM_STRING \
: ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUMPRO) \
? PROCESSOR_PENTIUMPRO_STRING \
: PROCESSOR_I386_STRING
(PROCESSOR_DEFAULT == PROCESSOR_I486 ? PROCESSOR_I486_STRING \
: PROCESSOR_DEFAULT == PROCESSOR_PENTIUM ? PROCESSOR_PENTIUM_STRING \
: PROCESSOR_DEFAULT == PROCESSOR_PENTIUMPRO ? PROCESSOR_PENTIUMPRO_STRING \
: PROCESSOR_DEFAULT == PROCESSOR_K6 ? PROCESSOR_K6_STRING \
: PROCESSOR_I386_STRING)
/* This macro is similar to `TARGET_SWITCHES' but defines names of
command options that have values. Its definition is an
@ -260,14 +258,15 @@ extern int ix86_arch;
option if the fixed part matches. The actual option name is made
by appending `-m' to the specified name. */
#define TARGET_OPTIONS \
{ { "cpu=", &ix86_cpu_string}, \
{ "arch=", &ix86_arch_string}, \
{ "reg-alloc=", &i386_reg_alloc_order }, \
{ "regparm=", &i386_regparm_string }, \
{ "align-loops=", &i386_align_loops_string }, \
{ "align-jumps=", &i386_align_jumps_string }, \
{ "align-functions=", &i386_align_funcs_string }, \
{ "branch-cost=", &i386_branch_cost_string }, \
{ { "cpu=", &ix86_cpu_string, "Schedule code for given CPU"}, \
{ "arch=", &ix86_arch_string, "Generate code for given CPU"}, \
{ "reg-alloc=", &i386_reg_alloc_order, "Control allocation order of integer registers" }, \
{ "regparm=", &i386_regparm_string, "Number of registers used to pass integer arguments" }, \
{ "align-loops=", &i386_align_loops_string, "Loop code aligned to this power of 2" }, \
{ "align-jumps=", &i386_align_jumps_string, "Jump targets are aligned to this power of 2" }, \
{ "align-functions=", &i386_align_funcs_string, "Function starts are aligned to this power of 2" }, \
{ "preferred-stack-boundary=", &i386_preferred_stack_boundary_string, "Attempt to keep stack aligned to this power of 2" }, \
{ "branch-cost=", &i386_branch_cost_string, "Branches are this expensive (1-5, arbitrary units)" }, \
SUBTARGET_OPTIONS \
}
@ -295,44 +294,45 @@ extern int ix86_arch;
#define CC1_CPU_SPEC "\
%{!mcpu*: \
%{m386:-mcpu=i386 -march=i386} \
%{mno-486:-mcpu=i386 -march=i386} \
%{m486:-mcpu=i486 -march=i486} \
%{mno-386:-mcpu=i486 -march=i486} \
%{mno-pentium:-mcpu=i486 -march=i486} \
%{mpentium:-mcpu=pentium} \
%{mno-pentiumpro:-mcpu=pentium} \
%{mpentiumpro:-mcpu=pentiumpro}}"
#endif
#define CPP_486_SPEC "%{!ansi:-Di486} -D__i486 -D__i486__"
#define CPP_586_SPEC "%{!ansi:-Di586 -Dpentium} \
-D__i586 -D__i586__ -D__pentium -D__pentium__"
#define CPP_K6_SPEC "%{!ansi:-Di586 -Dk6} \
-D__i586 -D__i586__ -D__k6 -D__k6__"
#define CPP_686_SPEC "%{!ansi:-Di686 -Dpentiumpro} \
-D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__"
#ifndef CPP_CPU_DEFAULT_SPEC
#if TARGET_CPU_DEFAULT == 1
#define CPP_CPU_DEFAULT_SPEC "%(cpp_486)"
#else
#endif
#if TARGET_CPU_DEFAULT == 2
#define CPP_CPU_DEFAULT_SPEC "%(cpp_586)"
#else
#endif
#if TARGET_CPU_DEFAULT == 3
#define CPP_CPU_DEFAULT_SPEC "%(cpp_686)"
#else
#endif
#if TARGET_CPU_DEFAULT == 4
#define CPP_CPU_DEFAULT_SPEC "%(cpp_k6)"
#endif
#ifndef CPP_CPU_DEFAULT_SPEC
#define CPP_CPU_DEFAULT_SPEC ""
#endif
#endif
#endif
#endif /* CPP_CPU_DEFAULT_SPEC */
#ifndef CPP_CPU_SPEC
#define CPP_CPU_SPEC "\
-Asystem(unix) -Acpu(i386) -Amachine(i386) \
-Acpu(i386) -Amachine(i386) \
%{!ansi:-Di386} -D__i386 -D__i386__ \
%{mcpu=i486:%(cpp_486)} %{m486:%(cpp_486)} \
%{mpentium:%(cpp_586)} %{mcpu=pentium:%(cpp_586)} \
%{mpentiumpro:%(cpp_686)} %{mcpu=pentiumpro:%(cpp_686)} \
%{mcpu=k6:%(cpp_k6)} \
%{!mcpu*:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}"
#endif
@ -357,6 +357,7 @@ extern int ix86_arch;
#define EXTRA_SPECS \
{ "cpp_486", CPP_486_SPEC}, \
{ "cpp_586", CPP_586_SPEC}, \
{ "cpp_k6", CPP_K6_SPEC}, \
{ "cpp_686", CPP_686_SPEC}, \
{ "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \
{ "cpp_cpu", CPP_CPU_SPEC }, \
@ -407,9 +408,13 @@ extern int ix86_arch;
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY 32
/* Boundary (in *bits*) on which stack pointer should be aligned. */
/* Boundary (in *bits*) on which the stack pointer must be aligned. */
#define STACK_BOUNDARY 32
/* Boundary (in *bits*) on which the stack pointer preferrs to be
aligned; the compiler cannot rely on having this alignment. */
#define PREFERRED_STACK_BOUNDARY i386_preferred_stack_boundary
/* Allocation boundary (in *bits*) for the code of a function.
For i486, we get better performance by aligning to a cache
line (i.e. 16 byte) boundary. */
@ -502,6 +507,46 @@ extern int ix86_arch;
: (ALIGN)) \
: (ALIGN))
/* If defined, a C expression to compute the alignment for a local
variable. TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this macro is used
instead of that alignment to align the object.
If this macro is not defined, then ALIGN is used.
One use of this macro is to increase alignment of medium-size
data to make it all fit in fewer cache lines. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == COMPLEX_TYPE \
? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: ((TREE_CODE (TYPE) == RECORD_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == QUAL_UNION_TYPE) \
&& TYPE_FIELDS (TYPE)) \
? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \
? 64 \
: (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: TREE_CODE (TYPE) == REAL_TYPE \
? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \
? 64 \
: (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \
? 128 \
: (ALIGN)) \
: (ALIGN))
/* Set this non-zero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 0
@ -664,8 +709,8 @@ extern int ix86_arch;
#define MODES_TIEABLE_P(MODE1, MODE2) \
((MODE1) == (MODE2) \
|| ((MODE1) == SImode && (MODE2) == HImode \
|| (MODE1) == HImode && (MODE2) == SImode))
|| ((MODE1) == SImode && (MODE2) == HImode) \
|| ((MODE1) == HImode && (MODE2) == SImode))
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
@ -834,11 +879,6 @@ enum reg_class
#define STACK_TOP_P(xop) (REG_P (xop) && REGNO (xop) == FIRST_STACK_REG)
/* Try to maintain the accuracy of the death notes for regs satisfying the
following. Important for stack like regs, to know when to pop. */
/* #define PRESERVE_DEATH_INFO_REGNO_P(x) FP_REGNO_P(x) */
/* 1 if register REGNO can magically overlap other regs.
Note that nonzero values work only in very special circumstances. */
@ -896,19 +936,10 @@ enum reg_class
/* Similar, but for floating constants, and defining letters G and H.
Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if
TARGET_387 isn't set, because the stack register converter may need to
load 0.0 into the function value register.
We disallow these constants when -fomit-frame-pointer and compiling
PIC code since reload might need to force the constant to memory.
Forcing the constant to memory changes the elimination offsets after
the point where they must stay constant.
However, we must allow them after reload as completed as reg-stack.c
will create insns which use these constants. */
load 0.0 into the function value register. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
(((reload_completed || !flag_pic || !flag_omit_frame_pointer) && (C) == 'G') \
? standard_80387_constant_p (VALUE) : 0)
((C) == 'G' ? standard_80387_constant_p (VALUE) : 0)
/* Place additional restrictions on the register class to use when it
is necessary to be able to hold a value of mode MODE in a reload
@ -931,8 +962,11 @@ enum reg_class
Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
movdf to do mem-to-mem moves through integer regs. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode ? NO_REGS \
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
(GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode \
? (standard_80387_constant_p (X) \
? reg_class_subset_p (CLASS, FLOAT_REGS) ? CLASS : FLOAT_REGS \
: NO_REGS) \
: GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
: ((CLASS) == ALL_REGS \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS \
@ -1532,25 +1566,16 @@ do { \
/* Output assembler code for a block containing the constant parts
of a trampoline, leaving space for the variable parts. */
/* On the 386, the trampoline contains three instructions:
/* On the 386, the trampoline contains two instructions:
mov #STATIC,ecx
mov #FUNCTION,eax
jmp @eax */
#define TRAMPOLINE_TEMPLATE(FILE) \
{ \
ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb9)); \
ASM_OUTPUT_SHORT (FILE, const0_rtx); \
ASM_OUTPUT_SHORT (FILE, const0_rtx); \
ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb8)); \
ASM_OUTPUT_SHORT (FILE, const0_rtx); \
ASM_OUTPUT_SHORT (FILE, const0_rtx); \
ASM_OUTPUT_CHAR (FILE, GEN_INT (0xff)); \
ASM_OUTPUT_CHAR (FILE, GEN_INT (0xe0)); \
}
jmp FUNCTION
The trampoline is generated entirely at runtime. The operand of JMP
is the address of FUNCTION relative to the instruction following the
JMP (which is 5 bytes long). */
/* Length in units of the trampoline for entering a nested function. */
#define TRAMPOLINE_SIZE 12
#define TRAMPOLINE_SIZE 10
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
@ -1558,8 +1583,14 @@ do { \
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
{ \
/* Compute offset from the end of the jmp to the target function. */ \
rtx disp = expand_binop (SImode, sub_optab, FNADDR, \
plus_constant (TRAMP, 10), \
NULL_RTX, 1, OPTAB_DIRECT); \
emit_move_insn (gen_rtx_MEM (QImode, TRAMP), GEN_INT (0xb9)); \
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 1)), CXT); \
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), FNADDR); \
emit_move_insn (gen_rtx_MEM (QImode, plus_constant (TRAMP, 5)), GEN_INT (0xe9));\
emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), disp); \
}
/* Definitions for register eliminations.
@ -1601,30 +1632,33 @@ do { \
(OFFSET) = 8; /* Skip saved PC and previous frame pointer */ \
else \
{ \
int regno; \
int offset = 0; \
int nregs; \
int offset; \
int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; \
HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), \
&nregs); \
\
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
if ((regs_ever_live[regno] && ! call_used_regs[regno]) \
|| ((current_function_uses_pic_offset_table \
|| current_function_uses_const_pool) \
&& flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)) \
offset += 4; \
(OFFSET) = (tsize + nregs * UNITS_PER_WORD); \
\
(OFFSET) = offset + get_frame_size (); \
offset = 4; \
if (frame_pointer_needed) \
offset += UNITS_PER_WORD; \
\
if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) += 4; /* Skip saved PC */ \
if ((FROM) == ARG_POINTER_REGNUM) \
(OFFSET) += offset; \
else \
(OFFSET) -= ((offset + preferred_alignment - 1) \
& -preferred_alignment) - offset; \
} \
}
/* Addressing modes, and classification of registers for them. */
/* #define HAVE_POST_INCREMENT */
/* #define HAVE_POST_DECREMENT */
/* #define HAVE_POST_INCREMENT 0 */
/* #define HAVE_POST_DECREMENT 0 */
/* #define HAVE_PRE_DECREMENT */
/* #define HAVE_PRE_INCREMENT */
/* #define HAVE_PRE_DECREMENT 0 */
/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
@ -1703,15 +1737,15 @@ do { \
#define MAX_REGS_PER_ADDRESS 2
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|| GET_CODE (X) == HIGH)
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_CONSTANT_P(X) 1
#define LEGITIMATE_CONSTANT_P(X) \
(GET_CODE (X) == CONST_DOUBLE ? standard_80387_constant_p (X) : 1)
#ifdef REG_OK_STRICT
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
@ -1764,8 +1798,7 @@ do { \
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_PIC_OPERAND_P(X) \
(! SYMBOLIC_CONST (X) \
|| (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)))
(! SYMBOLIC_CONST (X) || legitimate_pic_address_disp_p (X))
#define SYMBOLIC_CONST(X) \
(GET_CODE (X) == SYMBOL_REF \
@ -1893,10 +1926,10 @@ while (0)
in one reasonably fast instruction. */
#define MOVE_MAX 4
/* The number of scalar move insns which should be generated instead
of a string move insn or a library call. Increasing the value
will always make code faster, but eventually incurs high cost in
increased code size.
/* If a memory-to-memory move would take MOVE_RATIO or more simple
move-instruction pairs, we will do a movstr or libcall instead.
Increasing the value will always make code faster, but eventually
incurs high cost in increased code size.
If you don't define this, a reasonable default is used.
@ -2243,70 +2276,7 @@ while (0)
the same cost as a data-dependence. */
#define ADJUST_COST(insn,link,dep_insn,cost) \
{ \
rtx next_inst; \
if (GET_CODE (dep_insn) == CALL_INSN) \
(cost) = 0; \
\
else if (GET_CODE (dep_insn) == INSN \
&& GET_CODE (PATTERN (dep_insn)) == SET \
&& GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG \
&& GET_CODE (insn) == INSN \
&& GET_CODE (PATTERN (insn)) == SET \
&& !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)), \
SET_SRC (PATTERN (insn)))) \
{ \
(cost) = 0; \
} \
\
else if (GET_CODE (insn) == JUMP_INSN) \
{ \
(cost) = 0; \
} \
\
if (TARGET_PENTIUM) \
{ \
if (cost !=0 && is_fp_insn (insn) && is_fp_insn (dep_insn) \
&& !is_fp_dest (dep_insn)) \
{ \
(cost) = 0; \
} \
\
if (agi_dependent (insn, dep_insn)) \
{ \
(cost) = 3; \
} \
else if (GET_CODE (insn) == INSN \
&& GET_CODE (PATTERN (insn)) == SET \
&& SET_DEST (PATTERN (insn)) == cc0_rtx \
&& (next_inst = next_nonnote_insn (insn)) \
&& GET_CODE (next_inst) == JUMP_INSN) \
{ /* compare probably paired with jump */ \
(cost) = 0; \
} \
} \
else \
if (!is_fp_dest (dep_insn)) \
{ \
if(!agi_dependent (insn, dep_insn)) \
(cost) = 0; \
else if (TARGET_486) \
(cost) = 2; \
} \
else \
if (is_fp_store (insn) && is_fp_insn (dep_insn) \
&& NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn)) \
&& NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))) \
&& (GET_CODE (NEXT_INSN (insn)) == INSN) \
&& (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN) \
&& (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE) \
&& (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) \
== NOTE_INSN_LOOP_END)) \
{ \
(cost) = 3; \
} \
}
(cost) = x86_adjust_cost(insn, link, dep_insn, cost)
#define ADJUST_BLOCKAGE(last_insn,insn,blockage) \
{ \
@ -2323,6 +2293,8 @@ while (0)
} \
}
#define ISSUE_RATE ((int)ix86_cpu > (int)PROCESSOR_I486 ? 2 : 1)
/* Add any extra modes needed to represent the condition code.
@ -2606,7 +2578,7 @@ do { long l; \
F,f -- likewise, but for floating-point. */
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '*')
((CODE) == '*' || (CODE) == '_')
/* Print the name of a register based on its machine mode and number.
If CODE is 'w', pretend the mode is HImode.
@ -2741,11 +2713,8 @@ extern void function_arg_advance ();
extern struct rtx_def *function_arg ();
extern int function_arg_partial_nregs ();
extern char *output_strlen_unroll ();
extern void output_op_from_reg ();
extern void output_to_reg ();
extern char *singlemove_string ();
extern char *output_move_double ();
extern char *output_move_memory ();
extern char *output_move_pushmem ();
extern int standard_80387_constant_p ();
extern char *output_move_const_single ();
@ -2773,6 +2742,7 @@ extern int shift_op ();
extern int VOIDmode_compare_op ();
extern char *output_387_binary_op ();
extern char *output_fix_trunc ();
extern void output_float_extend ();
extern char *output_float_compare ();
extern char *output_fp_cc0_set ();
extern void save_386_machine_status ();
@ -2793,6 +2763,9 @@ extern int reg_mentioned_in_mem ();
extern char *output_int_conditional_move ();
extern char *output_fp_conditional_move ();
extern int ix86_can_use_return_insn_p ();
extern int small_shift_operand ();
extern char *output_ashl ();
extern int memory_address_info ();
#ifdef NOTYET
extern struct rtx_def *copy_all_rtx ();
@ -2807,11 +2780,13 @@ extern char *i386_regparm_string; /* # registers to use to pass args */
extern char *i386_align_loops_string; /* power of two alignment for loops */
extern char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */
extern char *i386_align_funcs_string; /* power of two alignment for functions */
extern char *i386_preferred_stack_boundary_string;/* power of two alignment for stack boundary */
extern char *i386_branch_cost_string; /* values 1-5: see jump.c */
extern int i386_regparm; /* i386_regparm_string as a number */
extern int i386_align_loops; /* power of two alignment for loops */
extern int i386_align_jumps; /* power of two alignment for non-loop jumps */
extern int i386_align_funcs; /* power of two alignment for functions */
extern int i386_preferred_stack_boundary; /* preferred stack boundary alignment in bits */
extern int i386_branch_cost; /* values 1-5: see jump.c */
extern char *hi_reg_name[]; /* names for 16 bit regs */
extern char *qi_reg_name[]; /* names for 8 bit regs (low) */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
/* Subroutines for insn-output.c for Windows NT.
Copyright (C) 1998, 1999 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.
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. */
#include "config.h"
#include "system.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "output.h"
#include "tree.h"
#include "flags.h"
/* Return string which is the former assembler name modified with a
suffix consisting of an atsign (@) followed by the number of bytes of
arguments */
char *
gen_stdcall_suffix (decl)
tree decl;
{
int total = 0;
/* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
of DECL_ASSEMBLER_NAME. */
char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
char *newsym;
if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
== void_type_node)
{
tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
while (TREE_VALUE (formal_type) != void_type_node)
{
int parm_size
= TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
/* Must round up to include padding. This is done the same
way as in store_one_arg. */
parm_size = ((parm_size + PARM_BOUNDARY - 1)
/ PARM_BOUNDARY * PARM_BOUNDARY);
total += parm_size;
formal_type = TREE_CHAIN (formal_type);
}
}
newsym = xmalloc (strlen (asmname) + 10);
sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
return IDENTIFIER_POINTER (get_identifier (newsym));
}
#if 0
/* Turn this back on when the linker is updated to handle grouped
.data$ sections correctly. See corresponding note in i386/interix.h.
MK. */
/* Cover function for UNIQUE_SECTION. */
void
i386_pe_unique_section (decl, reloc)
tree decl;
int reloc;
{
int len;
char *name,*string,*prefix;
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
/* Strip off any encoding in fnname. */
STRIP_NAME_ENCODING (name, name);
/* The object is put in, for example, section .text$foo.
The linker will then ultimately place them in .text
(everything from the $ on is stripped). Don't put
read-only data in .rdata section to avoid a PE linker
bug when .rdata$* grouped sections are used in code
without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL)
prefix = ".text$";
else if (DECL_READONLY_SECTION (decl, reloc))
#ifdef READONLY_DATA_SECTION
prefix = ".rdata$";
#else
prefix = ".text$";
#endif
else
prefix = ".data$";
len = strlen (name) + strlen (prefix);
string = alloca (len + 1);
sprintf (string, "%s%s", prefix, name);
DECL_SECTION_NAME (decl) = build_string (len, string);
}
#endif /* 0 */

View File

@ -59,7 +59,7 @@
So don't make TARGET_IEEE_FP default for ISC. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0201
#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* The ISC 2.0.2 software FPU emulator apparently can't handle
80-bit XFmode insns, so don't generate them. */
@ -72,20 +72,23 @@
message. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
do { \
char c; \
int max = 0; \
char *string = dump_base_name; \
\
fputs ("\t.file\t\"", FILE); \
\
while ((c = *string++) != 0 && max++ < 14) { \
if (c == '\"' || c == '\\') \
putc ('\\', FILE); \
putc (c, FILE); \
} \
fputs ("\"\n", FILE); \
#define ASM_FILE_START(FILE) \
do { \
int len = strlen (main_input_filename); \
char *na = main_input_filename + len; \
char shorter[15]; \
/* NA gets MAIN_INPUT_FILENAME sans directory names. */\
while (na > main_input_filename) \
{ \
if (na[-1] == '/') \
break; \
na--; \
} \
strncpy (shorter, na, 14); \
shorter[14] = 0; \
fprintf (FILE, "\t.file\t"); \
output_quoted_string (FILE, shorter); \
fprintf (FILE, "\n"); \
} while (0)
/* Work around assembler forward label references generated in exception

View File

@ -1,8 +1,8 @@
/* Definitions for Intel 386 running Interactive Unix System V.
Specifically, this is for recent versions that support POSIX;
for version 2.0.2, use configuration option i386-sysv instead.
(But set TARGET_DEFAULT to 0201 if you do that,
if you don't have a real 80387.) */
(But set TARGET_DEFAULT to (MASK_80307 | MASK_FLOAT_RETURNS)
if you do that, if you don't have a real 80387.) */
/* Mostly it's like AT&T Unix System V. */

View File

@ -150,9 +150,8 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
/* The egcs-1.1 branch is the last time we will have -Di386. -D__i386__ is the thing to use. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__ELF__ -Dunix -Di386 -D__i386__ -Dlinux -Asystem(posix)"
#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__i386__ -Dlinux -Asystem(posix)"
#undef CPP_SPEC
#ifdef USE_GNULIBC_1
@ -227,8 +226,11 @@ Boston, MA 02111-1307, USA. */
This is used to align code labels according to Intel recommendations. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
if ((LOG)!=0) \
if ((MAX_SKIP)==0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP))
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
} \
} while (0)
#endif

View File

@ -2,7 +2,7 @@
hosting on Windows32, using GNU tools and the Windows32 API Library,
as distinct from winnt.h, which is used to build GCC for use with a
windows style library and tool set and uses the Microsoft tools.
Copyright (C) 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -21,17 +21,17 @@ 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. */
/* Most of this is the same as for Cygwin32, except for changing some
/* Most of this is the same as for cygwin, except for changing some
specs. */
#include "i386/cygwin32.h"
#include "i386/cygwin.h"
/* Please keep changes to CPP_PREDEFINES in sync with i386/crtdll. The
only difference between the two should be __MSVCRT__ needed to
distinguish MSVC from CRTDLL runtime in mingw headers. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \
-D__MINGW32__ -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__MINGW32__=0.2 -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
-D_stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
@ -44,25 +44,24 @@ Boston, MA 02111-1307, USA. */
#define STANDARD_INCLUDE_COMPONENT "MINGW32"
#undef CPP_SPEC
#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE}"
/* For Windows applications, include more libraries, but always include
kernel32. */
#undef LIB_SPEC
#define LIB_SPEC \
"%{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32 -lshell32"
#define LIB_SPEC "%{mwindows:-lgdi32 -lcomdlg32} \
-luser32 -lkernel32 -ladvapi32 -lshell32"
/* Include in the mingw32 libraries with libgcc */
#undef LIBGCC_SPEC
#define LIBGCC_SPEC "-lmingw32 -lgcc -lmoldname -lmsvcrt"
/* Specify a different entry point when linking a DLL */
#undef LINK_SPEC
#define LINK_SPEC \
"%{mwindows:--subsystem windows} %{mdll:--dll -e _DllMainCRTStartup@12}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{mdll:dllcrt2%O%s} %{!mdll:crt2%O%s}"
#define MATH_LIBRARY "-lmsvcrt"
/* MS runtime does not need a separate math library. */
#define MATH_LIBRARY ""
/* Output STRING, a string representing a filename, to FILE. We canonicalize
it to be in MS-DOS format. */

View File

@ -16,7 +16,8 @@ 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* I believe in reuse... */
#include "i386/linux.h"

View File

@ -1,6 +1,3 @@
/* This goes away when the math-emulator is fixed */
#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */
/* This is tested by i386gas.h. */
#define YES_UNDERSCORES
@ -12,6 +9,11 @@
/* Get generic NetBSD definitions. */
#include <netbsd.h>
/* This goes away when the math-emulator is fixed */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dunix -Di386 -D__NetBSD__ -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386)"

View File

@ -1,5 +1,5 @@
/* Target definitions for GNU compiler for Intel x86 CPU running NeXTSTEP
Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1993, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
/* By default, target has a 80387, with IEEE FP. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (1|0100)
#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP)
/* Implicit library calls should use memcpy, not bcopy, etc. */

View File

@ -31,6 +31,11 @@ Boston, MA 02111-1307, USA. */
#define OBSD_OLD_GAS
#include <openbsd.h>
/* This goes away when the math-emulator is fixed */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387)
/* Run-time target specifications */
#define CPP_PREDEFINES "-D__unix__ -D__i386__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(i386) -Amachine(i386)"
@ -120,9 +125,10 @@ Boston, MA 02111-1307, USA. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
if ((LOG) != 0) \
if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
} \
} while (0)
#endif

View File

@ -121,8 +121,8 @@ extern char *sys_siglist[];
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "mcount", -MASK_NO_MCOUNT}, \
{ "no-mcount", MASK_NO_MCOUNT},
{ "mcount", -MASK_NO_MCOUNT, "Profiling uses mcount" }, \
{ "no-mcount", MASK_NO_MCOUNT, "" },
/* This macro generates the assembly code for function entry.
FILE is a stdio stream to output the code to.

View File

@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler.
Intel 386 (OSF/1 with OSF/rose) version.
Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -43,7 +43,6 @@ Boston, MA 02111-1307, USA. */
#define MASK_HALF_PIC 010000000000 /* Mask for half-pic code */
#define MASK_HALF_PIC_DEBUG 004000000000 /* Debug flag */
#define MASK_ELF 002000000000 /* ELF not rose */
#define MASK_NO_IDENT 001000000000 /* suppress .ident */
#define MASK_NO_UNDERSCORES 000400000000 /* suppress leading _ */
#define MASK_LARGE_ALIGN 000200000000 /* align to >word boundaries */
#define MASK_NO_MCOUNT 000100000000 /* profiling uses mcount_ptr */
@ -53,28 +52,25 @@ Boston, MA 02111-1307, USA. */
#define HALF_PIC_DEBUG TARGET_DEBUG
#define TARGET_ELF (target_flags & MASK_ELF)
#define TARGET_ROSE ((target_flags & MASK_ELF) == 0)
#define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0)
#define TARGET_UNDERSCORES ((target_flags & MASK_NO_UNDERSCORES) == 0)
#define TARGET_LARGE_ALIGN (target_flags & MASK_LARGE_ALIGN)
#define TARGET_MCOUNT ((target_flags & MASK_NO_MCOUNT) == 0)
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "half-pic", MASK_HALF_PIC}, \
{ "no-half-pic", -MASK_HALF_PIC}, \
{ "debug-half-pic", MASK_HALF_PIC_DEBUG}, \
{ "debugb", MASK_HALF_PIC_DEBUG}, \
{ "elf", MASK_ELF}, \
{ "rose", -MASK_ELF}, \
{ "ident", -MASK_NO_IDENT}, \
{ "no-ident", MASK_NO_IDENT}, \
{ "underscores", -MASK_NO_UNDERSCORES}, \
{ "no-underscores", MASK_NO_UNDERSCORES}, \
{ "large-align", MASK_LARGE_ALIGN}, \
{ "no-large-align", -MASK_LARGE_ALIGN}, \
{ "mcount", -MASK_NO_MCOUNT}, \
{ "mcount-ptr", MASK_NO_MCOUNT}, \
{ "no-mcount", MASK_NO_MCOUNT},
{ "half-pic", MASK_HALF_PIC, "Emit half-PIC code" }, \
{ "no-half-pic", -MASK_HALF_PIC, "" } \
{ "debug-half-pic", MASK_HALF_PIC_DEBUG, 0 /* intentionally undoc */ }, \
{ "debugb", MASK_HALF_PIC_DEBUG, 0 /* intentionally undoc */ }, \
{ "elf", MASK_ELF, "Emit ELF object code" }, \
{ "rose", -MASK_ELF, "Emit ROSE object code" }, \
{ "underscores", -MASK_NO_UNDERSCORES, "Symbols have a leading underscore" }, \
{ "no-underscores", MASK_NO_UNDERSCORES, "" }, \
{ "large-align", MASK_LARGE_ALIGN, "Align to >word boundaries" }, \
{ "no-large-align", -MASK_LARGE_ALIGN, "" }, \
{ "mcount", -MASK_NO_MCOUNT, "Use mcount for profiling" }, \
{ "mcount-ptr", MASK_NO_MCOUNT, "Use mcount_ptr for profiling" }, \
{ "no-mcount", MASK_NO_MCOUNT, "" },
/* OSF/rose uses stabs, not dwarf. */
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
@ -752,7 +748,7 @@ do \
if (HALF_PIC_P ()) \
HALF_PIC_FINISH (STREAM); \
\
if (TARGET_IDENT) \
if (!flag_no_ident) \
{ \
char *fstart = main_input_filename; \
char *fname; \

View File

@ -1,5 +1,5 @@
/* Definitions for Intel 386 running SCO Unix System V.
Copyright (C) 1988, 1992, 1994, 1995 Free, 1996 Software Foundation, Inc.
Copyright (C) 1988, 92, 94, 95, 96, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */
So don't make TARGET_IEEE_FP default for SCO. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0201
#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Let's guess that the SCO software FPU emulator can't handle
80-bit XFmode insns, so don't generate them. */

View File

@ -1,5 +1,5 @@
/* Definitions for Intel 386 running SCO Unix System V 3.2 Version 5.
Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Copyright (C) 1992, 95-98, 1999 Free Software Foundation, Inc.
Contributed by Kean Johnston (hug@netcom.com)
This file is part of GNU CC.
@ -211,8 +211,9 @@ do { \
#undef ASM_FILE_END
#define ASM_FILE_END(FILE) \
do { \
fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \
IDENT_ASM_OP, version_string); \
if (!flag_no_ident) \
fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \
IDENT_ASM_OP, version_string); \
} while (0)
#undef ASM_FINISH_DECLARE_OBJECT
@ -689,7 +690,9 @@ dtors_section () \
#undef SELECT_SECTION
#define SELECT_SECTION(DECL,RELOC) \
{ \
if (TREE_CODE (DECL) == STRING_CST) \
if (TARGET_ELF && flag_pic && RELOC) \
data_section (); \
else if (TREE_CODE (DECL) == STRING_CST) \
{ \
if (! flag_writable_strings) \
const_section (); \
@ -698,11 +701,7 @@ dtors_section () \
} \
else if (TREE_CODE (DECL) == VAR_DECL) \
{ \
if ((TARGET_ELF && flag_pic && RELOC) \
|| !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \
|| !DECL_INITIAL (DECL) \
|| (DECL_INITIAL (DECL) != error_mark_node \
&& !TREE_CONSTANT (DECL_INITIAL (DECL)))) \
if (! DECL_READONLY_SECTION (DECL, RELOC)) \
data_section (); \
else \
const_section (); \
@ -726,11 +725,19 @@ dtors_section () \
&& strcmp (STR, "Tbss"))
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0301
#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
#undef HANDLE_SYSV_PRAGMA
#define HANDLE_SYSV_PRAGMA 1
/* Though OpenServer support .weak in COFF, g++ doesn't play nice with it
* so we'll punt on it for now
*/
#define SUPPORTS_WEAK (TARGET_ELF)
#define ASM_WEAKEN_LABEL(FILE,NAME) \
do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
fputc ('\n', FILE); } while (0)
#undef SCCS_DIRECTIVE
#define SCCS_DIRECTIVE 1
@ -904,11 +911,23 @@ dtors_section () \
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "coff", MASK_COFF }, \
{ "elf", -MASK_COFF },
{ "coff", MASK_COFF, "Generate COFF output" }, \
{ "elf", -MASK_COFF, "Generate ELF output" },
#define NO_DOLLAR_IN_LABEL
/* Implicit library calls should use memcpy, not bcopy, etc. They are
faster on OpenServer libraries. */
#define TARGET_MEM_FUNCTIONS
/* Biggest alignment supported by the object file format of this
machine. Use this macro to limit the alignment which can be
specified using the `__attribute__ ((aligned (N)))' construct. If
not defined, the default value is `BIGGEST_ALIGNMENT'. */
#define MAX_OFILE_ALIGNMENT (32768*8)
/*
Here comes some major hackery to get the crt stuff to compile properly.
Since we can (and do) compile for both COFF and ELF environments, we

View File

@ -1,6 +1,6 @@
/* Definitions for Intel 386 running SCO Unix System V,
using dbx-in-coff encapsulation.
Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
So don't make TARGET_IEEE_FP default for SCO. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0201
#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Use crt1.o as a startup file and crtn.o as a closing file. */

View File

@ -1,5 +1,5 @@
/* Definitions for Sequent Intel 386.
Copyright (C) 1988, 1994 Free Software Foundation, Inc.
Copyright (C) 1988, 1994, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -26,11 +26,10 @@ Boston, MA 02111-1307, USA. */
/* By default, don't use IEEE compatible arithmetic comparisons
because the assembler can't handle the fucom insn.
Return float values in the 387.
(TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) */
Return float values in the 387. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 0201
#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS)
/* Specify predefined symbols in preprocessor. */

View File

@ -93,3 +93,6 @@ Boston, MA 02111-1307, USA. */
|| (CHAR) == 'z')
#define STDC_0_IN_SYSTEM_HEADERS
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."

View File

@ -59,11 +59,11 @@ do \
do { \
extern char *version_string, *language_string; \
{ \
int len = strlen (dump_base_name); \
char *na = dump_base_name + len; \
int len = strlen (main_input_filename); \
char *na = main_input_filename + len; \
char shorter[15]; \
/* NA gets DUMP_BASE_NAME sans directory names. */\
while (na > dump_base_name) \
/* NA gets MAIN_INPUT_FILENAME sans directory names. */\
while (na > main_input_filename) \
{ \
if (na[-1] == '/') \
break; \

View File

@ -0,0 +1,35 @@
/* Definitions for Intel 386 running System V Release 5 (i.e. UnixWare 7)
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Robert Lipe (robertlipe@usa.net)
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.
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. */
#include "i386/sysv4.h"
/* Dwarf2 is supported by native debuggers */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
/* Add -lcrt for Dwarf2 abbreviation table */
#undef LIB_SPEC
#define LIB_SPEC "%{pthread:-lthread} %{!shared:%{!symbolic:-lc -lcrt}}"
#undef CPP_SPEC
#define CPP_SPEC "%{pthread:-D_REENTRANT}"

View File

@ -0,0 +1,16 @@
LIBGCC1 = libgcc1-asm.a
CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = i386/cygwin.asm
LIB1ASMFUNCS = _chkstk
# cygwin always has a limits.h, but, depending upon how we are doing
# the build, it may not be installed yet.
LIMITS_H_TEST = true
# If we are building next to winsup, this will let us find the real
# limits.h when building libgcc2. Otherwise, winsup must be installed
# first.
LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/include
winnt.o: $(srcdir)/config/i386/winnt.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c

View File

@ -1,4 +1,8 @@
#
# target makefile for dgux
#
EXTRA_PARTS=crtbegin.o crtend.o
EXTRA_PARTS=crti.o crtbegin.o crtend.o
crti.o: $(srcdir)/config/i386/sol2-ci.asm $(GCC_PASSES)
sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s
$(GCC_FOR_TARGET) -c -o crti.o crti.s

View File

@ -0,0 +1,2 @@
LIBGCC1 = libgcc1.null
CROSS_LIBGCC1 = libgcc1.null

View File

@ -0,0 +1,16 @@
# t-interix
LIBGCC1 = libgcc1-asm.a
CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = i386/cygwin.asm
LIB1ASMFUNCS = _chkstk
interix.o: $(srcdir)/config/i386/interix.c
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/interix.c
# System headers will track gcc's needs.
# Even LANG_EXTRA_HEADERS may be temporary.
USER_H=$(LANG_EXTRA_HEADERS)
# We don't want this one either.
INSTALL_ASSERT_H=

Some files were not shown because too many files have changed in this diff Show More