Update in-tree GCC to 3.4.4.
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Tue, 24 May 2005 06:29:33 +0000 (06:29 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Tue, 24 May 2005 06:29:33 +0000 (06:29 +0000)
106 files changed:
contrib/gcc-3.4/BUGS
contrib/gcc-3.4/LAST_UPDATED
contrib/gcc-3.4/MAINTAINERS
contrib/gcc-3.4/README.DELETED
contrib/gcc-3.4/README.SCO
contrib/gcc-3.4/gcc/attribs.c
contrib/gcc-3.4/gcc/builtins.c
contrib/gcc-3.4/gcc/c-common.c
contrib/gcc-3.4/gcc/c-decl.c
contrib/gcc-3.4/gcc/c-format.c
contrib/gcc-3.4/gcc/c-opts.c
contrib/gcc-3.4/gcc/c-ppoutput.c
contrib/gcc-3.4/gcc/c-semantics.c
contrib/gcc-3.4/gcc/c-typeck.c
contrib/gcc-3.4/gcc/c.opt
contrib/gcc-3.4/gcc/calls.c
contrib/gcc-3.4/gcc/collect2.c
contrib/gcc-3.4/gcc/combine.c
contrib/gcc-3.4/gcc/config/i386/i386-modes.def
contrib/gcc-3.4/gcc/config/i386/i386-protos.h
contrib/gcc-3.4/gcc/config/i386/i386.c
contrib/gcc-3.4/gcc/config/i386/i386.h
contrib/gcc-3.4/gcc/config/i386/i386.md
contrib/gcc-3.4/gcc/cp/call.c
contrib/gcc-3.4/gcc/cp/class.c
contrib/gcc-3.4/gcc/cp/cp-tree.h
contrib/gcc-3.4/gcc/cp/cvt.c
contrib/gcc-3.4/gcc/cp/decl.c
contrib/gcc-3.4/gcc/cp/init.c
contrib/gcc-3.4/gcc/cp/method.c
contrib/gcc-3.4/gcc/cp/name-lookup.c
contrib/gcc-3.4/gcc/cp/parser.c
contrib/gcc-3.4/gcc/cp/pt.c
contrib/gcc-3.4/gcc/cp/semantics.c
contrib/gcc-3.4/gcc/cp/tree.c
contrib/gcc-3.4/gcc/cp/typeck.c
contrib/gcc-3.4/gcc/cp/typeck2.c
contrib/gcc-3.4/gcc/cppfiles.c
contrib/gcc-3.4/gcc/cpplib.c
contrib/gcc-3.4/gcc/cppmacro.c
contrib/gcc-3.4/gcc/dbxout.c
contrib/gcc-3.4/gcc/defaults.h
contrib/gcc-3.4/gcc/doc/extend.texi
contrib/gcc-3.4/gcc/doc/include/gcc-common.texi
contrib/gcc-3.4/gcc/doc/install.texi
contrib/gcc-3.4/gcc/doc/invoke.texi
contrib/gcc-3.4/gcc/doc/md.texi
contrib/gcc-3.4/gcc/doc/tm.texi
contrib/gcc-3.4/gcc/dojump.c
contrib/gcc-3.4/gcc/dwarf2out.c
contrib/gcc-3.4/gcc/emit-rtl.c
contrib/gcc-3.4/gcc/explow.c
contrib/gcc-3.4/gcc/expr.c
contrib/gcc-3.4/gcc/expr.h
contrib/gcc-3.4/gcc/f/news.texi
contrib/gcc-3.4/gcc/flow.c
contrib/gcc-3.4/gcc/fold-const.c
contrib/gcc-3.4/gcc/function.c
contrib/gcc-3.4/gcc/gcc.c
contrib/gcc-3.4/gcc/gcov-io.h
contrib/gcc-3.4/gcc/ifcvt.c
contrib/gcc-3.4/gcc/libgcc2.c
contrib/gcc-3.4/gcc/libgcc2.h
contrib/gcc-3.4/gcc/loop-unroll.c
contrib/gcc-3.4/gcc/loop.c
contrib/gcc-3.4/gcc/objc/objc-act.c
contrib/gcc-3.4/gcc/params.def
contrib/gcc-3.4/gcc/params.h
contrib/gcc-3.4/gcc/predict.c
contrib/gcc-3.4/gcc/real.c
contrib/gcc-3.4/gcc/reg-stack.c
contrib/gcc-3.4/gcc/regrename.c
contrib/gcc-3.4/gcc/reload.c
contrib/gcc-3.4/gcc/reload1.c
contrib/gcc-3.4/gcc/simplify-rtx.c
contrib/gcc-3.4/gcc/toplev.c
contrib/gcc-3.4/gcc/tree-inline.c
contrib/gcc-3.4/gcc/tree.h
contrib/gcc-3.4/gcc/unwind-dw2.c
contrib/gcc-3.4/gcc/varasm.c
contrib/gcc-3.4/gcc/version.c
contrib/gcc-3.4/libiberty/ChangeLog
contrib/gcc-3.4/libiberty/cp-demangle.c
contrib/gcc-3.4/libobjc/ChangeLog
contrib/gcc-3.4/libobjc/gc.c
contrib/gcc-3.4/libstdc++-v3/ChangeLog
contrib/gcc-3.4/libstdc++-v3/config/io/basic_file_stdio.cc
contrib/gcc-3.4/libstdc++-v3/config/io/c_io_stdio.h
contrib/gcc-3.4/libstdc++-v3/config/linker-map.gnu
contrib/gcc-3.4/libstdc++-v3/config/locale/generic/c_locale.h
contrib/gcc-3.4/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h
contrib/gcc-3.4/libstdc++-v3/include/bits/basic_string.h
contrib/gcc-3.4/libstdc++-v3/include/bits/c++config
contrib/gcc-3.4/libstdc++-v3/include/bits/fstream.tcc
contrib/gcc-3.4/libstdc++-v3/include/bits/ios_base.h
contrib/gcc-3.4/libstdc++-v3/include/bits/locale_facets.h
contrib/gcc-3.4/libstdc++-v3/include/bits/locale_facets.tcc
contrib/gcc-3.4/libstdc++-v3/include/bits/stl_algobase.h
contrib/gcc-3.4/libstdc++-v3/include/bits/stl_list.h
contrib/gcc-3.4/libstdc++-v3/include/bits/stl_tree.h
contrib/gcc-3.4/libstdc++-v3/include/bits/vector.tcc
contrib/gcc-3.4/libstdc++-v3/include/ext/rope
contrib/gcc-3.4/libstdc++-v3/include/std/std_complex.h
contrib/gcc-3.4/libstdc++-v3/libsupc++/eh_globals.cc
contrib/gcc-3.4/libstdc++-v3/src/debug.cc
contrib/gcc-3.4/libstdc++-v3/src/ios.cc

index e4de179..37252d8 100644 (file)
@@ -31,12 +31,12 @@ Table of Contents
 
    The  main  purpose of a bug report is to enable us to fix the bug. The
    most  important  prerequisite  for  this  is  that  the report must be
-   complete and self-contained, which we explain in detail below.
+   complete and self-contained.
 
    Before  you report a bug, please check the [19]list of well-known bugs
-   and,  if  possible  in any way, try a current development snapshot. If
-   you  want  to report a bug with versions of GCC before 3.1 we strongly
-   recommend upgrading to the current release first.
+   and,  if  possible, try a current development snapshot. If you want to
+   report  a  bug  with  versions of GCC before 3.4 we strongly recommend
+   upgrading to the current release first.
 
    Before  reporting  that  GCC  compiles  your  code incorrectly, please
    compile  it  with  gcc -Wall and see whether this shows anything wrong
@@ -81,9 +81,6 @@ Summarized bug reporting instructions
        compiled,  such that retrying a sufficient number of times results
        in  a  successful  compilation;  this  is  a symptom of a hardware
        problem, not of a compiler bug (sorry)
-     * E-mail  messages that complement previous, incomplete bug reports.
-       Post  a  new, self-contained, full bug report instead, if possible
-       as a follow-up to the original bug report
      * Assembly  files  (*.s)  produced  by  the  compiler, or any binary
        files,   such   as  object  files,  executables,  core  files,  or
        precompiled header files
@@ -119,15 +116,6 @@ Detailed bug reporting instructions
 
      gcc -v -save-temps all-your-options source-file
 
-   Typically  the  preprocessed  file (extension .i for C or .ii for C++,
-   and .f if the preprocessor is used on Fortran files) will be large, so
-   please compress the resulting file with one of the popular compression
-   programs  such as bzip2, gzip, zip or compress (in decreasing order of
-   preference). Use maximum compression (-9) if available. Please include
-   the  compressed  preprocessor  output  in your bug report, even if the
-   source  code  is  freely  available elsewhere; it makes the job of our
-   volunteer testers much easier.
-
    The  only  excuses  to not send us the preprocessed sources are (i) if
    you've  found  a  bug  in the preprocessor, (ii) if you've reduced the
    testcase  to a small file that doesn't include any other file or (iii)
@@ -140,12 +128,6 @@ Detailed bug reporting instructions
    although  you  may want to post parts of it to point out assembly code
    you consider to be wrong.
 
-   Whether to use MIME attachments or uuencode is up to you. In any case,
-   make  sure  the compiler command line, version and error output are in
-   plain text, so that we don't have to decode the bug report in order to
-   tell  who  should  take  care  of  it. A meaningful subject indicating
-   language and platform also helps.
-
    Please  avoid  posting  an archive (.tar, .shar or .zip); we generally
    need   just  a  single  file  to  reproduce  the  bug  (the  .i/.ii/.f
    preprocessed  file),  and,  by  storing  it in an archive, you're just
@@ -158,16 +140,6 @@ Detailed bug reporting instructions
    included  in  the  body  of  your  bug  report  as plain text, even if
    needlessly duplicated as part of an archive.
 
-   If  you  fail  to  supply  enough  information  for a bug report to be
-   reproduced,   someone   will  probably  ask  you  to  post  additional
-   information  (or just ignore your bug report, if they're in a bad day,
-   so  try to get it right on the first posting :-). In this case, please
-   post the additional information to the bug reporting mailing list, not
-   just  to  the  person  who requested it, unless explicitly told so. If
-   possible, please include in this follow-up all the information you had
-   supplied  in  the  incomplete  bug  report (including the preprocessor
-   output), so that the new bug report is self-contained.
-
 Detailed bug reporting instructions for GNAT
 
    See  the  [24]previous  section for bug reporting instructions for GCC
@@ -837,4 +809,4 @@ References
   36. http://www.ncits.org/cplusplus.htm
   37. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html
   38. http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html
-  39. http://gcc.gnu.org/onlinedocs/gcc/C---Misunderstandings.html
+  39. http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Misunderstandings.html
index e25a3dc..84fb90f 100644 (file)
@@ -1 +1 @@
-Obtained from CVS: -rgcc_3_4_3_release 
+Obtained from CVS: -rgcc_3_4_4_release 
index 71d343e..b7bb69b 100644 (file)
@@ -209,7 +209,7 @@ Doug Evans                                  dje@transmeta.com
 Kaveh Ghazi                                    ghazi@caip.rutgers.edu
 Matthew Gingell                                        gingell@gnat.com
 Anthony Green                                  green@redhat.com
-Laurent Guerby                                 guerby@acm.org
+Laurent Guerby                                 laurent@guerby.net
 Olivier Hainque                                        hainque@act-europe.fr
 Stuart Hastings                                        stuart@apple.com
 Matthew Hiller                                 hiller@redhat.com
index 07b3093..5af4cf2 100644 (file)
@@ -3,6 +3,7 @@
 ./ChangeLog
 ./INSTALL
 ./MD5SUMS
+./NEWS
 ./Makefile.def
 ./Makefile.in
 ./Makefile.tpl
@@ -42,6 +43,8 @@
 ./gcc/README.Portability
 ./gcc/aclocal.m4
 ./gcc/c-config-lang.in
+./gcc/c-parse.c
+./gcc/c-parse.y
 ./gcc/config.build
 ./gcc/config.gcc
 ./gcc/config.host
 ./gcc/config/t-libc-ok
 ./gcc/config/t-libgcc-pic
 ./gcc/config/t-libunwind
+./gcc/config/t-libunwind-elf
 ./gcc/config/t-linux
 ./gcc/config/t-linux-gnulibc1
 ./gcc/config/t-netbsd
 ./gcc/cppucnid.tab
 ./gcc/cstamp-h.in
 ./gcc/doc/install.texi2html
+./gcc/doc/cpp.1
+./gcc/doc/cpp.info
+./gcc/doc/cppinternals.info
+./gcc/doc/fsf-funding.7
+./gcc/doc/g++.1
+./gcc/doc/g77.1
+./gcc/doc/g77.info
+./gcc/doc/gcc.1
+./gcc/doc/gcc.info
+./gcc/doc/gccinstall.info
+./gcc/doc/gccint.info
+./gcc/doc/gcj.1
+./gcc/doc/gcj.info
+./gcc/doc/gcjh.1
+./gcc/doc/gcov.1
+./gcc/doc/gfdl.7
+./gcc/doc/gij.1
+./gcc/doc/gpl.7
+./gcc/doc/jcf-dump.1
+./gcc/doc/jv-convert.1
+./gcc/doc/jv-scan.1
+./gcc/doc/rmic.1
+./gcc/doc/rmiregistry.1
+./gcc/f/BUGS
 ./gcc/f/ChangeLog
 ./gcc/f/ChangeLog.0
 ./gcc/f/Make-lang.in
+./gcc/f/NEWS
 ./gcc/f/RELEASE-PREP
 ./gcc/f/config-lang.in
 ./gcc/fixinc
 ./gcc/fixproto
 ./gcc/gccbug.in
 ./gcc/gdbinit.in
+./gcc/gengtype-lex.c
+./gcc/gengtype-yacc.c
+./gcc/gengtype-yacc.h
 ./gcc/ginclude
 ./gcc/libgcc-darwin.ver
 ./gcc/libgcc-std.ver
 ./gcc/move-if-change
 ./gcc/objc/Make-lang.in
 ./gcc/objc/config-lang.in
+./gcc/objc/objc-parse.c
+./gcc/objc/objc-parse.y
 ./gcc/po
 ./gcc/scan-types.sh
 ./gcc/sort-protos
 ./gcc/treelang
+./gcc/unwind-compat.c
+./gcc/unwind-compat.h
+./gcc/unwind-dw2-fde-compat.c
 ./include/ChangeLog
 ./include/floatformat.h
 ./include/fnmatch.h
 ./libiberty/config.h-vms
 ./libiberty/config.in
 ./libiberty/config.table
-./libiberty/config/mh-aix
-./libiberty/config/mh-cxux7
-./libiberty/config/mh-fbsd21
-./libiberty/config/mh-openedition
-./libiberty/config/mh-windows
 ./libiberty/configure
 ./libiberty/configure.ac
 ./libiberty/copying-lib.texi
 ./libobjc/thr-vxworks.c
 ./libobjc/thr-win32.c
 ./libstdc++-v3/.cvsignore
+./libstdc++-v3/ChangeLog-2004
 ./libstdc++-v3/Makefile.am
 ./libstdc++-v3/Makefile.in
 ./libstdc++-v3/acconfig.h
 ./libstdc++-v3/config/cpu/sparc
 ./libstdc++-v3/config/locale/gnu
 ./libstdc++-v3/config/os/aix
-./libstdc++-v3/config/os/bsd/netbsd
+./libstdc++-v3/config/os/bsd/freebsd
 ./libstdc++-v3/config/os/djgpp
 ./libstdc++-v3/config/os/gnu-linux
 ./libstdc++-v3/config/os/hpux
 ./libstdc++-v3/crossconfig.m4
 ./libstdc++-v3/docs
 ./libstdc++-v3/fragment.am
+./libstdc++-v3/include/Makefile.am
+./libstdc++-v3/include/Makefile.in
 ./libstdc++-v3/libmath/Makefile.am
 ./libstdc++-v3/libmath/Makefile.in
 ./libstdc++-v3/libsupc++/Makefile.am
index 6b28fe3..1c32590 100644 (file)
@@ -6,5 +6,4 @@ no longer believe that SCO is a serious threat.
 For more on the FSF's position regarding SCO's attacks on free
 software, please read:
 
-  http://www.gnu.org/philosophy/sco/sco.html
-
+  http://www.fsf.org/licensing/sco/
index a40fea7..3286bf3 100644 (file)
@@ -266,6 +266,8 @@ decl_attributes (tree *node, tree attributes, int flags)
          /* Force a recalculation of mode and size.  */
          DECL_MODE (*node) = VOIDmode;
          DECL_SIZE (*node) = 0;
+         if (!DECL_USER_ALIGN (*node))
+           DECL_ALIGN (*node) = 0;
 
          layout_decl (*node, 0);
        }
index dadb6cd..a3e069e 100644 (file)
@@ -1708,6 +1708,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
       narg = save_expr (arg);
       if (narg != arg)
        {
+         arg = narg;
          arglist = build_tree_list (NULL_TREE, arg);
          exp = build_function_call_expr (fndecl, arglist);
        }
@@ -1840,6 +1841,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
   narg = save_expr (arg1);
   if (narg != arg1)
     {
+      arg1 = narg;
       temp = build_tree_list (NULL_TREE, narg);
       stable = false;
     }
@@ -1849,6 +1851,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
   narg = save_expr (arg0);
   if (narg != arg0)
     {
+      arg0 = narg;
       arglist = tree_cons (NULL_TREE, narg, temp);
       stable = false;
     }
@@ -6581,7 +6584,7 @@ fold_builtin (tree exp)
              return build_function_call_expr (expfn, arglist);
            }
 
-         /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
+         /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
          if (flag_unsafe_math_optimizations
              && (fcode == BUILT_IN_POW
                  || fcode == BUILT_IN_POWF
@@ -6590,8 +6593,11 @@ fold_builtin (tree exp)
              tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
              tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
              tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
-             tree narg1 = fold (build (MULT_EXPR, type, arg1,
-                                       build_real (type, dconsthalf)));
+             tree narg1;
+             if (!tree_expr_nonnegative_p (arg0))
+               arg0 = build1 (ABS_EXPR, type, arg0);
+             narg1 = fold (build (MULT_EXPR, type, arg1,
+                                  build_real (type, dconsthalf)));
              arglist = tree_cons (NULL_TREE, arg0,
                                   build_tree_list (NULL_TREE, narg1));
              return build_function_call_expr (powfn, arglist);
index ff78e41..d79f200 100644 (file)
@@ -1137,7 +1137,7 @@ fname_decl (unsigned int rid, tree id)
       input_line = saved_lineno;
     }
   if (!ix && !current_function_decl)
-    pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
+    pedwarn ("'%D' is not defined outside of function scope", decl);
 
   return decl;
 }
@@ -4678,6 +4678,33 @@ handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
                                                        mode);
              *node = ptr_type;
            }
+         else if (TREE_CODE (type) == ENUMERAL_TYPE)
+           {
+             /* For enumeral types, copy the precision from the integer
+                type returned above.  If not an INTEGER_TYPE, we can't use
+                this mode for this type.  */
+             if (TREE_CODE (typefm) != INTEGER_TYPE)
+               {
+                 error ("cannot use mode %qs for enumeral types", p);
+                 return NULL_TREE;
+               }
+
+             if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+               type = build_type_copy (type);
+
+             /* We cannot use layout_type here, because that will attempt
+                to re-layout all variants, corrupting our original.  */
+             TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+             TYPE_MIN_VALUE (type) = TYPE_MIN_VALUE (typefm);
+             TYPE_MAX_VALUE (type) = TYPE_MAX_VALUE (typefm);
+             TYPE_SIZE (type) = TYPE_SIZE (typefm);
+             TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (typefm);
+             TYPE_MODE (type) = TYPE_MODE (typefm);
+             if (!TYPE_USER_ALIGN (type))
+               TYPE_ALIGN (type) = TYPE_ALIGN (typefm);
+
+             *node = type;
+           }
          else if (VECTOR_MODE_P (mode)
                   ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
                   : TREE_CODE (type) != TREE_CODE (typefm))
index 88e097b..619b221 100644 (file)
@@ -3620,10 +3620,6 @@ grokdeclarator (tree declarator, tree declspecs,
        }
     }
 
-  /* Check the type and width of a bit-field.  */
-  if (bitfield)
-    check_bitfield_type_and_width (&type, width, orig_name);
-
   /* 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
@@ -4133,6 +4129,10 @@ grokdeclarator (tree declarator, tree declspecs,
 
   /* Now TYPE has the actual type.  */
 
+  /* Check the type and width of a bit-field.  */
+  if (bitfield)
+    check_bitfield_type_and_width (&type, width, orig_name);
+
   /* Did array size calculations overflow?  */
 
   if (TREE_CODE (type) == ARRAY_TYPE
@@ -5132,7 +5132,7 @@ finish_struct (tree t, tree fieldlist, tree attributes)
      make it one, warn and turn off the flag.  */
   if (TREE_CODE (t) == UNION_TYPE
       && TYPE_TRANSPARENT_UNION (t)
-      && TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))
+      && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
     {
       TYPE_TRANSPARENT_UNION (t) = 0;
       warning ("union cannot be made transparent");
@@ -5284,9 +5284,19 @@ finish_enum (tree enumtype, tree values, tree attributes)
 
   TYPE_MIN_VALUE (enumtype) = minnode;
   TYPE_MAX_VALUE (enumtype) = maxnode;
-  TYPE_PRECISION (enumtype) = precision;
   TREE_UNSIGNED (enumtype) = unsign;
   TYPE_SIZE (enumtype) = 0;
+
+  /* If the precision of the type was specific with an attribute and it
+     was too small, give an error.  Otherwise, use it.  */
+  if (TYPE_PRECISION (enumtype))
+    {
+      if (precision > TYPE_PRECISION (enumtype))
+       error ("specified mode too small for enumeral values");
+    }
+  else
+    TYPE_PRECISION (enumtype) = precision;
+
   layout_type (enumtype);
 
   if (values != error_mark_node)
index a532259..620277f 100644 (file)
@@ -2518,9 +2518,27 @@ init_dynamic_asm_fprintf_info (void)
         length modifier to work, one must have issued: "typedef
         HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
         prior to using that modifier.  */
-      if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__"))
-         || !(hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi))))
+      hwi = maybe_get_identifier ("__gcc_host_wide_int__");
+      if (!hwi)
+       {
+         error ("'__gcc_host_wide_int__' is not defined as a type");
+         return;
+       }
+      hwi = identifier_global_value (hwi);
+      if (!hwi || TREE_CODE (hwi) != TYPE_DECL)
+       {
+         error ("'__gcc_host_wide_int__' is not defined as a type");
+         return;
+       }
+      hwi = DECL_ORIGINAL_TYPE (hwi);
+      if (!hwi)
        abort ();
+      if (hwi != long_integer_type_node && hwi != long_long_integer_type_node)
+       {
+         error ("'__gcc_host_wide_int__' is not defined as 'long'"
+                " or 'long long'");
+         return;
+       }
 
       /* Create a new (writable) copy of asm_fprintf_length_specs.  */
       new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
@@ -2563,19 +2581,71 @@ init_dynamic_diag_info (void)
         However we don't force a hard ICE because we may see only one
         or the other type.  */
       if ((loc = maybe_get_identifier ("location_t")))
-       loc = TREE_TYPE (identifier_global_value (loc));
+       {
+         loc = identifier_global_value (loc);
+         if (loc)
+           {
+             if (TREE_CODE (loc) != TYPE_DECL)
+               {
+                 error ("'location_t' is not defined as a type");
+                 loc = 0;
+               }
+             else
+               loc = TREE_TYPE (loc);
+           }
+       }
 
       /* We need to grab the underlying `union tree_node' so peek into
         an extra type level.  */
       if ((t = maybe_get_identifier ("tree")))
-       t = TREE_TYPE (TREE_TYPE (identifier_global_value (t)));
+       {
+         t = identifier_global_value (t);
+         if (t)
+           {
+             if (TREE_CODE (t) != TYPE_DECL)
+               {
+                 error ("'tree' is not defined as a type");
+                 t = 0;
+               }
+             else if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
+               {
+                 error ("'tree' is not defined as a pointer type");
+                 t = 0;
+               }
+             else
+               t = TREE_TYPE (TREE_TYPE (t));
+           }
+       }
     
       /* Find the underlying type for HOST_WIDE_INT.  For the %w
         length modifier to work, one must have issued: "typedef
         HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
         prior to using that modifier.  */
       if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
-       hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
+       {
+         hwi = identifier_global_value (hwi);
+         if (hwi)
+           {
+             if (TREE_CODE (hwi) != TYPE_DECL)
+               {
+                 error ("'__gcc_host_wide_int__' is not defined as a type");
+                 hwi = 0;
+               }
+             else
+               {
+                 hwi = DECL_ORIGINAL_TYPE (hwi);
+                 if (!hwi)
+                   abort ();
+                 if (hwi != long_integer_type_node
+                     && hwi != long_long_integer_type_node)
+                   {
+                     error ("'__gcc_host_wide_int__' is not defined"
+                            " as 'long' or 'long long'");
+                     hwi = 0;
+                   }
+               }
+           }
+       }
       
       /* Assign the new data for use.  */
 
index 5a351d9..2a61744 100644 (file)
@@ -1168,8 +1168,12 @@ c_common_post_options (const char **pfilename)
 
   *pfilename = this_input_filename
     = cpp_read_main_file (parse_in, in_fnames[0]);
+  /* Don't do any compilation or preprocessing if there is no input file.  */
   if (this_input_filename == NULL)
-    return true;
+    {
+      errorcount++;
+      return false;
+    }
 
   if (flag_working_directory
       && flag_preprocess_only && ! flag_no_line_commands)
@@ -1358,11 +1362,13 @@ sanitize_cpp_opts (void)
 
   /* Disable -dD, -dN and -dI if normal output is suppressed.  Allow
      -dM since at least glibc relies on -M -dM to work.  */
+  /* Also, flag_no_output implies flag_no_line_commands, always. */
   if (flag_no_output)
     {
       if (flag_dump_macros != 'M')
        flag_dump_macros = 0;
       flag_dump_includes = 0;
+      flag_no_line_commands = 1;
     }
 
   cpp_opts->unsigned_char = !flag_signed_char;
index 5588da3..8162ccb 100644 (file)
@@ -359,7 +359,7 @@ pp_file_change (const struct line_map *map)
 {
   const char *flags = "";
 
-  if (flag_no_line_commands || flag_no_output)
+  if (flag_no_line_commands)
     return;
 
   if (map != NULL)
index 080f0c6..692adfc 100644 (file)
@@ -937,6 +937,9 @@ expand_unreachable_if_stmt (tree t)
       return true;
     }
 
+  /* Account for declarations as conditions.  */
+  expand_cond (IF_COND (t));
+
   if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
     {
       n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
index dd06fda..c9479f0 100644 (file)
@@ -647,7 +647,7 @@ same_translation_unit_p (tree t1, tree t2)
   while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
     switch (TREE_CODE_CLASS (TREE_CODE (t2)))
       {
-      case 'd': t2 = DECL_CONTEXT (t1); break;
+      case 'd': t2 = DECL_CONTEXT (t2); break;
       case 't': t2 = TYPE_CONTEXT (t2); break;
       case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
       default: abort ();
@@ -4097,18 +4097,32 @@ digest_init (tree type, tree init, int require_constant)
   /* Build a VECTOR_CST from a *constant* vector constructor.  If the
      vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
      below and handle as a constructor.  */
-    if (code == VECTOR_TYPE
-        && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
-        && TREE_CONSTANT (inside_init))
-      {
-       if (TREE_CODE (inside_init) == VECTOR_CST
-           && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
-                         TYPE_MAIN_VARIANT (type),
-                         COMPARE_STRICT))
-         return inside_init;
-       else
-         return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
-      }
+  if (code == VECTOR_TYPE
+      && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
+      && TREE_CONSTANT (inside_init))
+    {
+      if (TREE_CODE (inside_init) == VECTOR_CST
+         && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+                       TYPE_MAIN_VARIANT (type),
+                       COMPARE_STRICT))
+       return inside_init;
+
+      if (TREE_CODE (inside_init) == CONSTRUCTOR)
+       {
+         tree link;
+         /* Iterate through elements and check if all constructor
+            elements are *_CSTs.  */
+         for (link = CONSTRUCTOR_ELTS (inside_init);
+              link;
+              link = TREE_CHAIN (link))
+           if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (link))) != 'c')
+             break;
+         if (link == NULL)
+           return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
+       }
+    }
 
   /* Any type can be initialized
      from an expression of the same type, optionally with braces.  */
@@ -6551,6 +6565,14 @@ c_finish_case (void)
 {
   struct c_switch *cs = switch_stack;
 
+  /* If we've not seen any case labels (or a default), we may still
+     need to chain any statements that were seen as the SWITCH_BODY.  */
+  if (SWITCH_BODY (cs->switch_stmt) == NULL)
+    {
+      SWITCH_BODY (cs->switch_stmt) = TREE_CHAIN (cs->switch_stmt);
+      TREE_CHAIN (cs->switch_stmt) = NULL_TREE;
+    }
+
   /* Rechain the next statements to the SWITCH_STMT.  */
   last_tree = cs->switch_stmt;
 
index 2a2ff85..7160dab 100644 (file)
@@ -405,7 +405,7 @@ Give strings the type \"array of char\"
 
 ansi
 C ObjC C++ ObjC++
-A synonym for -std=c89.  In a future version of GCC it will become synonymous with -std=c99 instead
+A synonym for -std=c89 (for C) or -std=c++98 (for C++).
 
 d
 C ObjC C++ ObjC++ Joined
@@ -788,7 +788,7 @@ Deprecated in favor of -std=gnu99
 
 std=iso9899:1990
 C ObjC
-Deprecated in favor of -std=c89
+Conform to the ISO 1990 C standard
 
 std=iso9899:199409
 C ObjC
@@ -796,11 +796,11 @@ Conform to the ISO 1990 C standard as amended in 1994
 
 std=iso9899:1999
 C ObjC
-Deprecated in favor of -std=c99
+Conform to the ISO 1999 C standard
 
 std=iso9899:199x
 C ObjC
-Deprecated in favor of -std=c99
+Deprecated in favor of -std=iso9899:1999
 
 traditional-cpp
 C ObjC C++ ObjC++
index 5dc96c6..86e5184 100644 (file)
@@ -1719,8 +1719,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
            use_group_regs (call_fusage, reg);
          else if (nregs == -1)
            use_reg (call_fusage, reg);
-         else
-           use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
+         else if (nregs > 0)
+           use_regs (call_fusage, REGNO (reg), nregs);
        }
     }
 }
@@ -2730,10 +2730,14 @@ expand_call (tree exp, rtx target, int ignore)
         Also, do all pending adjustments now if there is any chance
         this might be a call to alloca or if we are expanding a sibling
         call sequence or if we are calling a function that is to return
-        with stack pointer depressed.  */
+        with stack pointer depressed.
+        Also do the adjustments before a throwing call, otherwise
+        exception handling can fail; PR 19225. */
       if (pending_stack_adjust >= 32
          || (pending_stack_adjust > 0
              && (flags & (ECF_MAY_BE_ALLOCA | ECF_SP_DEPRESSED)))
+         || (pending_stack_adjust > 0
+             && flag_exceptions && !(flags & ECF_NOTHROW))
          || pass == 0)
        do_pending_stack_adjust ();
 
index 4fbe3a4..33206f5 100644 (file)
@@ -189,6 +189,7 @@ static int strip_flag;                      /* true if -s */
 #ifdef COLLECT_EXPORT_LIST
 static int export_flag;                 /* true if -bE */
 static int aix64_flag;                 /* true if -b64 */
+static int aixrtl_flag;                        /* true if -brtl */
 #endif
 
 int debug;                             /* true if -debug */
@@ -246,7 +247,6 @@ static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
 static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
 static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
                                          &libpath_lib_dirs, NULL};
-static const char *const libexts[3] = {"a", "so", NULL};  /* possible library extensions */
 #endif
 
 static void handler (int);
@@ -1080,6 +1080,8 @@ main (int argc, char **argv)
                 export_flag = 1;
              else if (arg[2] == '6' && arg[3] == '4')
                aix64_flag = 1;
+             else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
+               aixrtl_flag = 1;
              break;
 #endif
 
@@ -2823,6 +2825,8 @@ resolve_lib_name (const char *name)
 {
   char *lib_buf;
   int i, j, l = 0;
+  /* Library extensions for AIX dynamic linking.  */
+  const char * const libexts[2] = {"a", "so"};
 
   for (i = 0; libpaths[i]; i++)
     if (libpaths[i]->max_len > l)
@@ -2841,14 +2845,15 @@ resolve_lib_name (const char *name)
          const char *p = "";
          if (list->prefix[strlen(list->prefix)-1] != '/')
            p = "/";
-         for (j = 0; libexts[j]; j++)
+         for (j = 0; j < 2; j++)
            {
              sprintf (lib_buf, "%s%slib%s.%s",
-                      list->prefix, p, name, libexts[j]);
-if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
+                      list->prefix, p, name,
+                      libexts[(j + aixrtl_flag) % 2]);
+             if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
              if (file_exists (lib_buf))
                {
-if (debug) fprintf (stderr, "found: %s\n", lib_buf);
+                 if (debug) fprintf (stderr, "found: %s\n", lib_buf);
                  return (lib_buf);
                }
            }
index e860b4f..0a3f381 100644 (file)
@@ -90,6 +90,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "real.h"
 #include "toplev.h"
 #include "target.h"
+#include "params.h"
 
 #ifndef SHIFT_COUNT_TRUNCATED
 #define SHIFT_COUNT_TRUNCATED 0
@@ -3417,10 +3418,10 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
              /* If this is a register being set, ignore it.  */
              new = XEXP (x, i);
              if (in_dest
-                 && (code == SUBREG || code == STRICT_LOW_PART
-                     || code == ZERO_EXTRACT)
                  && i == 0
-                 && GET_CODE (new) == REG)
+                 && (((code == SUBREG || code == ZERO_EXTRACT)
+                      && GET_CODE (new) == REG)
+                     || code == STRICT_LOW_PART))
                ;
 
              else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
@@ -10688,34 +10689,61 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
          break;
 
        case SUBREG:
-         /* Check for the case where we are comparing A - C1 with C2,
-            both constants are smaller than 1/2 the maximum positive
-            value in MODE, and the comparison is equality or unsigned.
-            In that case, if A is either zero-extended to MODE or has
-            sufficient sign bits so that the high-order bit in MODE
-            is a copy of the sign in the inner mode, we can prove that it is
-            safe to do the operation in the wider mode.  This simplifies
-            many range checks.  */
+         /* Check for the case where we are comparing A - C1 with C2, that is
+
+              (subreg:MODE (plus (A) (-C1))) op (C2)
+
+            with C1 a constant, and try to lift the SUBREG, i.e. to do the
+            comparison in the wider mode.  One of the following two conditions
+            must be true in order for this to be valid:
+
+              1. The mode extension results in the same bit pattern being added
+                 on both sides and the comparison is equality or unsigned.  As
+                 C2 has been truncated to fit in MODE, the pattern can only be
+                 all 0s or all 1s.
+
+              2. The mode extension results in the sign bit being copied on
+                 each side.
+
+            The difficulty here is that we have predicates for A but not for
+            (A - C1) so we need to check that C1 is within proper bounds so
+            as to perturbate A as little as possible.  */
 
          if (mode_width <= HOST_BITS_PER_WIDE_INT
              && subreg_lowpart_p (op0)
+             && GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) > mode_width
              && GET_CODE (SUBREG_REG (op0)) == PLUS
-             && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
-             && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
-             && (-INTVAL (XEXP (SUBREG_REG (op0), 1))
-                 < (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)))
-                       & ~GET_MODE_MASK (mode))
-                 || (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
-                                          GET_MODE (SUBREG_REG (op0)))
-                     > (unsigned int)
-                       (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
-                        - GET_MODE_BITSIZE (mode)))))
-           {
-             op0 = SUBREG_REG (op0);
-             continue;
+             && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT)
+           {
+             enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
+             rtx a = XEXP (SUBREG_REG (op0), 0);
+             HOST_WIDE_INT c1 = -INTVAL (XEXP (SUBREG_REG (op0), 1));
+
+             if ((c1 > 0
+                  && (unsigned HOST_WIDE_INT) c1
+                      < (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)
+                  && (equality_comparison_p || unsigned_comparison_p)
+                  /* (A - C1) zero-extends if it is positive and sign-extends
+                     if it is negative, C2 both zero- and sign-extends.  */
+                  && ((0 == (nonzero_bits (a, inner_mode)
+                             & ~GET_MODE_MASK (mode))
+                       && const_op >= 0)
+                      /* (A - C1) sign-extends if it is positive and 1-extends
+                         if it is negative, C2 both sign- and 1-extends.  */
+                      || (num_sign_bit_copies (a, inner_mode)
+                          > (unsigned int) (GET_MODE_BITSIZE (inner_mode)
+                                            - mode_width)
+                          && const_op < 0)))
+                 || ((unsigned HOST_WIDE_INT) c1
+                      < (unsigned HOST_WIDE_INT) 1 << (mode_width - 2)
+                     /* (A - C1) always sign-extends, like C2.  */
+                     && num_sign_bit_copies (a, inner_mode)
+                        > (unsigned int) (GET_MODE_BITSIZE (inner_mode)
+                                          - mode_width - 1)))
+               {
+                 op0 = SUBREG_REG (op0);
+                 continue;
+               }
            }
 
          /* If the inner mode is narrower and we are extracting the low part,
@@ -11353,6 +11381,47 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
     return gen_binary (reversed_code, mode, op0, op1);
 }
 \f
+/* Utility function for record_value_for_reg.  Count number of
+   rtxs in X.  */
+static int
+count_rtxs (rtx x)
+{
+  enum rtx_code code = GET_CODE (x);
+  const char *fmt;
+  int i, ret = 1;
+
+  if (GET_RTX_CLASS (code) == '2'
+      || GET_RTX_CLASS (code) == 'c')
+    {
+      rtx x0 = XEXP (x, 0);
+      rtx x1 = XEXP (x, 1);
+
+      if (x0 == x1)
+       return 1 + 2 * count_rtxs (x0);
+
+      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+         && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+       return 2 + 2 * count_rtxs (x0)
+              + count_rtxs (x == XEXP (x1, 0)
+                            ? XEXP (x1, 1) : XEXP (x1, 0));
+
+      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+         && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+       return 2 + 2 * count_rtxs (x1)
+              + count_rtxs (x == XEXP (x0, 0)
+                            ? XEXP (x0, 1) : XEXP (x0, 0));
+    }
+
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    if (fmt[i] == 'e')
+      ret += count_rtxs (XEXP (x, i));
+
+  return ret;
+}
+\f
 /* Utility function for following routine.  Called when X is part of a value
    being stored into reg_last_set_value.  Sets reg_last_set_table_tick
    for each register mentioned.  Similar to mention_regs in cse.c  */
@@ -11459,6 +11528,13 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
              && GET_CODE (XEXP (tem, 0)) == CLOBBER
              && GET_CODE (XEXP (tem, 1)) == CLOBBER)
            tem = XEXP (tem, 0);
+         else if (count_occurrences (value, reg, 1) >= 2)
+           {
+             /* If there are two or more occurrences of REG in VALUE,
+                prevent the value from growing too much.  */
+             if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
+               tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
+           }
 
          value = replace_rtx (copy_rtx (value), reg, tem);
        }
index 89c83c4..36c6d42 100644 (file)
@@ -29,6 +29,8 @@ Boston, MA 02111-1307, USA.  */
 FLOAT_MODE (XF, 12, ieee_extended_intel_96_format);
 ADJUST_FLOAT_FORMAT (XF, (TARGET_128BIT_LONG_DOUBLE
                          ? &ieee_extended_intel_128_format
+                         : TARGET_96_ROUND_53_LONG_DOUBLE
+                         ? &ieee_extended_intel_96_round_53_format
                          : &ieee_extended_intel_96_format));
 ADJUST_BYTESIZE  (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 12);
 ADJUST_ALIGNMENT (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 4);
index cc1bb81..ea0e8f6 100644 (file)
@@ -93,6 +93,7 @@ extern int memory_displacement_operand (rtx, enum machine_mode);
 extern int cmpsi_operand (rtx, enum machine_mode);
 extern int long_memory_operand (rtx, enum machine_mode);
 extern int aligned_operand (rtx, enum machine_mode);
+extern int compare_operator (rtx, enum machine_mode);
 extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
 
 extern int ix86_expand_movstr (rtx, rtx, rtx, rtx);
index 50794c3..9504583 100644 (file)
@@ -522,7 +522,14 @@ const int x86_sse_typeless_stores = m_ATHLON_K8;
 const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
 const int x86_use_ffreep = m_ATHLON_K8;
 const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
-const int x86_inter_unit_moves = ~(m_ATHLON_K8);
+
+/* ??? HACK!  The following is a lie.  SSE can hold e.g. SImode, and
+   indeed *must* be able to hold SImode so that SSE2 shifts are able
+   to work right.  But this can result in some mighty surprising 
+   register allocation when building kernels.  Turning this off should
+   make us less likely to all-of-the-sudden select an SSE register.  */
+const int x86_inter_unit_moves = 0;  /* ~(m_ATHLON_K8) */
+
 const int x86_ext_80387_constants = m_K6 | m_ATHLON | m_PENT4 | m_PPRO;
 
 /* In case the average insn count for single function invocation is
@@ -2536,6 +2543,34 @@ function_arg_advance (CUMULATIVE_ARGS *cum,      /* current arg information */
   return;
 }
 
+/* A subroutine of function_arg.  We want to pass a parameter whose nominal
+   type is MODE in REGNO.  We try to minimize ABI variation, so MODE may not
+   actually be valid for REGNO with the current ISA.  In this case, ALT_MODE
+   is used instead.  It must be the same size as MODE, and must be known to
+   be valid for REGNO.  Finally, ORIG_MODE is the original mode of the 
+   parameter, as seen by the type system.  This may be different from MODE
+   when we're mucking with things minimizing ABI variations.
+
+   Returns a REG or a PARALLEL as appropriate.  */
+
+static rtx
+gen_reg_or_parallel (enum machine_mode mode, enum machine_mode alt_mode,
+                    enum machine_mode orig_mode, unsigned int regno)
+{
+  rtx tmp;
+
+  if (HARD_REGNO_MODE_OK (regno, mode))
+    tmp = gen_rtx_REG (mode, regno);
+  else
+    {
+      tmp = gen_rtx_REG (alt_mode, regno);
+      tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
+      tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
+    }
+
+  return tmp;
+}
+
 /* Define where to put the arguments to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
@@ -2550,12 +2585,11 @@ function_arg_advance (CUMULATIVE_ARGS *cum,     /* current arg information */
     (otherwise it is an extra parameter matching an ellipsis).  */
 
 rtx
-function_arg (CUMULATIVE_ARGS *cum,    /* current arg information */
-             enum machine_mode mode,   /* current arg mode */
-             tree type,        /* type of the argument or 0 if lib support */
-             int named)        /* != 0 for normal args, == 0 for ...  args */
+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
+             tree type, int named)
 {
-  rtx ret   = NULL_RTX;
+  enum machine_mode mode = orig_mode;
+  rtx ret = NULL_RTX;
   int bytes =
     (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
   int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
@@ -2628,7 +2662,8 @@ function_arg (CUMULATIVE_ARGS *cum,       /* current arg information */
                         "changes the ABI");
              }
            if (cum->sse_nregs)
-             ret = gen_rtx_REG (mode, cum->sse_regno + FIRST_SSE_REG);
+             ret = gen_reg_or_parallel (mode, TImode, orig_mode,
+                                        cum->sse_regno + FIRST_SSE_REG);
          }
        break;
       case V8QImode:
@@ -2644,7 +2679,8 @@ function_arg (CUMULATIVE_ARGS *cum,       /* current arg information */
                         "changes the ABI");
              }
            if (cum->mmx_nregs)
-             ret = gen_rtx_REG (mode, cum->mmx_regno + FIRST_MMX_REG);
+             ret = gen_reg_or_parallel (mode, DImode, orig_mode,
+                                        cum->mmx_regno + FIRST_MMX_REG);
          }
        break;
       }
@@ -4319,6 +4355,12 @@ aligned_operand (rtx op, enum machine_mode mode)
   /* Didn't find one -- this must be an aligned address.  */
   return 1;
 }
+
+int
+compare_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return GET_CODE (op) == COMPARE;
+}
 \f
 /* Initialize the table of extra 80387 mathematical constants.  */
 
@@ -10604,10 +10646,11 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
          else if (GET_CODE (operand) == CONST_DOUBLE)
            {
              REAL_VALUE_TYPE r;
-             long l[3];
+             long l[4];
 
              REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
              real_to_target (l, &r, mode);
+
              /* Do not use shift by 32 to avoid warning on 32bit systems.  */
              if (HOST_BITS_PER_WIDE_INT >= 64)
                parts[0]
@@ -10617,6 +10660,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
                       DImode);
              else
                parts[0] = immed_double_const (l[0], l[1], DImode);
+
              if (upper_mode == SImode)
                parts[1] = gen_int_mode (l[2], SImode);
              else if (HOST_BITS_PER_WIDE_INT >= 64)
@@ -14891,10 +14935,29 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
   if (FP_REGNO_P (regno))
     return VALID_FP_MODE_P (mode);
   if (SSE_REGNO_P (regno))
-    return (TARGET_SSE ? VALID_SSE_REG_MODE (mode) : 0);
+    {
+      /* HACK!  We didn't change all of the constraints for SSE1 for the
+        scalar modes on the branch.  Fortunately, they're not required
+        for ABI compatibility.  */
+      if (!TARGET_SSE2 && !VECTOR_MODE_P (mode))
+       return VALID_SSE_REG_MODE (mode);
+
+      /* We implement the move patterns for all vector modes into and
+         out of SSE registers, even when no operation instructions
+         are available.  */
+      return (VALID_SSE_REG_MODE (mode)
+             || VALID_SSE2_REG_MODE (mode)
+             || VALID_MMX_REG_MODE (mode)
+             || VALID_MMX_REG_MODE_3DNOW (mode));
+    }
   if (MMX_REGNO_P (regno))
-    return (TARGET_MMX
-           ? VALID_MMX_REG_MODE (mode) || VALID_MMX_REG_MODE_3DNOW (mode) : 0);
+    {
+      /* We implement the move patterns for 3DNOW modes even in MMX mode,
+         so if the register is available at all, then we can move data of
+         the given mode into or out of it.  */
+      return (VALID_MMX_REG_MODE (mode)
+             || VALID_MMX_REG_MODE_3DNOW (mode));
+    }
   /* We handle both integer and floats in the general purpose registers.
      In future we should be able to handle vector modes as well.  */
   if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
@@ -15230,7 +15293,9 @@ ix86_rtx_costs (rtx x, int code, int outer_code, int *total)
       return false;
 
     case FLOAT_EXTEND:
-      if (!TARGET_SSE_MATH || !VALID_SSE_REG_MODE (mode))
+      if (!TARGET_SSE_MATH
+         || mode == XFmode
+         || (mode == DFmode && !TARGET_SSE2))
        *total = 0;
       return false;
 
index f5be340..8a912d5 100644 (file)
@@ -447,6 +447,10 @@ extern int x86_prefetch_sse;
    redefines this to 1.  */
 #define TARGET_MACHO 0
 
+/* Subtargets may reset this to 1 in order to enable 96-bit long double
+   with the rounding mode forced to 53 bits.  */
+#define TARGET_96_ROUND_53_LONG_DOUBLE 0
+
 /* This macro is similar to `TARGET_SWITCHES' but defines names of
    command options that have values.  Its definition is an
    initializer with a subgrouping for each command option.
@@ -1059,14 +1063,11 @@ do {                                                                    \
 
 #define VALID_SSE2_REG_MODE(MODE) \
     ((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode    \
-     || (MODE) == V2DImode)
+     || (MODE) == V2DImode || (MODE) == DFmode)
 
 #define VALID_SSE_REG_MODE(MODE)                                       \
     ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode      \
-     || (MODE) == SFmode || (MODE) == TFmode                           \
-     /* Always accept SSE2 modes so that xmmintrin.h compiles.  */     \
-     || VALID_SSE2_REG_MODE (MODE)                                     \
-     || (TARGET_SSE2 && ((MODE) == DFmode || VALID_MMX_REG_MODE (MODE))))
+     || (MODE) == SFmode || (MODE) == TFmode)
 
 #define VALID_MMX_REG_MODE_3DNOW(MODE) \
     ((MODE) == V2SFmode || (MODE) == SFmode)
@@ -2990,7 +2991,8 @@ do {                                              \
   {"zero_extended_scalar_load_operand", {MEM}},                                \
   {"vector_move_operand", {CONST_VECTOR, SUBREG, REG, MEM}},           \
   {"no_seg_address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
-                             LABEL_REF, SUBREG, REG, MEM, PLUS, MULT}},
+                             LABEL_REF, SUBREG, REG, MEM, PLUS, MULT}}, \
+  {"compare_operator", {COMPARE}},
 
 /* A list of predicates that do special things with modes, and so
    should not elicit warnings for VOIDmode match_operand.  */
index 86ea88c..93d9dcd 100644 (file)
   ""
   "xchg{l}\t%1, %0"
   [(set_attr "type" "imov")
+   (set_attr "mode" "SI")
    (set_attr "pent_pair" "np")
    (set_attr "athlon_decode" "vector")
-   (set_attr "mode" "SI")
-   (set_attr "modrm" "0")
    (set_attr "ppro_uops" "few")])
 
 (define_expand "movhi"
        (match_operand:HI 1 "register_operand" "+r"))
    (set (match_dup 1)
        (match_dup 0))]
-  "TARGET_PARTIAL_REG_STALL"
-  "xchg{w}\t%1, %0"
+  "!TARGET_PARTIAL_REG_STALL || optimize_size"
+  "xchg{l}\t%k1, %k0"
   [(set_attr "type" "imov")
+   (set_attr "mode" "SI")
    (set_attr "pent_pair" "np")
-   (set_attr "mode" "HI")
-   (set_attr "modrm" "0")
+   (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
 
 (define_insn "*swaphi_2"
        (match_operand:HI 1 "register_operand" "+r"))
    (set (match_dup 1)
        (match_dup 0))]
-  "TARGET_PARTIAL_REG_STALL"
-  "xchg{l}\t%k1, %k0"
+  "TARGET_PARTIAL_REG_STALL"
+  "xchg{w}\t%1, %0"
   [(set_attr "type" "imov")
+   (set_attr "mode" "HI")
    (set_attr "pent_pair" "np")
-   (set_attr "mode" "SI")
-   (set_attr "modrm" "0")
+   (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
 
 (define_expand "movstricthi"
   DONE;
 })
 
-(define_insn "*swapqi"
+(define_insn "*swapqi_1"
   [(set (match_operand:QI 0 "register_operand" "+r")
        (match_operand:QI 1 "register_operand" "+r"))
    (set (match_dup 1)
        (match_dup 0))]
-  ""
-  "xchg{b}\t%1, %0"
+  "!TARGET_PARTIAL_REG_STALL || optimize_size"
+  "xchg{l}\t%k1, %k0"
   [(set_attr "type" "imov")
+   (set_attr "mode" "SI")
    (set_attr "pent_pair" "np")
+   (set_attr "athlon_decode" "vector")
+   (set_attr "ppro_uops" "few")])
+
+(define_insn "*swapqi_2"
+  [(set (match_operand:QI 0 "register_operand" "+q")
+       (match_operand:QI 1 "register_operand" "+q"))
+   (set (match_dup 1)
+       (match_dup 0))]
+  "TARGET_PARTIAL_REG_STALL"
+  "xchg{b}\t%1, %0"
+  [(set_attr "type" "imov")
    (set_attr "mode" "QI")
-   (set_attr "modrm" "0")
+   (set_attr "pent_pair" "np")
+   (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
 
 (define_expand "movstrictqi"
   "TARGET_64BIT"
   "xchg{q}\t%1, %0"
   [(set_attr "type" "imov")
+   (set_attr "mode" "DI")
    (set_attr "pent_pair" "np")
    (set_attr "athlon_decode" "vector")
-   (set_attr "mode" "DI")
-   (set_attr "modrm" "0")
    (set_attr "ppro_uops" "few")])
 
-  
 (define_expand "movsf"
   [(set (match_operand:SF 0 "nonimmediate_operand" "")
        (match_operand:SF 1 "general_operand" ""))]
      (if_then_else (match_operand:QI 1 "incdec_operand" "")
        (const_string "incdec")
        (const_string "alu1")))
+   (set (attr "memory")
+     (if_then_else (match_operand 1 "memory_operand" "")
+        (const_string "load")
+        (const_string "none")))
    (set_attr "mode" "QI")])
 
 (define_insn "*addqi_2"
   ""
   "")
 
-(define_insn "*testqi_1"
+(define_insn "*testqi_1_maybe_si"
   [(set (reg 17)
-        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
-                        (match_operand:QI 1 "general_operand" "n,n,qn,n"))
-                (const_int 0)))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+        (compare
+         (and:QI
+           (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
+           (match_operand:QI 1 "general_operand" "n,n,qn,n"))
+         (const_int 0)))]
+  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+   && ix86_match_ccmode (insn,
+                        GET_CODE (operands[1]) == CONST_INT
+                        && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
 {
   if (which_alternative == 3)
     {
-      if (GET_CODE (operands[1]) == CONST_INT
-         && (INTVAL (operands[1]) & 0xffffff00))
+      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
        operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
       return "test{l}\t{%1, %k0|%k0, %1}";
     }
    (set_attr "mode" "QI,QI,QI,SI")
    (set_attr "pent_pair" "uv,np,uv,np")])
 
+(define_insn "*testqi_1"
+  [(set (reg 17)
+        (compare
+         (and:QI
+           (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
+           (match_operand:QI 1 "general_operand" "n,n,qn"))
+         (const_int 0)))]
+  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+   && ix86_match_ccmode (insn, CCNOmode)"
+  "test{b}\t{%1, %0|%0, %1}"
+  [(set_attr "type" "test")
+   (set_attr "modrm" "0,1,1")
+   (set_attr "mode" "QI")
+   (set_attr "pent_pair" "uv,np,uv")])
+
 (define_expand "testqi_ext_ccno_0"
   [(set (reg:CCNO 17)
        (compare:CCNO
   "#")
 
 (define_split
-  [(set (reg 17)
-        (compare (zero_extract
-                  (match_operand 0 "nonimmediate_operand" "")
-                  (match_operand 1 "const_int_operand" "")
-                  (match_operand 2 "const_int_operand" ""))
-                (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+        (match_operator 1 "compare_operator"
+         [(zero_extract
+            (match_operand 2 "nonimmediate_operand" "")
+            (match_operand 3 "const_int_operand" "")
+            (match_operand 4 "const_int_operand" ""))
+          (const_int 0)]))]
   "ix86_match_ccmode (insn, CCNOmode)"
-  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
+  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
 {
-  HOST_WIDE_INT len = INTVAL (operands[1]);
-  HOST_WIDE_INT pos = INTVAL (operands[2]);
+  rtx val = operands[2];
+  HOST_WIDE_INT len = INTVAL (operands[3]);
+  HOST_WIDE_INT pos = INTVAL (operands[4]);
   HOST_WIDE_INT mask;
   enum machine_mode mode, submode;
 
-  mode = GET_MODE (operands[0]);
-  if (GET_CODE (operands[0]) == MEM)
+  mode = GET_MODE (val);
+  if (GET_CODE (val) == MEM)
     {
       /* ??? Combine likes to put non-volatile mem extractions in QImode
         no matter the size of the test.  So find a mode that works.  */
-      if (! MEM_VOLATILE_P (operands[0]))
+      if (! MEM_VOLATILE_P (val))
        {
          mode = smallest_mode_for_size (pos + len, MODE_INT);
-         operands[0] = adjust_address (operands[0], mode, 0);
+         val = adjust_address (val, mode, 0);
        }
     }
-  else if (GET_CODE (operands[0]) == SUBREG
-          && (submode = GET_MODE (SUBREG_REG (operands[0])),
+  else if (GET_CODE (val) == SUBREG
+          && (submode = GET_MODE (SUBREG_REG (val)),
               GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
           && pos + len <= GET_MODE_BITSIZE (submode))
     {
       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
       mode = submode;
-      operands[0] = SUBREG_REG (operands[0]);
+      val = SUBREG_REG (val);
     }
   else if (mode == HImode && pos + len <= 8)
     {
       /* Small HImode tests can be converted to QImode.  */
       mode = QImode;
-      operands[0] = gen_lowpart (QImode, operands[0]);
+      val = gen_lowpart (QImode, val);
     }
 
   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
 
-  operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
+  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
 })
 
 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
 ;; Do the conversion only post-reload to avoid limiting of the register class
 ;; to QI regs.
 (define_split
-  [(set (reg 17)
-       (compare
-         (and (match_operand 0 "register_operand" "")
-              (match_operand 1 "const_int_operand" ""))
-         (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and (match_operand 2 "register_operand" "")
+               (match_operand 3 "const_int_operand" ""))
+          (const_int 0)]))]
    "reload_completed
-    && QI_REG_P (operands[0])
+    && QI_REG_P (operands[2])
+    && GET_MODE (operands[2]) != QImode
     && ((ix86_match_ccmode (insn, CCZmode)
-        && !(INTVAL (operands[1]) & ~(255 << 8)))
+        && !(INTVAL (operands[3]) & ~(255 << 8)))
        || (ix86_match_ccmode (insn, CCNOmode)
-           && !(INTVAL (operands[1]) & ~(127 << 8))))
-    && GET_MODE (operands[0]) != QImode"
-  [(set (reg:CCNO 17)
-       (compare:CCNO
-         (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
-                 (match_dup 1))
-         (const_int 0)))]
-  "operands[0] = gen_lowpart (SImode, operands[0]);
-   operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
+           && !(INTVAL (operands[3]) & ~(127 << 8))))"
+  [(set (match_dup 0)
+       (match_op_dup 1
+         [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
+                  (match_dup 3))
+          (const_int 0)]))]
+  "operands[2] = gen_lowpart (SImode, operands[2]);
+   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
 
 (define_split
-  [(set (reg 17)
-       (compare
-         (and (match_operand 0 "nonimmediate_operand" "")
-              (match_operand 1 "const_int_operand" ""))
-         (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and (match_operand 2 "nonimmediate_operand" "")
+               (match_operand 3 "const_int_operand" ""))
+          (const_int 0)]))]
    "reload_completed
-    && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
+    && GET_MODE (operands[2]) != QImode
+    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
     && ((ix86_match_ccmode (insn, CCZmode)
-        && !(INTVAL (operands[1]) & ~255))
+        && !(INTVAL (operands[3]) & ~255))
        || (ix86_match_ccmode (insn, CCNOmode)
-           && !(INTVAL (operands[1]) & ~127)))
-    && GET_MODE (operands[0]) != QImode"
-  [(set (reg:CCNO 17)
-       (compare:CCNO
-         (and:QI (match_dup 0)
-                 (match_dup 1))
-         (const_int 0)))]
-  "operands[0] = gen_lowpart (QImode, operands[0]);
-   operands[1] = gen_lowpart (QImode, operands[1]);")
+           && !(INTVAL (operands[3]) & ~127)))"
+  [(set (match_dup 0)
+       (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
+                        (const_int 0)]))]
+  "operands[2] = gen_lowpart (QImode, operands[2]);
+   operands[3] = gen_lowpart (QImode, operands[3]);")
 
 
 ;; %%% This used to optimize known byte-wide and operations to memory,
   [(set_attr "type" "alu1")
    (set_attr "mode" "QI")])
 
-(define_insn "*andqi_2"
+(define_insn "*andqi_2_maybe_si"
   [(set (reg 17)
        (compare (and:QI
-                  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
-                  (match_operand:QI 2 "general_operand" "qim,qi,i"))
+                     (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
+                     (match_operand:QI 2 "general_operand" "qim,qi,i"))
                 (const_int 0)))
    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
        (and:QI (match_dup 1) (match_dup 2)))]
-  "ix86_match_ccmode (insn, CCNOmode)
-   && ix86_binary_operator_ok (AND, QImode, operands)"
+  "ix86_binary_operator_ok (AND, QImode, operands)
+   && ix86_match_ccmode (insn,
+                        GET_CODE (operands[2]) == CONST_INT
+                        && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
 {
   if (which_alternative == 2)
     {
-      if (GET_CODE (operands[2]) == CONST_INT
-          && (INTVAL (operands[2]) & 0xffffff00))
+      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
       return "and{l}\t{%2, %k0|%k0, %2}";
     }
   [(set_attr "type" "alu")
    (set_attr "mode" "QI,QI,SI")])
 
+(define_insn "*andqi_2"
+  [(set (reg 17)
+       (compare (and:QI
+                  (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+                  (match_operand:QI 2 "general_operand" "qim,qi"))
+                (const_int 0)))
+   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
+       (and:QI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && ix86_binary_operator_ok (AND, QImode, operands)"
+  "and{b}\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_insn "*andqi_2_slp"
   [(set (reg 17)
        (compare (and:QI
   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
                   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
-  "TARGET_80387"
-  "if (TARGET_SSE)
+  "TARGET_80387 || TARGET_SSE_MATH"
+  "if (TARGET_SSE_MATH)
      {
        /* In case operand is in memory,  we will not use SSE.  */
        if (memory_operand (operands[0], VOIDmode)
    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (xor:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (xor:V4SF (match_dup 1)
+                 (match_dup 2)))]
 {
-  operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
   if (operands_match_p (operands[0], operands[2]))
     {
       rtx tmp;
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
        (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && !TARGET_SSE
+  "TARGET_80387
    && ix86_unary_operator_ok (NEG, SFmode, operands)"
   "#")
 
   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
                   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
-  "TARGET_80387"
-  "if (TARGET_SSE2)
+  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
+  "if (TARGET_SSE2 && TARGET_SSE_MATH)
      {
        /* In case operand is in memory,  we will not use SSE.  */
        if (memory_operand (operands[0], VOIDmode)
    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (xor:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (xor:V2DF (match_dup 1)
+                 (match_dup 2)))]
 {
   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
-  operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
   /* Avoid possible reformatting on the operands.  */
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
                   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
-  "TARGET_80387"
-  "if (TARGET_SSE)
+  "TARGET_80387 || TARGET_SSE_MATH"
+  "if (TARGET_SSE_MATH)
      {
        /* In case operand is in memory,  we will not use SSE.  */
        if (memory_operand (operands[0], VOIDmode)
    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (and:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (and:V4SF (match_dup 1)
+                 (match_dup 2)))]
 {
-  operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
   if (operands_match_p (operands[0], operands[2]))
     {
       rtx tmp;
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
+  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
   "#")
 
 (define_split
   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
                   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
-  "TARGET_80387"
-  "if (TARGET_SSE2)
+  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
+  "if (TARGET_SSE2 && TARGET_SSE_MATH)
      {
        /* In case operand is in memory,  we will not use SSE.  */
        if (memory_operand (operands[0], VOIDmode)
    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (and:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (and:V2DF (match_dup 1)
+                 (match_dup 2)))]
 {
   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
-  operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
   /* Avoid possible reformatting on the operands.  */
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
    (set_attr "mode" "DI")])
 
 (define_split
-  [(set (reg 17)
-       (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
-                (const_int 0)))
-   (set (match_operand:DI 0 "nonimmediate_operand" "")
-       (not:DI (match_dup 1)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
+          (const_int 0)]))
+   (set (match_operand:DI 1 "nonimmediate_operand" "")
+       (not:DI (match_dup 3)))]
   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (xor:DI (match_dup 1) (const_int -1)))])]
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2
+                    [(xor:DI (match_dup 3) (const_int -1))
+                     (const_int 0)]))
+             (set (match_dup 1)
+                  (xor:DI (match_dup 3) (const_int -1)))])]
   "")
 
 (define_expand "one_cmplsi2"
    (set_attr "mode" "SI")])
 
 (define_split
-  [(set (reg 17)
-       (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
-                (const_int 0)))
-   (set (match_operand:SI 0 "nonimmediate_operand" "")
-       (not:SI (match_dup 1)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
+          (const_int 0)]))
+   (set (match_operand:SI 1 "nonimmediate_operand" "")
+       (not:SI (match_dup 3)))]
   "ix86_match_ccmode (insn, CCNOmode)"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (xor:SI (match_dup 1) (const_int -1)))])]
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
+                                   (const_int 0)]))
+             (set (match_dup 1)
+                  (xor:SI (match_dup 3) (const_int -1)))])]
   "")
 
 ;; ??? Currently never generated - xor is used instead.
    (set_attr "mode" "SI")])
 
 (define_split
-  [(set (reg 17)
-       (compare (not:SI (match_operand:SI 1 "register_operand" ""))
-                (const_int 0)))
-   (set (match_operand:DI 0 "register_operand" "")
-       (zero_extend:DI (not:SI (match_dup 1))))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(not:SI (match_operand:SI 3 "register_operand" ""))
+          (const_int 0)]))
+   (set (match_operand:DI 1 "register_operand" "")
+       (zero_extend:DI (not:SI (match_dup 3))))]
   "ix86_match_ccmode (insn, CCNOmode)"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
+                                   (const_int 0)]))
+             (set (match_dup 1)
+                  (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
   "")
 
 (define_expand "one_cmplhi2"
    (set_attr "mode" "HI")])
 
 (define_split
-  [(set (reg 17)
-       (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
-                (const_int 0)))
-   (set (match_operand:HI 0 "nonimmediate_operand" "")
-       (not:HI (match_dup 1)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
+          (const_int 0)]))
+   (set (match_operand:HI 1 "nonimmediate_operand" "")
+       (not:HI (match_dup 3)))]
   "ix86_match_ccmode (insn, CCNOmode)"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (xor:HI (match_dup 1) (const_int -1)))])]
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
+                                   (const_int 0)]))
+             (set (match_dup 1)
+                  (xor:HI (match_dup 3) (const_int -1)))])]
   "")
 
 ;; %%% Potential partial reg stall on alternative 1.  What to do?
    (set_attr "mode" "QI")])
 
 (define_split
-  [(set (reg 17)
-       (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
-                (const_int 0)))
-   (set (match_operand:QI 0 "nonimmediate_operand" "")
-       (not:QI (match_dup 1)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
+          (const_int 0)]))
+   (set (match_operand:QI 1 "nonimmediate_operand" "")
+       (not:QI (match_dup 3)))]
   "ix86_match_ccmode (insn, CCNOmode)"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (xor:QI (match_dup 1) (const_int -1)))])]
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
+                                   (const_int 0)]))
+             (set (match_dup 1)
+                  (xor:QI (match_dup 3) (const_int -1)))])]
   "")
 \f
 ;; Arithmetic shift instructions
    (clobber (match_operand 6 "" ""))
    (clobber (reg:CC 17))]
   "!SSE_REG_P (operands[0]) && reload_completed
-   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
+   && (GET_MODE (operands[0]) == SFmode
+       || (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))"
   [(const_int 0)]
 {
    ix86_compare_op0 = operands[5];
 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
 ;; or   op2, op0   -  get the nonzero one into the result.
 (define_split
-  [(set (match_operand 0 "register_operand" "")
-       (if_then_else (match_operator 1 "sse_comparison_operator"
-                       [(match_operand 4 "register_operand" "")
-                        (match_operand 5 "nonimmediate_operand" "")])
-                     (match_operand 2 "register_operand" "")
-                     (match_operand 3 "register_operand" "")))
+  [(set (match_operand:SF 0 "register_operand" "")
+       (if_then_else:SF (match_operator 1 "sse_comparison_operator"
+                          [(match_operand:SF 4 "register_operand" "")
+                           (match_operand:SF 5 "nonimmediate_operand" "")])
+                        (match_operand:SF 2 "register_operand" "")
+                        (match_operand:SF 3 "register_operand" "")))
+   (clobber (match_operand 6 "" ""))
+   (clobber (reg:CC 17))]
+  "SSE_REG_P (operands[0]) && reload_completed"
+  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
+   (set (match_dup 2) (and:V4SF (match_dup 2)
+                               (match_dup 8)))
+   (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
+                                         (match_dup 3)))
+   (set (match_dup 0) (ior:V4SF (match_dup 6)
+                               (match_dup 7)))]
+{
+  /* If op2 == op3, op3 would be clobbered before it is used.  */
+  if (operands_match_p (operands[2], operands[3]))
+    {
+      emit_move_insn (operands[0], operands[2]);
+      DONE;
+    }
+
+  PUT_MODE (operands[1], GET_MODE (operands[0]));
+  if (operands_match_p (operands[0], operands[4]))
+    operands[6] = operands[4], operands[7] = operands[2];
+  else
+    operands[6] = operands[2], operands[7] = operands[4];
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
+  operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
+  operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
+  operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
+  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
+})
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (if_then_else:DF (match_operator 1 "sse_comparison_operator"
+                          [(match_operand:DF 4 "register_operand" "")
+                           (match_operand:DF 5 "nonimmediate_operand" "")])
+                        (match_operand:DF 2 "register_operand" "")
+                        (match_operand:DF 3 "register_operand" "")))
    (clobber (match_operand 6 "" ""))
    (clobber (reg:CC 17))]
   "SSE_REG_P (operands[0]) && reload_completed"
   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
-   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
-                                           (subreg:TI (match_dup 4) 0)))
-   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
-                                           (subreg:TI (match_dup 3) 0)))
-   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
-                                           (subreg:TI (match_dup 7) 0)))]
+   (set (match_dup 2) (and:V2DF (match_dup 2)
+                               (match_dup 8)))
+   (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
+                                         (match_dup 3)))
+   (set (match_dup 0) (ior:V2DF (match_dup 6)
+                               (match_dup 7)))]
 {
   if (GET_MODE (operands[2]) == DFmode
       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
     operands[6] = operands[4], operands[7] = operands[2];
   else
     operands[6] = operands[2], operands[7] = operands[4];
+  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+  operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
+  operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
+  operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
+  operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
+  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
 })
 
 ;; Special case of conditional move we can handle effectively.
   "#")
 
 (define_split
-  [(set (match_operand 0 "register_operand" "")
-       (if_then_else (match_operator 1 "comparison_operator"
-                       [(match_operand 4 "nonimmediate_operand" "")
-                        (match_operand 5 "nonimmediate_operand" "")])
-                     (match_operand 2 "nonmemory_operand" "")
-                     (match_operand 3 "nonmemory_operand" "")))]
+  [(set (match_operand:SF 0 "register_operand" "")
+       (if_then_else:SF (match_operator 1 "comparison_operator"
+                          [(match_operand:SF 4 "nonimmediate_operand" "")
+                           (match_operand:SF 5 "nonimmediate_operand" "")])
+                        (match_operand:SF 2 "nonmemory_operand" "")
+                        (match_operand:SF 3 "nonmemory_operand" "")))]
   "SSE_REG_P (operands[0]) && reload_completed
    && (const0_operand (operands[2], GET_MODE (operands[0]))
        || const0_operand (operands[3], GET_MODE (operands[0])))"
   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
-   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
-                                           (match_dup 7)))]
+   (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
+{
+  PUT_MODE (operands[1], GET_MODE (operands[0]));
+  if (!sse_comparison_operator (operands[1], VOIDmode)
+      || !rtx_equal_p (operands[0], operands[4]))
+    {
+      rtx tmp = operands[5];
+      operands[5] = operands[4];
+      operands[4] = tmp;
+      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
+    }
+  if (!rtx_equal_p (operands[0], operands[4]))
+    abort ();
+  operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  if (const0_operand (operands[2], GET_MODE (operands[2])))
+    {
+      operands[7] = operands[3];
+      operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
+    }
+  else
+    {
+      operands[7] = operands[2];
+      operands[6] = operands[8];
+    }
+  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
+})
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (if_then_else:DF (match_operator 1 "comparison_operator"
+                          [(match_operand:DF 4 "nonimmediate_operand" "")
+                           (match_operand:DF 5 "nonimmediate_operand" "")])
+                        (match_operand:DF 2 "nonmemory_operand" "")
+                        (match_operand:DF 3 "nonmemory_operand" "")))]
+  "SSE_REG_P (operands[0]) && reload_completed
+   && (const0_operand (operands[2], GET_MODE (operands[0]))
+       || const0_operand (operands[3], GET_MODE (operands[0])))"
+  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
+   (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
 {
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
       && GET_MODE (operands[2]) == DFmode)
     }
   if (!rtx_equal_p (operands[0], operands[4]))
     abort ();
-  if (const0_operand (operands[2], GET_MODE (operands[0])))
+  operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+  if (const0_operand (operands[2], GET_MODE (operands[2])))
     {
       operands[7] = operands[3];
-      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
-                                                        0));
+      operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
     }
   else
     {
       operands[7] = operands[2];
-      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
+      operands[6] = operands[8];
     }
-  operands[7] = simplify_gen_subreg (TImode, operands[7],
-                                    GET_MODE (operands[7]), 0);
+  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
 })
 
 (define_expand "allocate_stack_worker"
 ; instruction size is unchanged, except in the %eax case for
 ; which it is increased by one byte, hence the ! optimize_size.
 (define_split
-  [(set (reg 17)
-       (compare (and (match_operand 1 "aligned_operand" "")
-                     (match_operand 2 "const_int_operand" ""))
-                (const_int 0)))
-   (set (match_operand 0 "register_operand" "")
-       (and (match_dup 1) (match_dup 2)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 2 "compare_operator"
+         [(and (match_operand 3 "aligned_operand" "")
+               (match_operand 4 "const_int_operand" ""))
+          (const_int 0)]))
+   (set (match_operand 1 "register_operand" "")
+       (and (match_dup 3) (match_dup 4)))]
   "! TARGET_PARTIAL_REG_STALL && reload_completed
    /* Ensure that the operand will remain sign-extended immediate.  */
-   && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
+   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
    && ! optimize_size
-   && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
-       || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
-                                (const_int 0)))
-             (set (match_dup 0)
-                  (and:SI (match_dup 1) (match_dup 2)))])]
-  "operands[2]
-     = gen_int_mode (INTVAL (operands[2])
-                    & GET_MODE_MASK (GET_MODE (operands[0])),
-                    SImode);
-   operands[0] = gen_lowpart (SImode, operands[0]);
-   operands[1] = gen_lowpart (SImode, operands[1]);")
+   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
+       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
+                                   (const_int 0)]))
+             (set (match_dup 1)
+                  (and:SI (match_dup 3) (match_dup 4)))])]
+{
+  operands[4]
+    = gen_int_mode (INTVAL (operands[4])
+                   & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
+  operands[1] = gen_lowpart (SImode, operands[1]);
+  operands[3] = gen_lowpart (SImode, operands[3]);
+})
 
 ; Don't promote the QImode tests, as i386 doesn't have encoding of
 ; the TEST instruction with 32-bit sign-extended immediate and thus
 ; the instruction size would at least double, which is not what we
 ; want even with ! optimize_size.
 (define_split
-  [(set (reg 17)
-       (compare (and (match_operand:HI 0 "aligned_operand" "")
-                     (match_operand:HI 1 "const_int_operand" ""))
-                (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and (match_operand:HI 2 "aligned_operand" "")
+               (match_operand:HI 3 "const_int_operand" ""))
+          (const_int 0)]))]
   "! TARGET_PARTIAL_REG_STALL && reload_completed
    /* Ensure that the operand will remain sign-extended immediate.  */
-   && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
+   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
    && ! TARGET_FAST_PREFIX
    && ! optimize_size"
-  [(set (reg:CCNO 17)
-       (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
-                     (const_int 0)))]
-  "operands[1]
-     = gen_int_mode (INTVAL (operands[1])
-                    & GET_MODE_MASK (GET_MODE (operands[0])),
-                    SImode);
-   operands[0] = gen_lowpart (SImode, operands[0]);")
+  [(set (match_dup 0)
+       (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
+                        (const_int 0)]))]
+{
+  operands[3]
+    = gen_int_mode (INTVAL (operands[3])
+                   & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
+  operands[2] = gen_lowpart (SImode, operands[2]);
+})
 
 (define_split
   [(set (match_operand 0 "register_operand" "")
 
 ;; Don't compare memory with zero, load and use a test instead.
 (define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:SI 0 "memory_operand" "")
-                (const_int 0)))
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(match_operand:SI 2 "memory_operand" "")
+          (const_int 0)]))
    (match_scratch:SI 3 "r")]
   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
-  [(set (match_dup 3) (match_dup 0))
-   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
+  [(set (match_dup 3) (match_dup 2))
+   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
   "")
 
 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
 ;; versions if we're concerned about partial register stalls.
 
 (define_peephole2
-  [(set (reg 17)
-       (compare (and:SI (match_operand:SI 0 "register_operand" "")
-                        (match_operand:SI 1 "immediate_operand" ""))
-                (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and:SI (match_operand:SI 2 "register_operand" "")
+                  (match_operand:SI 3 "immediate_operand" ""))
+          (const_int 0)]))]
   "ix86_match_ccmode (insn, CCNOmode)
-   && (true_regnum (operands[0]) != 0
-       || (GET_CODE (operands[1]) == CONST_INT
-          && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+   && (true_regnum (operands[2]) != 0
+       || (GET_CODE (operands[3]) == CONST_INT
+          && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
+   && peep2_reg_dead_p (1, operands[2])"
   [(parallel
-     [(set (reg:CCNO 17)
-          (compare:CCNO (and:SI (match_dup 0)
-                                (match_dup 1))
-                        (const_int 0)))
-      (set (match_dup 0)
-          (and:SI (match_dup 0) (match_dup 1)))])]
+     [(set (match_dup 0)
+          (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
+                           (const_int 0)]))
+      (set (match_dup 2)
+          (and:SI (match_dup 2) (match_dup 3)))])]
   "")
 
 ;; We don't need to handle HImode case, because it will be promoted to SImode
 ;; on ! TARGET_PARTIAL_REG_STALL
 
 (define_peephole2
-  [(set (reg 17)
-       (compare (and:QI (match_operand:QI 0 "register_operand" "")
-                        (match_operand:QI 1 "immediate_operand" ""))
-                (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and:QI (match_operand:QI 2 "register_operand" "")
+                  (match_operand:QI 3 "immediate_operand" ""))
+          (const_int 0)]))]
   "! TARGET_PARTIAL_REG_STALL
    && ix86_match_ccmode (insn, CCNOmode)
-   && true_regnum (operands[0]) != 0
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+   && true_regnum (operands[2]) != 0
+   && peep2_reg_dead_p (1, operands[2])"
   [(parallel
-     [(set (reg:CCNO 17)
-          (compare:CCNO (and:QI (match_dup 0)
-                                (match_dup 1))
-                        (const_int 0)))
-      (set (match_dup 0)
-          (and:QI (match_dup 0) (match_dup 1)))])]
+     [(set (match_dup 0)
+          (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
+                           (const_int 0)]))
+      (set (match_dup 2)
+          (and:QI (match_dup 2) (match_dup 3)))])]
   "")
 
 (define_peephole2
-  [(set (reg 17)
-       (compare
-         (and:SI
-           (zero_extract:SI
-             (match_operand 0 "ext_register_operand" "")
-             (const_int 8)
-             (const_int 8))
-           (match_operand 1 "const_int_operand" ""))
-         (const_int 0)))]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(and:SI
+            (zero_extract:SI
+              (match_operand 2 "ext_register_operand" "")
+              (const_int 8)
+              (const_int 8))
+            (match_operand 3 "const_int_operand" ""))
+          (const_int 0)]))]
   "! TARGET_PARTIAL_REG_STALL
    && ix86_match_ccmode (insn, CCNOmode)
-   && true_regnum (operands[0]) != 0
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCNO 17)
-                  (compare:CCNO
-                      (and:SI
-                        (zero_extract:SI
-                        (match_dup 0)
-                        (const_int 8)
-                        (const_int 8))
-                       (match_dup 1))
-                  (const_int 0)))
-             (set (zero_extract:SI (match_dup 0)
+   && true_regnum (operands[2]) != 0
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 1
+                    [(and:SI
+                       (zero_extract:SI
+                         (match_dup 2)
+                         (const_int 8)
+                         (const_int 8))
+                       (match_dup 3))
+                     (const_int 0)]))
+             (set (zero_extract:SI (match_dup 2)
                                    (const_int 8)
                                    (const_int 8))
                   (and:SI 
                     (zero_extract:SI
-                      (match_dup 0)
+                      (match_dup 2)
                       (const_int 8)
                       (const_int 8))
-                    (match_dup 1)))])]
+                    (match_dup 3)))])]
   "")
 
 ;; Don't do logical operations with memory inputs.
   "")
 \f
 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
-;; required and register dies.
-(define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:SI 0 "register_operand" "")
-                (match_operand:SI 1 "incdec_operand" "")))]
-  "ix86_match_ccmode (insn, CCGCmode)
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCGC 17)
-                  (compare:CCGC (match_dup 0)
-                                (match_dup 1)))
-             (clobber (match_dup 0))])]
-  "")
-
+;; required and register dies.  Similarly for 128 to plus -128.
 (define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:HI 0 "register_operand" "")
-                (match_operand:HI 1 "incdec_operand" "")))]
-  "ix86_match_ccmode (insn, CCGCmode)
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCGC 17)
-                  (compare:CCGC (match_dup 0)
-                                (match_dup 1)))
-             (clobber (match_dup 0))])]
-  "")
-
-(define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:QI 0 "register_operand" "")
-                (match_operand:QI 1 "incdec_operand" "")))]
-  "ix86_match_ccmode (insn, CCGCmode)
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCGC 17)
-                  (compare:CCGC (match_dup 0)
-                                (match_dup 1)))
-             (clobber (match_dup 0))])]
-  "")
-
-;; Convert compares with 128 to shorter add -128
-(define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:SI 0 "register_operand" "")
-                (const_int 128)))]
-  "ix86_match_ccmode (insn, CCGCmode)
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCGC 17)
-                  (compare:CCGC (match_dup 0)
-                                (const_int 128)))
-             (clobber (match_dup 0))])]
-  "")
-
-(define_peephole2
-  [(set (reg 17)
-       (compare (match_operand:HI 0 "register_operand" "")
-                (const_int 128)))]
-  "ix86_match_ccmode (insn, CCGCmode)
-   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
-  [(parallel [(set (reg:CCGC 17)
-                  (compare:CCGC (match_dup 0)
-                                (const_int 128)))
-             (clobber (match_dup 0))])]
+  [(set (match_operand 0 "flags_reg_operand" "")
+       (match_operator 1 "compare_operator"
+         [(match_operand 2 "register_operand" "")
+          (match_operand 3 "const_int_operand" "")]))]
+  "(INTVAL (operands[3]) == -1
+    || INTVAL (operands[3]) == 1
+    || INTVAL (operands[3]) == 128)
+   && ix86_match_ccmode (insn, CCGCmode)
+   && peep2_reg_dead_p (1, operands[2])"
+  [(parallel [(set (match_dup 0)
+                  (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
+             (clobber (match_dup 2))])]
   "")
 \f
 (define_peephole2
 {
   if (constant_call_address_operand (operands[1], QImode))
     return "call\t%P1";
-  return "call\t%*%1";
+  return "call\t%A1";
 }
   [(set_attr "type" "callv")])
 
 {
   if (constant_call_address_operand (operands[1], QImode))
     return "jmp\t%P1";
-  return "jmp\t%*%1";
+  return "jmp\t%A1";
 }
   [(set_attr "type" "callv")])
 
 
 ;; Moves for SSE/MMX regs.
 
-(define_insn "movv4sf_internal"
+(define_insn "*movv4sf_internal"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE"
+  "TARGET_SSE
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
     xorps\t%0, %0
     movaps\t{%1, %0|%0, %1}
 (define_split
   [(set (match_operand:V4SF 0 "register_operand" "")
        (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
-  "TARGET_SSE"
+  "TARGET_SSE && reload_completed"
   [(set (match_dup 0)
        (vec_merge:V4SF
         (vec_duplicate:V4SF (match_dup 1))
   operands[2] = CONST0_RTX (V4SFmode);
 })
 
-(define_insn "movv4si_internal"
+(define_insn "*movv4si_internal"
   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE"
+  "TARGET_SSE
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
 {
   switch (which_alternative)
     {
                   (const_string "TI"))]
               (const_string "TI")))])
 
-(define_insn "movv2di_internal"
+(define_insn "*movv2di_internal"
   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE"
+  "TARGET_SSE
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
 {
   switch (which_alternative)
     {
 (define_split
   [(set (match_operand:V2DF 0 "register_operand" "")
        (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
-  "TARGET_SSE2"
+  "TARGET_SSE2 && reload_completed"
   [(set (match_dup 0)
        (vec_merge:V2DF
         (vec_duplicate:V2DF (match_dup 1))
   operands[2] = CONST0_RTX (V2DFmode);
 })
 
-(define_insn "movv8qi_internal"
-  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
-       (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
+(define_insn "*movv2si_internal"
+  [(set (match_operand:V2SI 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+       (match_operand:V2SI 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
   "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
+    pxor\t%0, %0
+    movq\t{%1, %0|%0, %1}
+    movq\t{%1, %0|%0, %1}
+    movdq2q\t{%1, %0|%0, %1}
+    movq2dq\t{%1, %0|%0, %1}
     pxor\t%0, %0
     movq\t{%1, %0|%0, %1}
     movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov")
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI")])
 
-(define_insn "movv4hi_internal"
-  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
-       (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
+(define_insn "*movv4hi_internal"
+  [(set (match_operand:V4HI 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+       (match_operand:V4HI 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
   "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
+    pxor\t%0, %0
+    movq\t{%1, %0|%0, %1}
+    movq\t{%1, %0|%0, %1}
+    movdq2q\t{%1, %0|%0, %1}
+    movq2dq\t{%1, %0|%0, %1}
     pxor\t%0, %0
     movq\t{%1, %0|%0, %1}
     movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxmov")
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI")])
 
-(define_insn "movv2si_internal"
-  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
-       (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
+(define_insn "*movv8qi_internal"
+  [(set (match_operand:V8QI 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+       (match_operand:V8QI 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
   "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
+    pxor\t%0, %0
+    movq\t{%1, %0|%0, %1}
+    movq\t{%1, %0|%0, %1}
+    movdq2q\t{%1, %0|%0, %1}
+    movq2dq\t{%1, %0|%0, %1}
     pxor\t%0, %0
     movq\t{%1, %0|%0, %1}
     movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxcvt")
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI")])
 
-(define_insn "movv2sf_internal"
-  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
-        (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
-  "TARGET_3DNOW
+(define_insn "*movv2sf_internal"
+  [(set (match_operand:V2SF 0 "nonimmediate_operand"
+                                       "=y,y ,m,!y,!*Y,*x,?*x,?m")
+        (match_operand:V2SF 1 "vector_move_operand"
+                                       "C ,ym,y,*Y,y  ,C ,*xm,*x"))]
+  "TARGET_MMX
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
     pxor\t%0, %0
     movq\t{%1, %0|%0, %1}
+    movq\t{%1, %0|%0, %1}
+    movdq2q\t{%1, %0|%0, %1}
+    movq2dq\t{%1, %0|%0, %1}
+    xorps\t%0, %0
+    movq\t{%1, %0|%0, %1}
     movq\t{%1, %0|%0, %1}"
-  [(set_attr "type" "mmxcvt")
+  [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov")
    (set_attr "mode" "DI")])
 
 (define_expand "movti"
        (match_operand:TF 1 "nonimmediate_operand" ""))]
   "TARGET_64BIT"
 {
-  if (TARGET_64BIT)
-    ix86_expand_move (TFmode, operands);
-  else
-    ix86_expand_vector_move (TFmode, operands);
+  ix86_expand_move (TFmode, operands);
   DONE;
 })
 
-(define_insn "movv2df_internal"
+(define_insn "*movv2df_internal"
   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE2
+  "TARGET_SSE
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
 {
   switch (which_alternative)
 }
   [(set_attr "type" "ssemov")
    (set (attr "mode")
-        (cond [(eq_attr "alternative" "0,1")
+        (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
+                (const_string "V4SF")
+              (eq_attr "alternative" "0,1")
                 (if_then_else
                   (ne (symbol_ref "optimize_size")
                       (const_int 0))
                   (const_string "V2DF"))]
               (const_string "V2DF")))])
 
-(define_insn "movv8hi_internal"
+(define_insn "*movv8hi_internal"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE2
+  "TARGET_SSE
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
 {
   switch (which_alternative)
                   (const_string "TI"))]
               (const_string "TI")))])
 
-(define_insn "movv16qi_internal"
+(define_insn "*movv16qi_internal"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
-  "TARGET_SSE2
+  "TARGET_SSE
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
 {
   switch (which_alternative)
 (define_expand "movv2df"
   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
        (match_operand:V2DF 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
 {
   ix86_expand_vector_move (V2DFmode, operands);
   DONE;
 (define_expand "movv8hi"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
        (match_operand:V8HI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
 {
   ix86_expand_vector_move (V8HImode, operands);
   DONE;
 (define_expand "movv16qi"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
        (match_operand:V16QI 1 "nonimmediate_operand" ""))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
 {
   ix86_expand_vector_move (V16QImode, operands);
   DONE;
 (define_expand "movv2sf"
   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
        (match_operand:V2SF 1 "nonimmediate_operand" ""))]
-   "TARGET_3DNOW"
+  "TARGET_MMX"
 {
   ix86_expand_vector_move (V2SFmode, operands);
   DONE;
 (define_insn "*pushv2di"
   [(set (match_operand:V2DI 0 "push_operand" "=<")
        (match_operand:V2DI 1 "register_operand" "x"))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
   "#")
 
 (define_insn "*pushv8hi"
   [(set (match_operand:V8HI 0 "push_operand" "=<")
        (match_operand:V8HI 1 "register_operand" "x"))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
   "#")
 
 (define_insn "*pushv16qi"
   [(set (match_operand:V16QI 0 "push_operand" "=<")
        (match_operand:V16QI 1 "register_operand" "x"))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
   "#")
 
 (define_insn "*pushv4sf"
 (define_insn "*pushv4si"
   [(set (match_operand:V4SI 0 "push_operand" "=<")
        (match_operand:V4SI 1 "register_operand" "x"))]
-  "TARGET_SSE2"
+  "TARGET_SSE"
   "#")
 
 (define_insn "*pushv2si"
 (define_insn "*pushv2sf"
   [(set (match_operand:V2SF 0 "push_operand" "=<")
        (match_operand:V2SF 1 "register_operand" "y"))]
-  "TARGET_3DNOW"
+  "TARGET_MMX"
   "#")
 
 (define_split
    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
 
 
-(define_insn "movti_internal"
+(define_insn "*movti_internal"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
        (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
   "TARGET_SSE && !TARGET_64BIT
 ;; of DImode subregs again!
 ;; SSE1 single precision floating point logical operation
 (define_expand "sse_andv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (and:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_andv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "andps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_andsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "andps\t{%2, %0|%0, %2}"
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_nandv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_nandv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE"
-  "andnps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_nandsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "andnps\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_iorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_iorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "orps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_iorsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "orps\t{%2, %0|%0, %2}"
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_xorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
+  "TARGET_SSE"
   "")
 
 (define_insn "*sse_xorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "xorps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_xorsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "xorps\t{%2, %0|%0, %2}"
 ;; SSE2 double precision floating point logical operation
 
 (define_expand "sse2_andv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (and:V2DF (match_operand:V2DF 1 "register_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_andv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "andpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_andv2df3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "andpd\t{%2, %0|%0, %2}"
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_nandv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_nandv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2"
-  "andnpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse_nandti3_df"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "andnpd\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_iorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_iorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "orpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_iordf3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "orpd\t{%2, %0|%0, %2}"
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_xorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_xorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "xorpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_xordf3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "xorpd\t{%2, %0|%0, %2}"
index c4a09ba..aeed315 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions related to invoking methods and overloaded functions.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) and
    modified by Brendan Kehoe (brendan@cygnus.com).
 
@@ -86,7 +86,7 @@ static struct z_candidate *add_conv_candidate
 static struct z_candidate *add_function_candidate 
        (struct z_candidate **, tree, tree, tree, tree, tree, int);
 static tree implicit_conversion (tree, tree, tree, int);
-static tree standard_conversion (tree, tree, tree);
+static tree standard_conversion (tree, tree, tree, int);
 static tree reference_binding (tree, tree, tree, int);
 static tree build_conv (enum tree_code, tree, tree);
 static bool is_subseq (tree, tree);
@@ -454,7 +454,7 @@ strip_top_quals (tree t)
    also pass the expression EXPR to convert from.  */
 
 static tree
-standard_conversion (tree to, tree from, tree expr)
+standard_conversion (tree to, tree from, tree expr, int flags)
 {
   enum tree_code fcode, tcode;
   tree conv;
@@ -505,7 +505,7 @@ standard_conversion (tree to, tree from, tree expr)
          the standard conversion sequence to perform componentwise
          conversion.  */
       tree part_conv = standard_conversion
-        (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE);
+        (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags);
       
       if (part_conv)
         {
@@ -692,7 +692,8 @@ standard_conversion (tree to, tree from, tree expr)
       && ((*targetm.vector_opaque_p) (from)
          || (*targetm.vector_opaque_p) (to)))
     return build_conv (STD_CONV, to, conv);
-  else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
+  else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
+          && IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
           && is_properly_derived_from (from, to))
     {
       if (TREE_CODE (conv) == RVALUE_CONV)
@@ -1105,7 +1106,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, flags);
   else
-    conv = standard_conversion (to, from, expr);
+    conv = standard_conversion (to, from, expr, flags);
 
   if (conv)
     return conv;
@@ -2202,10 +2203,18 @@ any_strictly_viable (struct z_candidate *cands)
   return false;
 }
 
+/* OBJ is being used in an expression like "OBJ.f (...)".  In other
+   words, it is about to become the "this" pointer for a member
+   function call.  Take the address of the object.  */
+
 static tree
 build_this (tree obj)
 {
-  /* Fix this to work on non-lvalues.  */
+  /* In a template, we are only concerned about the type of the
+     expression, so we can take a shortcut.  */
+  if (processing_template_decl)
+    return build_address (obj);
+
   return build_unary_op (ADDR_EXPR, obj, 0);
 }
 
@@ -3277,7 +3286,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
     }
 
  valid_operands:
-  result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3));
+  result = fold_if_not_in_template (build (COND_EXPR, result_type,
+                                          arg1, arg2, arg3));
   /* We can't use result_type below, as fold might have returned a
      throw_expr.  */
 
@@ -3561,20 +3571,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
       if (overloaded_p)
        *overloaded_p = true;
 
-      if (warn_synth
-         && fnname == ansi_assopname (NOP_EXPR)
-         && DECL_ARTIFICIAL (cand->fn)
-         && candidates->next
-         && ! candidates->next->next)
-       {
-         warning ("using synthesized `%#D' for copy assignment",
-                     cand->fn);
-         cp_warning_at ("  where cfront would use `%#D'",
-                        cand == candidates
-                        ? candidates->next->fn
-                        : candidates->fn);
-       }
-
       return build_over_call (cand, LOOKUP_NORMAL);
     }
 
@@ -3878,6 +3874,7 @@ check_constructor_callable (tree type, tree expr)
                             build_tree_list (NULL_TREE, expr), 
                             TYPE_BINFO (type),
                             LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
+                            | LOOKUP_NO_CONVERSION
                             | LOOKUP_CONSTRUCTOR_CALLABLE);
 }
 
@@ -6188,6 +6185,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
                                /*fn=*/NULL_TREE, /*argnum=*/0,
                                /*inner=*/-1,
                                /*issue_conversion_warnings=*/true);
+      if (error_operand_p (expr))
+       return error_mark_node;
       if (!real_lvalue_p (expr))
        {
          tree init;
index e4deb01..09daf11 100644 (file)
@@ -1,6 +1,7 @@
 /* Functions related to building classes and their related objects.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004  Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005
+     Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -2115,6 +2116,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
          also be converting to the return type of FN, we have to
          combine the two conversions here.  */
       tree fixed_offset, virtual_offset;
+
+      over_return = TREE_TYPE (over_return);
+      base_return = TREE_TYPE (base_return);
       
       if (DECL_THUNK_P (fn))
        {
@@ -2132,32 +2136,51 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
        virtual_offset =
          TREE_VALUE (purpose_member
                      (BINFO_TYPE (virtual_offset),
-                      CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
-      else if (!same_type_p (TREE_TYPE (over_return),
-                            TREE_TYPE (base_return)))
+                      CLASSTYPE_VBASECLASSES (over_return)));
+      else if (!same_type_ignoring_top_level_qualifiers_p
+              (over_return, base_return))
        {
-         /* There was no existing virtual thunk (which takes
-            precedence).  */
-         tree thunk_binfo;
-         base_kind kind;
+         /* There was no existing virtual thunk (which takes
+            precedence).  So find the binfo of the base function's
+            return type within the overriding function's return type.
+            We cannot call lookup base here, because we're inside a
+            dfs_walk, and will therefore clobber the BINFO_MARKED
+            flags.  Fortunately we know the covariancy is valid (it
+            has already been checked), so we can just iterate along
+            the binfos, which have been chained in inheritance graph
+            order.  Of course it is lame that we have to repeat the
+            search here anyway -- we should really be caching pieces
+            of the vtable and avoiding this repeated work.  */
+         tree thunk_binfo, base_binfo;
+
+         /* Find the base binfo within the overriding function's
+            return type.  We will always find a thunk_binfo, except
+            when the covariancy is invalid (which we will have
+            already diagnosed).  */
+         for (base_binfo = TYPE_BINFO (base_return),
+              thunk_binfo = TYPE_BINFO (over_return);
+              thunk_binfo;
+              thunk_binfo = TREE_CHAIN (thunk_binfo))
+           if (same_type_p (BINFO_TYPE (thunk_binfo),
+                            BINFO_TYPE (base_binfo)))
+             break;
          
-         thunk_binfo = lookup_base (TREE_TYPE (over_return),
-                                    TREE_TYPE (base_return),
-                                    ba_check | ba_quiet, &kind);
-
-         if (thunk_binfo && (kind == bk_via_virtual
-                             || !BINFO_OFFSET_ZEROP (thunk_binfo)))
+         /* See if virtual inheritance is involved.  */
+         for (virtual_offset = thunk_binfo;
+              virtual_offset;
+              virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
+           if (TREE_VIA_VIRTUAL (virtual_offset))
+             break;
+         
+         if (virtual_offset
+             || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
            {
              tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
 
-             if (kind == bk_via_virtual)
+             if (virtual_offset)
                {
-                 /* We convert via virtual base. Find the virtual
-                    base and adjust the fixed offset to be from there.  */
-                 while (!TREE_VIA_VIRTUAL (thunk_binfo))
-                   thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
-
-                 virtual_offset = thunk_binfo;
+                 /* We convert via virtual base.  Adjust the fixed
+                    offset to be from there.  */
                  offset = size_diffop
                    (offset, convert
                     (ssizetype, BINFO_OFFSET (virtual_offset)));
@@ -5217,6 +5240,7 @@ finish_struct (tree t, tree attributes)
     {
       finish_struct_methods (t);
       TYPE_SIZE (t) = bitsize_zero_node;
+      TYPE_SIZE_UNIT (t) = size_zero_node;
     }
   else
     finish_struct_1 (t);
index b2fec24..ed33f32 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for C++ parsing and type checking.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -2917,7 +2917,8 @@ struct lang_decl GTY(())
 #define THUNK_ALIAS(DECL) \
   (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
 
-/* For thunk NODE, this is the FUNCTION_DECL thunked to.  */
+/* For thunk NODE, this is the FUNCTION_DECL thunked to.  It is
+   possible for the target to be a thunk too.  */
 #define THUNK_TARGET(NODE)                             \
   (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
 
@@ -3921,7 +3922,6 @@ extern int is_specialization_of                 (tree, tree);
 extern bool is_specialization_of_friend         (tree, tree);
 extern int comp_template_args                   (tree, tree);
 extern void maybe_process_partial_specialization (tree);
-extern void maybe_check_template_type           (tree);
 extern tree most_specialized_instantiation      (tree);
 extern void print_candidates                    (tree);
 extern int instantiate_pending_templates        (void);
@@ -4195,6 +4195,7 @@ extern int cp_cannot_inline_tree_fn (tree*);
 extern tree cp_add_pending_fn_decls (void*,tree);
 extern int cp_is_overload_p (tree);
 extern int cp_auto_var_in_fn_p (tree,tree);
+extern tree fold_if_not_in_template (tree);
 extern tree cp_copy_res_decl_for_inlining (tree, tree, tree, void*,
                                                   int*, tree);
 
index 48be5c5..95fce07 100644 (file)
@@ -793,6 +793,11 @@ convert_to_void (tree expr, const char *implicit)
     return expr;
   if (invalid_nonstatic_memfn_p (expr))
     return error_mark_node;
+  if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
+    {
+      error ("pseudo-destructor is not called");
+      return error_mark_node;
+    }
   if (VOID_TYPE_P (TREE_TYPE (expr)))
     return expr;
   switch (TREE_CODE (expr))
index a19c501..6c7cece 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for C++ compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004  Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -1068,6 +1068,12 @@ decls_match (tree newdecl, tree olddecl)
     }
   else
     {
+      /* Need to check scope for variable declaration (VAR_DECL).
+        For typedef (TYPE_DECL), scope is ignored.  */
+      if (TREE_CODE (newdecl) == VAR_DECL
+         && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
+       return 0;
+
       if (TREE_TYPE (newdecl) == error_mark_node)
        types_match = TREE_TYPE (olddecl) == error_mark_node;
       else if (TREE_TYPE (olddecl) == NULL_TREE)
@@ -2023,7 +2029,8 @@ redeclaration_error_message (tree newdecl, tree olddecl)
       /* If both functions come from different namespaces, this is not
         a redeclaration - this is a conflict with a used function.  */
       if (DECL_NAMESPACE_SCOPE_P (olddecl)
-         && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl))
+         && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
+         && ! decls_match (olddecl, newdecl))
        return "`%D' conflicts with used function";
 
       /* We'll complain about linkage mismatches in
@@ -3704,12 +3711,12 @@ start_decl (tree declarator,
   deprecated_state = DEPRECATED_NORMAL;
 
   if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
-    return NULL_TREE;
+    return error_mark_node;
 
   type = TREE_TYPE (decl);
 
   if (type == error_mark_node)
-    return NULL_TREE;
+    return error_mark_node;
 
   context = DECL_CONTEXT (decl);
 
@@ -4210,13 +4217,17 @@ reshape_init_array (tree elt_type, tree max_index,
                    tree *initp, tree new_init)
 {
   bool sized_array_p = (max_index != NULL_TREE);
-  HOST_WIDE_INT max_index_cst = 0;
-  HOST_WIDE_INT index;
+  unsigned HOST_WIDE_INT max_index_cst = 0;
+  unsigned HOST_WIDE_INT index;
 
   if (sized_array_p)
-    /* HWI is either 32bit or 64bit, so it must be enough to represent the
-       array size.  */
-    max_index_cst = tree_low_cst (max_index, 1);
+    {
+      if (host_integerp (max_index, 1))
+       max_index_cst = tree_low_cst (max_index, 1);
+      /* sizetype is sign extended, not zero extended.  */
+      else
+       max_index_cst = tree_low_cst (convert (size_type_node, max_index), 1);
+    }
 
   /* Loop until there are no more initializers.  */
   for (index = 0;
@@ -4242,19 +4253,7 @@ reshape_init_array (tree elt_type, tree max_index,
              TREE_PURPOSE (element_init) = NULL_TREE;
            }
          else
-           {
-             if (TREE_CODE (designated_index) != INTEGER_CST)
-               abort ();
-             if (sized_array_p
-                 && tree_int_cst_lt (max_index, designated_index))
-               {
-                 error ("Designated initializer `%E' larger than array "
-                        "size", designated_index);
-                 TREE_PURPOSE (element_init) = NULL_TREE;
-               }
-             else
-               index = tree_low_cst (designated_index, 1);
-           }
+           abort ();
        }
     }
 
@@ -4284,6 +4283,7 @@ reshape_init (tree type, tree *initp)
   tree old_init_value;
   tree new_init;
   bool brace_enclosed_p;
+  bool string_init_p;
 
   old_init = *initp;
   old_init_value = (TREE_CODE (*initp) == TREE_LIST
@@ -4348,6 +4348,7 @@ reshape_init (tree type, tree *initp)
       return old_init;
     }
 
+  string_init_p = false;
   if (TREE_CODE (old_init_value) == STRING_CST
       && TREE_CODE (type) == ARRAY_TYPE
       && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
@@ -4362,6 +4363,7 @@ reshape_init (tree type, tree *initp)
       /* Move past the initializer.  */
       *initp = TREE_CHAIN (old_init);
       TREE_CHAIN (old_init) = NULL_TREE;
+      string_init_p = true;
     }
   else
     {
@@ -4450,10 +4452,15 @@ reshape_init (tree type, tree *initp)
        new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);
     }
 
-  /* If this was a brace-enclosed initializer and all of the
-     initializers were not used up, there is a problem.  */
-  if (brace_enclosed_p && *initp)
-    error ("too many initializers for `%T'", type);
+  /* If there are more initializers than necessary, issue a
+     diagnostic.  */  
+  if (*initp)
+    {
+      if (brace_enclosed_p)
+       error ("too many initializers for `%T'", type);
+      else if (warn_missing_braces && !string_init_p)
+       warning ("missing braces around initializer");
+    }
 
   return new_init;
 }
index 7f974bf..732d4a0 100644 (file)
@@ -217,7 +217,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      tree index;
       tree max_index;
       tree inits;
 
@@ -231,14 +230,16 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
       /* A zero-sized array, which is accepted as an extension, will
         have an upper bound of -1.  */
       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
-       for (index = size_zero_node;
-            !tree_int_cst_lt (max_index, index);
-            index = size_binop (PLUS_EXPR, index, size_one_node))
-         inits = tree_cons (index,
-                            build_zero_init (TREE_TYPE (type),
-                                             /*nelts=*/NULL_TREE,
-                                             static_storage_p),
-                            inits);
+       {
+         tree elt_init = build_zero_init (TREE_TYPE (type),
+                                          /*nelts=*/NULL_TREE,
+                                          static_storage_p);
+         tree range = build (RANGE_EXPR,
+                             sizetype, size_zero_node, max_index);
+         
+         inits = tree_cons (range, elt_init, inits);
+       }
+      
       CONSTRUCTOR_ELTS (init) = nreverse (inits);
     }
   else if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -1461,14 +1462,6 @@ build_offset_ref (tree type, tree name, bool address_p)
       return error_mark_node;
     }
 
-  if (processing_template_decl)
-    {
-      if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
-       return build_min (SCOPE_REF, TREE_TYPE (member), type, orig_name);
-      else
-       return build_min (SCOPE_REF, TREE_TYPE (member), type, name);
-    }
-
   if (TREE_CODE (member) == TYPE_DECL)
     {
       TREE_USED (member) = 1;
@@ -1630,21 +1623,23 @@ decl_constant_value (tree decl)
                      TREE_OPERAND (decl, 0), d1, d2);
     }
 
-  if (DECL_P (decl)
-      && (/* Enumeration constants are constant.  */
-         TREE_CODE (decl) == CONST_DECL
-         /* And so are variables with a 'const' type -- unless they
-            are also 'volatile'.  */
-         || CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
-      && DECL_INITIAL (decl)
-      && DECL_INITIAL (decl) != error_mark_node
-      /* This is invalid if initial value is not constant.
-        If it has either a function call, a memory reference,
-        or a variable, then re-evaluating it could give different results.  */
-      && TREE_CONSTANT (DECL_INITIAL (decl))
-      /* Check for cases where this is sub-optimal, even though valid.  */
-      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
-    return DECL_INITIAL (decl);
+  while (DECL_P (decl)
+        && (/* Enumeration constants are constant.  */
+            TREE_CODE (decl) == CONST_DECL
+            /* And so are variables with a 'const' type -- unless they
+               are also 'volatile'.  */
+            || CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
+        && DECL_INITIAL (decl)
+        && DECL_INITIAL (decl) != error_mark_node
+        /* This is invalid if initial value is not constant.  If it
+           has either a function call, a memory reference, or a
+           variable, then re-evaluating it could give different
+           results.  */
+        && TREE_CONSTANT (DECL_INITIAL (decl))
+        /* Check for cases where this is sub-optimal, even though
+           valid.  */
+        && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
+    decl = DECL_INITIAL (decl);
   return decl;
 }
 \f
@@ -2549,6 +2544,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
   tree atype = TREE_TYPE (base);
   /* The type of an element in the array.  */
   tree type = TREE_TYPE (atype);
+  /* The element type reached after removing all outer array 
+     types.  */
+  tree inner_elt_type;
   /* The type of a pointer to an element in the array.  */
   tree ptype;
   tree stmt_expr;
@@ -2565,15 +2563,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
   if (maxindex == NULL_TREE || maxindex == error_mark_node)
     return error_mark_node;
 
+  inner_elt_type = strip_array_types (atype);
   if (init
       && (from_array == 2
-         ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+         ? (!CLASS_TYPE_P (inner_elt_type) 
+            || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
          : !TYPE_NEEDS_CONSTRUCTING (type))
       && ((TREE_CODE (init) == CONSTRUCTOR
           /* Don't do this if the CONSTRUCTOR might contain something
              that might throw and require us to clean up.  */
           && (CONSTRUCTOR_ELTS (init) == NULL_TREE
-              || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type))))
+              || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
          || from_array))
     {
       /* Do non-default initialization of POD arrays resulting from
index 0f72dc7..ef69c37 100644 (file)
@@ -357,6 +357,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
        There's no need to process this thunk again.  */
     return;
 
+  if (DECL_THUNK_P (function))
+    /* The target is itself a thunk, process it now.  */
+    use_thunk (function, emit_p);
+  
   /* Thunks are always addressable; they only appear in vtables.  */
   TREE_ADDRESSABLE (thunk_fndecl) = 1;
 
@@ -583,14 +587,14 @@ do_build_copy_constructor (tree fndecl)
 
       for (; fields; fields = TREE_CHAIN (fields))
        {
-         tree init;
+         tree init = parm;
          tree field = fields;
          tree expr_type;
 
          if (TREE_CODE (field) != FIELD_DECL)
            continue;
 
-         init = parm;
+         expr_type = TREE_TYPE (field);
          if (DECL_NAME (field))
            {
              if (VFIELD_NAME_P (DECL_NAME (field)))
@@ -600,9 +604,7 @@ do_build_copy_constructor (tree fndecl)
              if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
                continue;
            }
-         else if ((t = TREE_TYPE (field)) != NULL_TREE
-                  && ANON_AGGR_TYPE_P (t)
-                  && TYPE_FIELDS (t) != NULL_TREE)
+         else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
            /* Just use the field; anonymous types can't have
               nontrivial copy ctors or assignment ops.  */;
          else
@@ -613,14 +615,19 @@ do_build_copy_constructor (tree fndecl)
             the field is "T", then the type will usually be "const
             T".  (There are no cv-qualified variants of reference
             types.)  */
-         expr_type = TREE_TYPE (field);
          if (TREE_CODE (expr_type) != REFERENCE_TYPE)
-           expr_type = cp_build_qualified_type (expr_type, cvquals);
+           {
+             int quals = cvquals;
+             
+             if (DECL_MUTABLE_P (field))
+               quals &= ~TYPE_QUAL_CONST;
+             expr_type = cp_build_qualified_type (expr_type, quals);
+           }
+         
          init = build (COMPONENT_REF, expr_type, init, field);
          init = build_tree_list (NULL_TREE, init);
 
-         member_init_list
-           = tree_cons (field, init, member_init_list);
+         member_init_list = tree_cons (field, init, member_init_list);
        }
       finish_mem_initializers (member_init_list);
     }
@@ -675,26 +682,27 @@ do_build_assign_ref (tree fndecl)
           fields; 
           fields = TREE_CHAIN (fields))
        {
-         tree comp, init, t;
+         tree comp = current_class_ref;
+         tree init = parm;
          tree field = fields;
+         tree expr_type;
+         int quals;
 
          if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
            continue;
 
-         if (CP_TYPE_CONST_P (TREE_TYPE (field)))
+         expr_type = TREE_TYPE (field);
+         if (CP_TYPE_CONST_P (expr_type))
            {
               error ("non-static const member `%#D', can't use default assignment operator", field);
              continue;
            }
-         else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
+         else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
            {
              error ("non-static reference member `%#D', can't use default assignment operator", field);
              continue;
            }
 
-         comp = current_class_ref;
-         init = parm;
-
          if (DECL_NAME (field))
            {
              if (VFIELD_NAME_P (DECL_NAME (field)))
@@ -704,24 +712,27 @@ do_build_assign_ref (tree fndecl)
              if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
                continue;
            }
-         else if ((t = TREE_TYPE (field)) != NULL_TREE
-                  && ANON_AGGR_TYPE_P (t)
-                  && TYPE_FIELDS (t) != NULL_TREE)
+         else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
            /* Just use the field; anonymous types can't have
               nontrivial copy ctors or assignment ops.  */;
          else
            continue;
 
          comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
-         init = build (COMPONENT_REF,
-                       cp_build_qualified_type (TREE_TYPE (field), cvquals),
-                       init, field);
+
+         /* Compute the type of init->field  */
+         quals = cvquals;
+         if (DECL_MUTABLE_P (field))
+           quals &= ~TYPE_QUAL_CONST;
+         expr_type = cp_build_qualified_type (expr_type, quals);
+         
+         init = build (COMPONENT_REF, expr_type, init, field);
 
          if (DECL_NAME (field))
-           finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
+           init = build_modify_expr (comp, NOP_EXPR, init);
          else
-           finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp,
-                                    init));
+           init = build (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
+         finish_expr_stmt (init);
        }
     }
   finish_return_stmt (current_class_ref);
index d627e00..3e79d3e 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions for C++ name lookup routines.
-   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -2018,7 +2018,8 @@ push_overloaded_decl (tree decl, int flags)
              if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
                  && !(flags & PUSH_USING)
                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
-                               TYPE_ARG_TYPES (TREE_TYPE (decl))))
+                               TYPE_ARG_TYPES (TREE_TYPE (decl)))
+                 && ! decls_match (fn, decl))
                error ("`%#D' conflicts with previous using declaration `%#D'",
                          decl, fn);
 
@@ -2804,6 +2805,7 @@ push_class_level_binding (tree name, tree x)
        || TREE_CODE (x) == CONST_DECL
        || (TREE_CODE (x) == TYPE_DECL
           && !DECL_SELF_REFERENCE_P (x))
+       || DECL_CLASS_TEMPLATE_P (x)
        /* A data member of an anonymous union.  */
        || (TREE_CODE (x) == FIELD_DECL
           && DECL_CONTEXT (x) != current_class_type))
@@ -4541,12 +4543,9 @@ maybe_process_template_type_declaration (tree type, int globalize,
     ;
   else
     {
-      maybe_check_template_type (type);
-
       my_friendly_assert (IS_AGGR_TYPE (type)
                          || TREE_CODE (type) == ENUMERAL_TYPE, 0);
 
-
       if (processing_template_decl)
        {
          /* This may change after the call to
index 2c29462..fb0d1e3 100644 (file)
@@ -1,5 +1,6 @@
 /* C++ Parser.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004,
+   2005 Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -2850,6 +2851,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        tree qualifying_scope;
        tree object_scope;
        tree scope;
+       bool done;
 
        /* Consume the `~' token.  */
        cp_lexer_consume_token (parser->lexer);
@@ -2906,6 +2908,8 @@ cp_parser_unqualified_id (cp_parser* parser,
 
        /* If there was an explicit qualification (S::~T), first look
           in the scope given by the qualification (i.e., S).  */
+       done = false;
+       type_decl = NULL_TREE;
        if (scope)
          {
            cp_parser_parse_tentatively (parser);
@@ -2917,10 +2921,10 @@ cp_parser_unqualified_id (cp_parser* parser,
                                              /*class_head_p=*/false,
                                              declarator_p);
            if (cp_parser_parse_definitely (parser))
-             return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+             done = true;
          }
        /* In "N::S::~S", look in "N" as well.  */
-       if (scope && qualifying_scope)
+       if (!done && scope && qualifying_scope)
          {
            cp_parser_parse_tentatively (parser);
            parser->scope = qualifying_scope;
@@ -2935,10 +2939,10 @@ cp_parser_unqualified_id (cp_parser* parser,
                                      /*class_head_p=*/false,
                                      declarator_p);
            if (cp_parser_parse_definitely (parser))
-             return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+             done = true;
          }
        /* In "p->S::~T", look in the scope given by "*p" as well.  */
-       else if (object_scope)
+       else if (!done && object_scope)
          {
            cp_parser_parse_tentatively (parser);
            parser->scope = object_scope;
@@ -2953,20 +2957,23 @@ cp_parser_unqualified_id (cp_parser* parser,
                                      /*class_head_p=*/false,
                                      declarator_p);
            if (cp_parser_parse_definitely (parser))
-             return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+             done = true;
          }
        /* Look in the surrounding context.  */
-       parser->scope = NULL_TREE;
-       parser->object_scope = NULL_TREE;
-       parser->qualifying_scope = NULL_TREE;
-       type_decl 
-         = cp_parser_class_name (parser, 
-                                 /*typename_keyword_p=*/false,
-                                 /*template_keyword_p=*/false,
-                                 /*type_p=*/false,
-                                 /*check_dependency=*/false,
-                                 /*class_head_p=*/false,
-                                 declarator_p);
+       if (!done)
+         {
+           parser->scope = NULL_TREE;
+           parser->object_scope = NULL_TREE;
+           parser->qualifying_scope = NULL_TREE;
+           type_decl 
+             = cp_parser_class_name (parser, 
+                                     /*typename_keyword_p=*/false,
+                                     /*template_keyword_p=*/false,
+                                     /*type_p=*/false,
+                                     /*check_dependency=*/false,
+                                     /*class_head_p=*/false,
+                                     declarator_p);
+         }
        /* If an error occurred, assume that the name of the
           destructor is the same as the name of the qualifying
           class.  That allows us to keep parsing after running
@@ -3544,18 +3551,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
        bool template_p = false;
        tree id;
        tree type;
+       tree scope;
 
        /* Consume the `typename' token.  */
        cp_lexer_consume_token (parser->lexer);
        /* Look for the optional `::' operator.  */
        cp_parser_global_scope_opt (parser, 
                                    /*current_scope_valid_p=*/false);
-       /* Look for the nested-name-specifier.  */
-       cp_parser_nested_name_specifier (parser,
-                                        /*typename_keyword_p=*/true,
-                                        /*check_dependency_p=*/true,
-                                        /*type_p=*/true,
-                                        /*is_declaration=*/true);
+       /* Look for the nested-name-specifier.  In case of error here,
+          consume the trailing id to avoid subsequent error messages
+          for usual cases.  */
+       scope = cp_parser_nested_name_specifier (parser,
+                                                /*typename_keyword_p=*/true,
+                                                /*check_dependency_p=*/true,
+                                                /*type_p=*/true,
+                                                /*is_declaration=*/true);
+
        /* Look for the optional `template' keyword.  */
        template_p = cp_parser_optional_template_keyword (parser);
        /* We don't know whether we're looking at a template-id or an
@@ -3568,9 +3579,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
        /* If that didn't work, try an identifier.  */
        if (!cp_parser_parse_definitely (parser))
          id = cp_parser_identifier (parser);
+
+       /* Don't process id if nested name specifier is invalid.  */
+       if (scope == error_mark_node)
+         return error_mark_node;
        /* If we look up a template-id in a non-dependent qualifying
           scope, there's no need to create a dependent type.  */
-       if (TREE_CODE (id) == TYPE_DECL
+       else if (TREE_CODE (id) == TYPE_DECL
            && !dependent_type_p (parser->scope))
          type = TREE_TYPE (id);
        /* Create a TYPENAME_TYPE to represent the type to which the
@@ -8030,6 +8045,13 @@ cp_parser_template_id (cp_parser *parser,
       token->keyword = RID_MAX;
       /* Purge all subsequent tokens.  */
       cp_lexer_purge_tokens_after (parser->lexer, token);
+
+      /* ??? Can we actually assume that, if template_id ==
+        error_mark_node, we will have issued a diagnostic to the
+        user, as opposed to simply marking the tentative parse as
+        failed?  */
+      if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
+       error ("parse error in template argument list");
     }
 
   pop_deferring_access_checks ();
@@ -8209,6 +8231,8 @@ cp_parser_template_name (cp_parser* parser,
     ;
   else 
     {
+      tree fn = NULL_TREE;
+
       /* The standard does not explicitly indicate whether a name that
         names a set of overloaded declarations, some of which are
         templates, is a template-name.  However, such a name should
@@ -8216,14 +8240,11 @@ cp_parser_template_name (cp_parser* parser,
         template-id for the overloaded templates.  */
       fns = BASELINK_P (decl) ? BASELINK_FUNCTIONS (decl) : decl;
       if (TREE_CODE (fns) == OVERLOAD)
-       {
-         tree fn;
-         
-         for (fn = fns; fn; fn = OVL_NEXT (fn))
-           if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
-             break;
-       }
-      else
+       for (fn = fns; fn; fn = OVL_NEXT (fn))
+         if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
+           break;
+
+      if (!fn)
        {
          /* Otherwise, the name does not name a template.  */
          cp_parser_error (parser, "expected template-name");
@@ -8724,21 +8745,40 @@ cp_parser_type_specifier (cp_parser* parser,
   keyword = token->keyword;
   switch (keyword)
     {
+    case RID_ENUM:
+      /* 'enum' [identifier] '{' introduces an enum-specifier;
+        'enum' <anything else> introduces an elaborated-type-specifier.  */
+      if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_BRACE
+         || (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
+             && cp_lexer_peek_nth_token (parser->lexer, 3)->type
+                == CPP_OPEN_BRACE))
+       {
+         if (parser->num_template_parameter_lists)
+           {
+             error ("template declaration of `enum'");
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             type_spec = error_mark_node;
+           }
+         else
+           type_spec = cp_parser_enum_specifier (parser);
+
+         if (declares_class_or_enum)
+           *declares_class_or_enum = 2;
+         return type_spec;
+       }
+      else
+       goto elaborated_type_specifier;
+
       /* Any of these indicate either a class-specifier, or an
         elaborated-type-specifier.  */
     case RID_CLASS:
     case RID_STRUCT:
     case RID_UNION:
-    case RID_ENUM:
       /* Parse tentatively so that we can back up if we don't find a
         class-specifier or enum-specifier.  */
       cp_parser_parse_tentatively (parser);
-      /* Look for the class-specifier or enum-specifier.  */
-      if (keyword == RID_ENUM)
-       type_spec = cp_parser_enum_specifier (parser);
-      else
-       type_spec = cp_parser_class_specifier (parser);
-
+      /* Look for the class-specifier.  */
+      type_spec = cp_parser_class_specifier (parser);
       /* If that worked, we're done.  */
       if (cp_parser_parse_definitely (parser))
        {
@@ -8750,6 +8790,7 @@ cp_parser_type_specifier (cp_parser* parser,
       /* Fall through.  */
 
     case RID_TYPENAME:
+    elaborated_type_specifier:
       /* Look for an elaborated-type-specifier.  */
       type_spec = cp_parser_elaborated_type_specifier (parser,
                                                       is_friend,
@@ -11522,6 +11563,9 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
 {
   tree initializer = NULL_TREE;
 
+  /* Assume the expression is constant.  */
+  *non_constant_p = false;
+
   /* If it is not a `{', then we are looking at an
      assignment-expression.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
@@ -12155,6 +12199,15 @@ cp_parser_class_head (cp_parser* parser,
   else if (nested_name_specifier)
     {
       tree scope;
+
+      /* Reject typedef-names in class heads.  */
+      if (!DECL_IMPLICIT_TYPEDEF_P (type))
+       {
+         error ("invalid class name in declaration of `%D'", type);
+         type = NULL_TREE;
+         goto done;
+       }
+
       /* Figure out in what scope the declaration is being placed.  */
       scope = current_scope ();
       if (!scope)
@@ -13495,36 +13548,39 @@ cp_parser_attribute_list (cp_parser* parser)
       /* Look for the identifier.  We also allow keywords here; for
         example `__attribute__ ((const))' is legal.  */
       token = cp_lexer_peek_token (parser->lexer);
-      if (token->type != CPP_NAME 
-         && token->type != CPP_KEYWORD)
-       return error_mark_node;
-      /* Consume the token.  */
-      token = cp_lexer_consume_token (parser->lexer);
-      
-      /* Save away the identifier that indicates which attribute this is.  */
-      identifier = token->value;
-      attribute = build_tree_list (identifier, NULL_TREE);
-
-      /* Peek at the next token.  */
-      token = cp_lexer_peek_token (parser->lexer);
-      /* If it's an `(', then parse the attribute arguments.  */
-      if (token->type == CPP_OPEN_PAREN)
+      if (token->type == CPP_NAME 
+         || token->type == CPP_KEYWORD)
        {
-         tree arguments;
+         /* Consume the token.  */
+         token = cp_lexer_consume_token (parser->lexer);
 
-         arguments = (cp_parser_parenthesized_expression_list 
-                      (parser, true, /*non_constant_p=*/NULL));
-         /* Save the identifier and arguments away.  */
-         TREE_VALUE (attribute) = arguments;
-       }
+         /* Save away the identifier that indicates which attribute 
+            this is.  */
+         identifier = token->value;
+         attribute = build_tree_list (identifier, NULL_TREE);
 
-      /* Add this attribute to the list.  */
-      TREE_CHAIN (attribute) = attribute_list;
-      attribute_list = attribute;
+         /* Peek at the next token.  */
+         token = cp_lexer_peek_token (parser->lexer);
+         /* If it's an `(', then parse the attribute arguments.  */
+         if (token->type == CPP_OPEN_PAREN)
+           {
+             tree arguments;
 
-      /* Now, look for more attributes.  */
-      token = cp_lexer_peek_token (parser->lexer);
-      /* If the next token isn't a `,', we're done.  */
+             arguments = (cp_parser_parenthesized_expression_list 
+                          (parser, true, /*non_constant_p=*/NULL));
+             /* Save the identifier and arguments away.  */
+             TREE_VALUE (attribute) = arguments;
+           }
+
+         /* Add this attribute to the list.  */
+         TREE_CHAIN (attribute) = attribute_list;
+         attribute_list = attribute;
+
+         /* Now, look for more attributes.  */
+         token = cp_lexer_peek_token (parser->lexer);
+       }
+      /* Now, look for more attributes.  If the next token isn't a
+        `,', we're done.  */
       if (token->type != CPP_COMMA)
        break;
 
@@ -14814,10 +14870,12 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
       parser->local_variables_forbidden_p = true;
        /* Parse the assignment-expression.  */
-      if (DECL_CLASS_SCOPE_P (fn))
+      if (DECL_FRIEND_CONTEXT (fn))
+       push_nested_class (DECL_FRIEND_CONTEXT (fn));
+      else if (DECL_CLASS_SCOPE_P (fn))
        push_nested_class (DECL_CONTEXT (fn));
       TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
-      if (DECL_CLASS_SCOPE_P (fn))
+      if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn))
        pop_nested_class ();
 
       /* If the token stream has not been completely used up, then
index 6626871..e5aadc1 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle parameterized types (templates) for GNU C++.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004  Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
    Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
    Rewritten by Jason Merrill (jason@cygnus.com).
 
@@ -180,7 +180,9 @@ push_access_scope (tree t)
                      || TREE_CODE (t) == VAR_DECL,
                      0);
 
-  if (DECL_CLASS_SCOPE_P (t))
+  if (DECL_FRIEND_CONTEXT (t))
+    push_nested_class (DECL_FRIEND_CONTEXT (t));
+  else if (DECL_CLASS_SCOPE_P (t))
     push_nested_class (DECL_CONTEXT (t));
   else
     push_to_top_level ();
@@ -205,7 +207,7 @@ pop_access_scope (tree t)
       saved_access_scope = TREE_CHAIN (saved_access_scope);
     }
 
-  if (DECL_CLASS_SCOPE_P (t))
+  if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
     pop_nested_class ();
   else
     pop_from_top_level ();
@@ -1955,6 +1957,10 @@ check_explicit_specialization (tree declarator,
                  DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
                  DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl))
                    = DECL_SOURCE_LOCATION (decl);
+                 /* We want to use the argument list specified in the
+                    definition, not in the original declaration.  */
+                 DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl))
+                   = DECL_ARGUMENTS (decl);
                }
              return tmpl;
            }
@@ -1991,49 +1997,6 @@ check_explicit_specialization (tree declarator,
   return decl;
 }
 
-/* TYPE is being declared.  Verify that the use of template headers
-   and such is reasonable.  Issue error messages if not.  */
-
-void
-maybe_check_template_type (tree type)
-{
-  if (template_header_count)
-    {
-      /* We are in the scope of some `template <...>' header.  */
-
-      int context_depth 
-       = template_class_depth_real (TYPE_CONTEXT (type),
-                                    /*count_specializations=*/1);
-
-      if (template_header_count <= context_depth)
-       /* This is OK; the template headers are for the context.  We
-          are actually too lenient here; like
-          check_explicit_specialization we should consider the number
-          of template types included in the actual declaration.  For
-          example, 
-
-            template <class T> struct S {
-              template <class U> template <class V>
-              struct I {};
-            }; 
-
-          is invalid, but:
-
-            template <class T> struct S {
-              template <class U> struct I;
-            }; 
-
-            template <class T> template <class U.
-            struct S<T>::I {};
-
-          is not.  */
-       ; 
-      else if (template_header_count > context_depth + 1)
-       /* There are two many template parameter lists.  */
-       error ("too many template parameter lists in declaration of `%T'", type); 
-    }
-}
-
 /* Returns 1 iff PARMS1 and PARMS2 are identical sets of template
    parameters.  These are represented in the same format used for
    DECL_TEMPLATE_PARMS.  */
@@ -7519,7 +7482,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
                                  /*entering_scope=*/1);
          if (ctx != DECL_CONTEXT (t))
-           return lookup_field (ctx, DECL_NAME (t), 0, false);
+           {
+             tree r = lookup_field (ctx, DECL_NAME (t), 0, false);
+             if (!r)
+               {
+                 if (complain & tf_error)
+                   error ("using invalid field `%D'", t);
+                 return error_mark_node;
+               }
+             return r;
+           }
        }
       return t;
 
@@ -8454,7 +8426,11 @@ tsubst_copy_and_build (tree t,
           lookup finds a non-function, in accordance with the
           expected resolution of DR 218.  */
        if (koenig_p
-           && (is_overloaded_fn (function)
+           && ((is_overloaded_fn (function)
+                /* If lookup found a member function, the Koenig lookup is
+                   not appropriate, even if an unqualified-name was used
+                   to denote the function.  */
+                && !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
                || TREE_CODE (function) == IDENTIFIER_NODE))
          function = perform_koenig_lookup (function, call_args);
 
@@ -8544,7 +8520,9 @@ tsubst_copy_and_build (tree t,
        else
          member = tsubst_copy (member, args, complain, in_decl);
 
-       if (!CLASS_TYPE_P (TREE_TYPE (object)))
+       if (member == error_mark_node)
+         return error_mark_node;
+       else if (!CLASS_TYPE_P (TREE_TYPE (object)))
          {
            if (TREE_CODE (member) == BIT_NOT_EXPR)
              return finish_pseudo_destructor_expr (object, 
@@ -8570,9 +8548,14 @@ tsubst_copy_and_build (tree t,
                                            /*is_type_p=*/false,
                                            /*complain=*/false);
            if (BASELINK_P (member))
-             BASELINK_FUNCTIONS (member) 
-               = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
-                           args);
+             {
+               BASELINK_FUNCTIONS (member) 
+                 = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
+                             args);
+               member = (adjust_result_of_qualified_name_lookup 
+                         (member, BINFO_TYPE (BASELINK_BINFO (member)), 
+                          TREE_TYPE (object)));
+             }
            else
              {
                qualified_name_lookup_error (TREE_TYPE (object), tmpl);
@@ -8909,6 +8892,9 @@ fn_type_unification (tree fn,
       tree converted_args;
       bool incomplete;
 
+      if (explicit_targs == error_mark_node)
+       return 1;
+
       converted_args
        = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn), 
                                  explicit_targs, NULL_TREE, tf_none, 
@@ -12250,7 +12236,8 @@ build_non_dependent_expr (tree expr)
   if (TREE_CODE (inner_expr) == OVERLOAD 
       || TREE_CODE (inner_expr) == FUNCTION_DECL
       || TREE_CODE (inner_expr) == TEMPLATE_DECL
-      || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR)
+      || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR
+      || TREE_CODE (inner_expr) == OFFSET_REF)
     return expr;
   /* Preserve string constants; conversions from string constants to
      "char *" are allowed, even though normally a "const char *"
index f41e503..bb2f3c9 100644 (file)
@@ -4,7 +4,7 @@
    and during the instantiation of template functions. 
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.  
 
@@ -1443,6 +1443,9 @@ finish_stmt_expr_expr (tree expr)
   tree result = NULL_TREE;
   tree type = void_type_node;
 
+  if (error_operand_p (expr))
+    return error_mark_node;
+  
   if (expr)
     {
       type = TREE_TYPE (expr);
@@ -2558,6 +2561,20 @@ finish_id_expression (tree id_expression,
          if (TREE_CODE (decl) == VAR_DECL
              || TREE_CODE (decl) == PARM_DECL)
            return decl;
+         /* The same is true for FIELD_DECL, but we also need to
+            make sure that the syntax is correct.  */
+         else if (TREE_CODE (decl) == FIELD_DECL)
+           {
+             /* Since SCOPE is NULL here, this is an unqualified name.
+                Access checking has been performed during name lookup
+                already.  Turn off checking to avoid duplicate errors.  */
+             push_deferring_access_checks (dk_no_check);
+             decl = finish_non_static_data_member
+                      (decl, current_class_ref,
+                       /*qualifying_scope=*/NULL_TREE);
+             pop_deferring_access_checks ();
+             return decl;
+           }
          return id_expression;
        }
 
@@ -2617,8 +2634,15 @@ finish_id_expression (tree id_expression,
            decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl);
        }
       else if (TREE_CODE (decl) == FIELD_DECL)
-       decl = finish_non_static_data_member (decl, current_class_ref,
-                                             /*qualifying_scope=*/NULL_TREE);
+       {
+         /* Since SCOPE is NULL here, this is an unqualified name.
+            Access checking has been performed during name lookup
+            already.  Turn off checking to avoid duplicate errors.  */
+         push_deferring_access_checks (dk_no_check);
+         decl = finish_non_static_data_member (decl, current_class_ref,
+                                               /*qualifying_scope=*/NULL_TREE);
+         pop_deferring_access_checks ();
+       }
       else if (is_overloaded_fn (decl))
        {
          tree first_fn = OVL_CURRENT (decl);
index 351467c..2e41211 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-dependent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -1604,6 +1604,11 @@ cp_tree_equal (tree t1, tree t2)
 
       return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
 
+    case OVERLOAD:
+      if (OVL_FUNCTION (t1) != OVL_FUNCTION (t2))
+       return false;
+      return cp_tree_equal (OVL_CHAIN (t1), OVL_CHAIN (t2));
+
     default:
       break;
     }
@@ -2517,12 +2522,28 @@ stabilize_init (tree init, tree *initp)
       if (TREE_CODE (t) == COND_EXPR)
        return false;
 
-      stabilize_call (t, initp);
+      /* The TARGET_EXPR might be initializing via bitwise copy from
+        another variable; leave that alone.  */
+      if (TREE_SIDE_EFFECTS (t))
+       stabilize_call (t, initp);
     }
 
   return true;
 }
 
+/* Like "fold", but should be used whenever we might be processing the
+   body of a template.  */
+
+tree
+fold_if_not_in_template (tree expr)
+{
+  /* In the body of a template, there is never any need to call
+     "fold".  We will call fold later when actually instantiating the
+     template.  Integral constant expressions in templates will be
+     evaluated via fold_non_dependent_expr, as necessary.  */
+  return (processing_template_decl ? expr : fold (expr));
+}
+
 \f
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree
index d7c1cb3..0c9c6c4 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C++ compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -1216,7 +1216,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
   if (type == error_mark_node)
     return error_mark_node;
   
-  if (processing_template_decl)
+  if (dependent_type_p (type))
     {
       value = build_min (op, size_type_node, type);
       TREE_READONLY (value) = 1;
@@ -3458,7 +3458,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     tree result = build (resultcode, build_type, op0, op1);
     tree folded;
 
-    folded = fold (result);
+    folded = fold_if_not_in_template (result);
     if (folded == result)
       TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
     if (final_type != 0)
@@ -3549,23 +3549,6 @@ build_x_unary_op (enum tree_code code, tree xarg)
       if (type_dependent_expression_p (xarg))
        return build_min_nt (code, xarg, NULL_TREE);
 
-      /* For non-dependent pointer-to-member, the SCOPE_REF will be
-        processed during template substitution.  Just compute the
-        right type here and build an ADDR_EXPR around it for
-        diagnostics.  */
-      if (code == ADDR_EXPR && TREE_CODE (xarg) == SCOPE_REF)
-       {
-         tree type;
-         if (TREE_TYPE (xarg) == unknown_type_node)
-           type = unknown_type_node;
-         else if (TREE_CODE (TREE_TYPE (xarg)) == FUNCTION_TYPE)
-           type = build_pointer_type (TREE_TYPE (xarg));
-         else
-           type = build_ptrmem_type (TREE_OPERAND (xarg, 0),
-                                     TREE_TYPE (xarg));
-         return build_min (code, type, xarg, NULL_TREE);
-       }
-
       xarg = build_non_dependent_expr (xarg);
     }
 
@@ -3627,13 +3610,13 @@ build_x_unary_op (enum tree_code code, tree xarg)
       else if (TREE_CODE (xarg) == TARGET_EXPR)
        warning ("taking address of temporary");
       exp = build_unary_op (ADDR_EXPR, xarg, 0);
-      if (TREE_CODE (exp) == ADDR_EXPR)
-       PTRMEM_OK_P (exp) = ptrmem;
     }
 
   if (processing_template_decl && exp != error_mark_node)
-    return build_min_non_dep (code, exp, orig_expr,
-                             /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
+    exp = build_min_non_dep (code, exp, orig_expr,
+                            /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
+  if (TREE_CODE (exp) == ADDR_EXPR)
+    PTRMEM_OK_P (exp) = ptrmem;
   return exp;
 }
 
@@ -4095,6 +4078,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
         is an error.  */
       else if (TREE_CODE (argtype) != FUNCTION_TYPE
               && TREE_CODE (argtype) != METHOD_TYPE
+              && TREE_CODE (arg) != OFFSET_REF
               && !lvalue_or_else (arg, "unary `&'"))
        return error_mark_node;
 
@@ -4109,7 +4093,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
               expression so we can just form an ADDR_EXPR with the
               correct type.  */
            || processing_template_decl)
-         addr = build_address (arg);
+         {
+           addr = build_address (arg);
+           if (TREE_CODE (arg) == OFFSET_REF)
+             PTRMEM_OK_P (addr) = PTRMEM_OK_P (arg);
+         }
        else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
          {
            tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
@@ -4178,7 +4166,8 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
    for certain kinds of expressions which are not really lvalues
    but which we can accept as lvalues.
 
-   If ARG is not a kind of expression we can handle, return zero.  */
+   If ARG is not a kind of expression we can handle, return
+   NULL_TREE.  */
    
 tree
 unary_complex_lvalue (enum tree_code code, tree arg)
index f11dbe1..780c3e7 100644 (file)
@@ -348,9 +348,11 @@ split_nonconstant_init_1 (tree dest, tree init, tree *pcode)
     case VECTOR_TYPE:
       if (!initializer_constant_valid_p (init, type))
        {
+         tree cons = copy_node (init);
          CONSTRUCTOR_ELTS (init) = NULL;
-         code = build (MODIFY_EXPR, type, dest, init);
+         code = build (MODIFY_EXPR, type, dest, cons);
          code = build_stmt (EXPR_STMT, code);
+         *pcode = code;
          pcode = &TREE_CHAIN (code);
        }
       break;
index 1ca793d..9aea34c 100644 (file)
@@ -168,6 +168,7 @@ static void open_file_failed (cpp_reader *pfile, _cpp_file *file);
 static struct file_hash_entry *search_cache (struct file_hash_entry *head,
                                             const cpp_dir *start_dir);
 static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
+static void destroy_cpp_file (_cpp_file *);
 static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
 static void allocate_file_hash_entries (cpp_reader *pfile);
 static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
@@ -598,12 +599,38 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
       if ((import || f->once_only)
          && f->err_no == 0
          && f->st.st_mtime == file->st.st_mtime
-         && f->st.st_size == file->st.st_size
-         && read_file (pfile, f)
-         /* Size might have changed in read_file().  */
-         && f->st.st_size == file->st.st_size
-         && !memcmp (f->buffer, file->buffer, f->st.st_size))
-       break;
+         && f->st.st_size == file->st.st_size)
+       {
+         _cpp_file *ref_file;
+         bool same_file_p = false;
+
+         if (f->buffer && !f->buffer_valid)
+           {
+             /* We already have a buffer but it is not valid, because
+                the file is still stacked.  Make a new one.  */
+             ref_file = make_cpp_file (pfile, f->dir, f->name);
+             ref_file->path = f->path;
+           }
+         else
+           /* The file is not stacked anymore.  We can reuse it.  */
+           ref_file = f;
+
+         same_file_p = read_file (pfile, ref_file)
+                       /* Size might have changed in read_file().  */
+                       && ref_file->st.st_size == file->st.st_size
+                       && !memcmp (ref_file->buffer,
+                                   file->buffer,
+                                   file->st.st_size);
+
+         if (f->buffer && !f->buffer_valid)
+           {
+             ref_file->path = 0;
+             destroy_cpp_file (ref_file);
+           }
+
+         if (same_file_p)
+           break;
+       }
     }
 
   return f == NULL;
@@ -781,6 +808,16 @@ make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
   return file;
 }
 
+/* Release a _cpp_file structure.  */
+static void
+destroy_cpp_file (_cpp_file *file)
+{
+  if (file->buffer)
+    free ((void *) file->buffer);
+  free ((void *) file->name);
+  free (file);
+}
+
 /* A hash of directory names.  The directory names are the path names
    of files which contain a #include "", the included file name is
    appended to this directories.
index 60a86e3..298f5e6 100644 (file)
@@ -680,6 +680,14 @@ do_include_common (cpp_reader *pfile, enum include_type type)
   if (!fname)
     return;
 
+  if (!*fname)
+  {
+    cpp_error (pfile, CPP_DL_ERROR, "empty filename in #%s",
+               pfile->directive->name);
+    free ((void *) fname);
+    return;
+  }
+
   /* Prevent #include recursion.  */
   if (pfile->line_maps.depth >= CPP_STACK_MAX)
     cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply");
index 11ac09f..2298c85 100644 (file)
@@ -1626,6 +1626,7 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
        len += NODE_LEN (macro->params[i]) + 1; /* "," */
     }
 
+  /* This should match below where we fill in the buffer.  */
   if (CPP_OPTION (pfile, traditional))
     len += _cpp_replacement_text_len (macro);
   else
@@ -1637,11 +1638,14 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
          if (token->type == CPP_MACRO_ARG)
            len += NODE_LEN (macro->params[token->val.arg_no - 1]);
          else
-           len += cpp_token_len (token) + 1; /* Includes room for ' '.  */
+           len += cpp_token_len (token);
+
          if (token->flags & STRINGIFY_ARG)
            len++;                      /* "#" */
          if (token->flags & PASTE_LEFT)
            len += 3;           /* " ##" */
+         if (token->flags & PREV_WHITE)
+           len++;              /* " " */
        }
     }
 
@@ -1701,10 +1705,10 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
 
          if (token->type == CPP_MACRO_ARG)
            {
-             len = NODE_LEN (macro->params[token->val.arg_no - 1]);
              memcpy (buffer,
-                     NODE_NAME (macro->params[token->val.arg_no - 1]), len);
-             buffer += len;
+                     NODE_NAME (macro->params[token->val.arg_no - 1]),
+                     NODE_LEN (macro->params[token->val.arg_no - 1]));
+             buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
            }
          else
            buffer = cpp_spell_token (pfile, token, buffer);
index 99a9def..b12ea5c 100644 (file)
@@ -2447,6 +2447,37 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 
          letter = decl_function_context (decl) ? 'V' : 'S';
 
+         /* Some ports can transform a symbol ref into a label ref,
+            because the symbol ref is too far away and has to be
+            dumped into a constant pool.  Alternatively, the symbol
+            in the constant pool might be referenced by a different
+            symbol.  */
+         if (GET_CODE (current_sym_addr) == SYMBOL_REF
+             && CONSTANT_POOL_ADDRESS_P (current_sym_addr))
+           {
+             bool marked;
+             rtx tmp = get_pool_constant_mark (current_sym_addr, &marked);
+
+             if (GET_CODE (tmp) == SYMBOL_REF)
+               {
+                 current_sym_addr = tmp;
+                 if (CONSTANT_POOL_ADDRESS_P (current_sym_addr))
+                   get_pool_constant_mark (current_sym_addr, &marked);
+                 else
+                   marked = true;
+               }
+             else if (GET_CODE (tmp) == LABEL_REF)
+               {
+                 current_sym_addr = tmp;
+                 marked = true;
+               }
+
+             /* If all references to the constant pool were optimized
+                out, we just ignore the symbol.  */
+             if (!marked)
+               return 0;
+           }
+
          /* This should be the same condition as in assemble_variable, but
             we don't have access to dont_output_data here.  So, instead,
             we rely on the fact that error_mark_node initializers always
@@ -2461,37 +2492,6 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
            current_sym_code = DBX_STATIC_CONST_VAR_CODE;
          else
            {
-             /* Some ports can transform a symbol ref into a label ref,
-                because the symbol ref is too far away and has to be
-                dumped into a constant pool.  Alternatively, the symbol
-                in the constant pool might be referenced by a different
-                symbol.  */
-             if (GET_CODE (current_sym_addr) == SYMBOL_REF
-                 && CONSTANT_POOL_ADDRESS_P (current_sym_addr))
-               {
-                 bool marked;
-                 rtx tmp = get_pool_constant_mark (current_sym_addr, &marked);
-
-                 if (GET_CODE (tmp) == SYMBOL_REF)
-                   {
-                     current_sym_addr = tmp;
-                     if (CONSTANT_POOL_ADDRESS_P (current_sym_addr))
-                       get_pool_constant_mark (current_sym_addr, &marked);
-                     else
-                       marked = true;
-                   }
-                 else if (GET_CODE (tmp) == LABEL_REF)
-                   {
-                     current_sym_addr = tmp;
-                     marked = true;
-                   }
-
-                  /* If all references to the constant pool were optimized
-                     out, we just ignore the symbol.  */
-                 if (!marked)
-                   return 0;
-               }
-
              /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
              data_section ();
index fff782f..d603547 100644 (file)
@@ -139,6 +139,12 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
 #endif
 #endif
 
+/* Decide whether to defer emitting the assembler output for an equate
+   of two values.  The default is to not defer output.  */
+#ifndef TARGET_DEFERRED_OUTPUT_DEFS
+#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) false
+#endif
+
 /* This is how to output the definition of a user-level label named
    NAME, such as the label on a static function or variable NAME.  */
 
index 0b4cd44..4638645 100644 (file)
@@ -2048,6 +2048,8 @@ typedef void voidfn ();
 volatile voidfn fatal;
 @end smallexample
 
+This approach does not work in GNU C++.
+
 @cindex @code{noinline} function attribute
 @item noinline
 This function attribute prevents a function from being considered for
index 3612192..b5e8891 100644 (file)
@@ -4,7 +4,7 @@
 
 @c Common values used in the GCC manuals:
 
-@set version-GCC 3.4.3
+@set version-GCC 3.4.4
 
 @c DEVELOPMENT is set to indicate an in-development version,
 @c as compared to a release version.  When making a release
index face1fb..cfa3be5 100644 (file)
@@ -2116,19 +2116,19 @@ GNU Compiler Collection on your machine.
 @ifhtml
 @itemize
 @item
-@uref{#alpha*-*-*,,alpha*-*-*}
+@uref{#alpha-x-x,,alpha*-*-*}
 @item
-@uref{#alpha*-dec-osf*,,alpha*-dec-osf*}
+@uref{#alpha-dec-osf,,alpha*-dec-osf*}
 @item
-@uref{#alphaev5-cray-unicosmk*,,alphaev5-cray-unicosmk*}
+@uref{#alphaev5-cray-unicosmk,,alphaev5-cray-unicosmk*}
 @item
-@uref{#arc-*-elf,,arc-*-elf}
+@uref{#arc-x-elf,,arc-*-elf}
 @item
-@uref{#arm-*-elf,,arm-*-elf}
-@uref{#arm-*-coff,,arm-*-coff}
-@uref{#arm-*-aout,,arm-*-aout}
+@uref{#arm-x-elf,,arm-*-elf}
+@uref{#arm-x-coff,,arm-*-coff}
+@uref{#arm-x-aout,,arm-*-aout}
 @item
-@uref{#xscale-*-*,,xscale-*-*}
+@uref{#xscale-x-x,,xscale-*-*}
 @item
 @uref{#avr,,avr}
 @item
@@ -2138,41 +2138,39 @@ GNU Compiler Collection on your machine.
 @item
 @uref{#dsp16xx,,dsp16xx}
 @item
-@uref{#*-*-freebsd*,,*-*-freebsd*}
+@uref{#x-x-freebsd,,*-*-freebsd*}
 @item
 @uref{#h8300-hms,,h8300-hms}
 @item
-@uref{#hppa*-hp-hpux*,,hppa*-hp-hpux*}
+@uref{#hppa-hp-hpux,,hppa*-hp-hpux*}
 @item
-@uref{#hppa*-hp-hpux10,,hppa*-hp-hpux10}
+@uref{#hppa-hp-hpux10,,hppa*-hp-hpux10}
 @item
-@uref{#hppa*-hp-hpux11,,hppa*-hp-hpux11}
+@uref{#hppa-hp-hpux11,,hppa*-hp-hpux11}
 @item
-@uref{#i370-*-*,,i370-*-*}
+@uref{#i370-x-x,,i370-*-*}
 @item
-@uref{#*-*-linux-gnu,,*-*-linux-gnu}
+@uref{#x-x-linux-gnu,,*-*-linux-gnu}
 @item
-@uref{#ix86-*-linux*aout,,i?86-*-linux*aout}
+@uref{#ix86-x-linuxaout,,i?86-*-linux*aout}
 @item
-@uref{#ix86-*-linux*,,i?86-*-linux*}
+@uref{#ix86-x-linux,,i?86-*-linux*}
 @item
-@uref{#ix86-*-sco3.2v5*,,i?86-*-sco3.2v5*}
+@uref{#ix86-x-sco32v5,,i?86-*-sco3.2v5*}
 @item
-@uref{#ix86-*-udk,,i?86-*-udk}
+@uref{#ix86-x-udk,,i?86-*-udk}
 @item
-@uref{#ix86-*-esix,,i?86-*-esix}
+@uref{#ia64-x-linux,,ia64-*-linux}
 @item
-@uref{#ia64-*-linux,,ia64-*-linux}
+@uref{#ia64-x-hpux,,ia64-*-hpux*}
 @item
-@uref{#ia64-*-hpux*,,ia64-*-hpux*}
+@uref{#x-ibm-aix,,*-ibm-aix*}
 @item
-@uref{#*-ibm-aix*,,*-ibm-aix*}
+@uref{#ip2k-x-elf,,ip2k-*-elf}
 @item
-@uref{#ip2k-*-elf,,ip2k-*-elf}
+@uref{#iq2000-x-elf,,iq2000-*-elf}
 @item
-@uref{#iq2000-*-elf,,iq2000-*-elf}
-@item
-@uref{#m32r-*-elf,,m32r-*-elf}
+@uref{#m32r-x-elf,,m32r-*-elf}
 @item
 @uref{#m6811-elf,,m6811-elf}
 @item
@@ -2180,63 +2178,61 @@ GNU Compiler Collection on your machine.
 @item
 @uref{#m68k-hp-hpux,,m68k-hp-hpux}
 @item
-@uref{#mips-*-*,,mips-*-*}
+@uref{#mips-x-x,,mips-*-*}
 @item
 @uref{#mips-sgi-irix5,,mips-sgi-irix5}
 @item
 @uref{#mips-sgi-irix6,,mips-sgi-irix6}
 @item
-@uref{#powerpc*-*-*,,powerpc*-*-*, powerpc-*-sysv4}
-@item
-@uref{#powerpc-*-darwin*,,powerpc-*-darwin*}
+@uref{#powerpc-x-x,,powerpc*-*-*, powerpc-*-sysv4}
 @item
-@uref{#powerpc-*-elf,,powerpc-*-elf, powerpc-*-sysv4}
+@uref{#powerpc-x-darwin,,powerpc-*-darwin*}
 @item
-@uref{#powerpc-*-linux-gnu*,,powerpc-*-linux-gnu*}
+@uref{#powerpc-x-elf,,powerpc-*-elf, powerpc-*-sysv4}
 @item
-@uref{#powerpc-*-netbsd*,,powerpc-*-netbsd*}
+@uref{#powerpc-x-linux-gnu,,powerpc*-*-linux-gnu*}
 @item
-@uref{#powerpc-*-eabiaix,,powerpc-*-eabiaix}
+@uref{#powerpc-x-netbsd,,powerpc-*-netbsd*}
 @item
-@uref{#powerpc-*-eabisim,,powerpc-*-eabisim}
+@uref{#powerpc-x-eabisim,,powerpc-*-eabisim}
 @item
-@uref{#powerpc-*-eabi,,powerpc-*-eabi}
+@uref{#powerpc-x-eabi,,powerpc-*-eabi}
 @item
-@uref{#powerpcle-*-elf,,powerpcle-*-elf, powerpcle-*-sysv4}
+@uref{#powerpcle-x-elf,,powerpcle-*-elf, powerpcle-*-sysv4}
 @item
-@uref{#powerpcle-*-eabisim,,powerpcle-*-eabisim}
+@uref{#powerpcle-x-eabisim,,powerpcle-*-eabisim}
 @item
-@uref{#powerpcle-*-eabi,,powerpcle-*-eabi}
+@uref{#powerpcle-x-eabi,,powerpcle-*-eabi}
 @item
-@uref{#s390-*-linux*,,s390-*-linux*}
+@uref{#s390-x-linux,,s390-*-linux*}
 @item
-@uref{#s390x-*-linux*,,s390x-*-linux*}
+@uref{#s390x-x-linux,,s390x-*-linux*}
 @item
-@uref{#s390x-ibm-tpf*,,s390x-ibm-tpf*}
+@uref{#s390x-ibm-tpf,,s390x-ibm-tpf*}
 @item
-@uref{#*-*-solaris2*,,*-*-solaris2*}
+@uref{#x-x-solaris2,,*-*-solaris2*}
 @item
-@uref{#sparc-sun-solaris2*,,sparc-sun-solaris2*}
+@uref{#sparc-sun-solaris2,,sparc-sun-solaris2*}
 @item
-@uref{#sparc-sun-solaris2.7,,sparc-sun-solaris2.7}
+@uref{#sparc-sun-solaris27,,sparc-sun-solaris2.7}
 @item
-@uref{#sparc-*-linux*,,sparc-*-linux*}
+@uref{#sparc-x-linux,,sparc-*-linux*}
 @item
-@uref{#sparc64-*-solaris2*,,sparc64-*-solaris2*}
+@uref{#sparc64-x-solaris2,,sparc64-*-solaris2*}
 @item
-@uref{#sparcv9-*-solaris2*,,sparcv9-*-solaris2*}
+@uref{#sparcv9-x-solaris2,,sparcv9-*-solaris2*}
 @item
-@uref{#*-*-sysv*,,*-*-sysv*}
+@uref{#x-x-sysv,,*-*-sysv*}
 @item
 @uref{#vax-dec-ultrix,,vax-dec-ultrix}
 @item
-@uref{#*-*-vxworks*,,*-*-vxworks*}
+@uref{#x-x-vxworks,,*-*-vxworks*}
 @item
-@uref{#x86_64-*-*,,x86_64-*-*, amd64-*-*}
+@uref{#x86-64-x-x,,x86_64-*-*, amd64-*-*}
 @item
-@uref{#xtensa-*-elf,,xtensa-*-elf}
+@uref{#xtensa-x-elf,,xtensa-*-elf}
 @item
-@uref{#xtensa-*-linux*,,xtensa-*-linux*}
+@uref{#xtensa-x-linux,,xtensa-*-linux*}
 @item
 @uref{#windows,,Microsoft Windows}
 @item
@@ -2247,7 +2243,7 @@ GNU Compiler Collection on your machine.
 
 @itemize
 @item
-@uref{#elf_targets,,all ELF targets} (SVR4, Solaris 2, etc.)
+@uref{#elf,,all ELF targets} (SVR4, Solaris 2, etc.)
 @end itemize
 @end ifhtml
 
@@ -2256,7 +2252,7 @@ GNU Compiler Collection on your machine.
 <!-- -------- host/target specific issues start here ---------------- -->
 <hr />
 @end html
-@heading @anchor{alpha*-*-*}alpha*-*-*
+@heading @anchor{alpha-x-x}alpha*-*-*
 
 This section contains general configuration information for all
 alpha-based platforms using ELF (in particular, ignore this section for
@@ -2271,7 +2267,7 @@ shared libraries.
 @html
 <hr />
 @end html
-@heading @anchor{alpha*-dec-osf*}alpha*-dec-osf*
+@heading @anchor{alpha-dec-osf}alpha*-dec-osf*
 Systems using processors that implement the DEC Alpha architecture and
 are running the DEC/Compaq Unix (DEC OSF/1, Digital UNIX, or Compaq
 Tru64 UNIX) operating system, for example the DEC Alpha AXP systems.
@@ -2352,7 +2348,7 @@ provide a fix shortly.
 @html
 <hr />
 @end html
-@heading @anchor{alphaev5-cray-unicosmk*}alphaev5-cray-unicosmk*
+@heading @anchor{alphaev5-cray-unicosmk}alphaev5-cray-unicosmk*
 Cray T3E systems running Unicos/Mk.
 
 This port is incomplete and has many known bugs.  We hope to improve the
@@ -2379,15 +2375,15 @@ failure.
 @html
 <hr />
 @end html
-@heading @anchor{arc-*-elf}arc-*-elf
+@heading @anchor{arc-x-elf}arc-*-elf
 Argonaut ARC processor.
 This configuration is intended for embedded systems.
 
 @html
 <hr />
 @end html
-@heading @anchor{arm-*-elf}arm-*-elf
-@heading @anchor{xscale-*-*}xscale-*-*
+@heading @anchor{arm-x-elf}arm-*-elf
+@heading @anchor{xscale-x-x}xscale-*-*
 ARM-family processors.  Subtargets that use the ELF object format
 require GNU binutils 2.13 or newer.  Such subtargets include:
 @code{arm-*-freebsd}, @code{arm-*-netbsdelf}, @code{arm-*-*linux},
@@ -2396,7 +2392,7 @@ require GNU binutils 2.13 or newer.  Such subtargets include:
 @html
 <hr />
 @end html
-@heading @anchor{arm-*-coff}arm-*-coff
+@heading @anchor{arm-x-coff}arm-*-coff
 ARM-family processors.  Note that there are two different varieties
 of PE format subtarget supported: @code{arm-wince-pe} and
 @code{arm-pe} as well as a standard COFF target @code{arm-*-coff}.
@@ -2404,7 +2400,7 @@ of PE format subtarget supported: @code{arm-wince-pe} and
 @html
 <hr />
 @end html
-@heading @anchor{arm-*-aout}arm-*-aout
+@heading @anchor{arm-x-aout}arm-*-aout
 ARM-family processors.  These targets support the AOUT file format:
 @code{arm-*-aout}, @code{arm-*-netbsd}.
 
@@ -2536,7 +2532,7 @@ A port to the AT&T DSP1610 family of processors.
 @html
 <hr />
 @end html
-@heading @anchor{*-*-freebsd*}*-*-freebsd*
+@heading @anchor{x-x-freebsd}*-*-freebsd*
 
 The version of binutils installed in @file{/usr/bin} probably works with
 this release of GCC.  However, on FreeBSD 4, bootstrapping against the
@@ -2597,7 +2593,7 @@ longer a multiple of 2 bytes.
 @html
 <hr />
 @end html
-@heading @anchor{hppa*-hp-hpux*}hppa*-hp-hpux*
+@heading @anchor{hppa-hp-hpux}hppa*-hp-hpux*
 Support for HP-UX version 9 and older was discontinued in GCC 3.4.
 
 We @emph{highly} recommend using gas/binutils 2.8 or newer on all hppa
@@ -2631,7 +2627,7 @@ More specific information to @samp{hppa*-hp-hpux*} targets follows.
 @html
 <hr />
 @end html
-@heading @anchor{hppa*-hp-hpux10}hppa*-hp-hpux10
+@heading @anchor{hppa-hp-hpux10}hppa*-hp-hpux10
 
 For hpux10.20, we @emph{highly} recommend you pick up the latest sed patch
 @code{PHCO_19798} from HP@.  HP has two sites which provide patches free of
@@ -2661,7 +2657,7 @@ the failure from @samp{make bootstrap}.
 @html
 <hr />
 @end html
-@heading @anchor{hppa*-hp-hpux11}hppa*-hp-hpux11
+@heading @anchor{hppa-hp-hpux11}hppa*-hp-hpux11
 
 GCC 3.0 and up support HP-UX 11.  GCC 2.95.x is not supported and cannot
 be used to compile GCC 3.0 and up.
@@ -2793,14 +2789,14 @@ This port still is undergoing significant development.
 @html
 <hr />
 @end html
-@heading @anchor{i370-*-*}i370-*-*
+@heading @anchor{i370-x-x}i370-*-*
 This port is very preliminary and has many known bugs.  We hope to
 have a higher-quality port for this machine soon.
 
 @html
 <hr />
 @end html
-@heading @anchor{*-*-linux-gnu}*-*-linux-gnu
+@heading @anchor{x-x-linux-gnu}*-*-linux-gnu
 
 Versions of libstdc++-v3 starting with 3.2.1 require bugfixes present
 in glibc 2.2.5 and later.  More information is available in the
@@ -2809,14 +2805,14 @@ libstdc++-v3 documentation.
 @html
 <hr />
 @end html
-@heading @anchor{ix86-*-linux*aout}i?86-*-linux*aout
+@heading @anchor{ix86-x-linuxaout}i?86-*-linux*aout
 Use this configuration to generate @file{a.out} binaries on Linux-based
 GNU systems.  This configuration is being superseded.
 
 @html
 <hr />
 @end html
-@heading @anchor{ix86-*-linux*}i?86-*-linux*
+@heading @anchor{ix86-x-linux}i?86-*-linux*
 
 As of GCC 3.3, binutils 2.13.1 or later is required for this platform.
 See @uref{http://gcc.gnu.org/PR10877,,bug 10877} for more information.
@@ -2840,7 +2836,7 @@ This will be fixed in future releases of GCC.
 @html
 <hr />
 @end html
-@heading @anchor{ix86-*-sco3.2v5*}i?86-*-sco3.2v5*
+@heading @anchor{ix86-x-sco32v5}i?86-*-sco3.2v5*
 Use this for the SCO OpenServer Release 5 family of operating systems.
 
 Unlike earlier versions of GCC, the ability to generate COFF with this
@@ -2884,7 +2880,7 @@ GCC, version 2.95.3.  It is useful for bootstrapping this version.
 @html
 <hr />
 @end html
-@heading @anchor{ix86-*-udk}i?86-*-udk
+@heading @anchor{ix86-x-udk}i?86-*-udk
 
 This target emulates the SCO Universal Development Kit and requires that
 package be installed.  (If it is installed, you will have a
@@ -2920,7 +2916,7 @@ have installed.
 @html
 <hr />
 @end html
-@heading @anchor{ia64-*-linux}ia64-*-linux
+@heading @anchor{ia64-x-linux}ia64-*-linux
 IA-64 processor (also known as IPF, or Itanium Processor Family)
 running GNU/Linux.
 
@@ -2940,7 +2936,7 @@ more major ABI changes are expected.
 @html
 <hr />
 @end html
-@heading @anchor{ia64-*-hpux*}ia64-*-hpux*
+@heading @anchor{ia64-x-hpux}ia64-*-hpux*
 Building GCC on this target requires the GNU Assembler. The bundled HP
 assembler will not work. To prevent GCC from using the wrong assembler,
 the option @option{--with-gnu-as} may be necessary.
@@ -2955,7 +2951,7 @@ removed and the system libunwind library will always be used.
 <hr />
 <!-- rs6000-ibm-aix*, powerpc-ibm-aix* -->
 @end html
-@heading @anchor{*-ibm-aix*}*-ibm-aix*
+@heading @anchor{x-ibm-aix}*-ibm-aix*
 Support for AIX version 3 and older was discontinued in GCC 3.4.
 
 AIX Make frequently has problems with GCC makefiles.  GNU Make 3.79.1 or
@@ -3080,7 +3076,7 @@ switch and using the configure option @option{--with-cpu-@var{cpu_type}}.
 @html
 <hr />
 @end html
-@heading @anchor{ip2k-*-elf}ip2k-*-elf
+@heading @anchor{ip2k-x-elf}ip2k-*-elf
 Ubicom IP2022 micro controller.
 This configuration is intended for embedded systems.
 There are no standard Unix configurations.
@@ -3090,14 +3086,14 @@ Use @samp{configure --target=ip2k-elf --enable-languages=c} to configure GCC@.
 @html
 <hr />
 @end html
-@heading @anchor{iq2000-*-elf}iq2000-*-elf
+@heading @anchor{iq2000-x-elf}iq2000-*-elf
 Vitesse IQ2000 processors.  These are used in embedded
 applications.  There are no standard Unix configurations.
 
 @html
 <hr />
 @end html
-@heading @anchor{m32r-*-elf}m32r-*-elf
+@heading @anchor{m32r-x-elf}m32r-*-elf
 Renesas M32R processor.
 This configuration is intended for embedded systems.
 
@@ -3171,7 +3167,7 @@ to look like:
 @html
 <hr />
 @end html
-@heading @anchor{mips-*-*}mips-*-*
+@heading @anchor{mips-x-x}mips-*-*
 If on a MIPS system you get an error message saying ``does not have gp
 sections for all it's [sic] sectons [sic]'', don't worry about it.  This
 happens whenever you use GAS with the MIPS linker, but there is not
@@ -3308,7 +3304,7 @@ information about using GCC on IRIX platforms.
 @html
 <hr />
 @end html
-@heading @anchor{powerpc*-*-*}powerpc-*-*
+@heading @anchor{powerpc-x-x}powerpc-*-*
 
 You can specify a default version for the @option{-mcpu=@var{cpu_type}}
 switch by using the configure option @option{--with-cpu-@var{cpu_type}}.
@@ -3316,13 +3312,13 @@ switch by using the configure option @option{--with-cpu-@var{cpu_type}}.
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-darwin*}powerpc-*-darwin*
+@heading @anchor{powerpc-x-darwin}powerpc-*-darwin*
 PowerPC running Darwin (Mac OS X kernel).
 
 Pre-installed versions of Mac OS X may not include any developer tools,
 meaning that you will not be able to build GCC from source.  Tool
 binaries are available at
-@uref{http://developer.apple.com/tools/compilers.html} (free
+@uref{http://developer.apple.com/darwin/projects/compiler/} (free
 registration required).
 
 The default stack limit of 512K is too small, which may cause compiles
@@ -3340,22 +3336,22 @@ are generally specific to Mac programming.
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-elf}powerpc-*-elf, powerpc-*-sysv4
+@heading @anchor{powerpc-x-elf}powerpc-*-elf, powerpc-*-sysv4
 PowerPC system in big endian mode, running System V.4.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-linux-gnu*}powerpc-*-linux-gnu*
+@heading @anchor{powerpc-x-linux-gnu}powerpc*-*-linux-gnu*
 
 You will need
-@uref{ftp://ftp.kernel.org/pub/linux/devel/binutils,,binutils 2.13.90.0.10}
+@uref{ftp://ftp.kernel.org/pub/linux/devel/binutils,,binutils 2.15}
 or newer for a working GCC@.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-netbsd*}powerpc-*-netbsd*
+@heading @anchor{powerpc-x-netbsd}powerpc-*-netbsd*
 PowerPC system in big endian mode running NetBSD@.  To build the
 documentation you will need Texinfo version 4.2 (NetBSD 1.5.1 included
 Texinfo version 3.12).
@@ -3363,51 +3359,51 @@ Texinfo version 3.12).
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-eabisim}powerpc-*-eabisim
+@heading @anchor{powerpc-x-eabisim}powerpc-*-eabisim
 Embedded PowerPC system in big endian mode for use in running under the
 PSIM simulator.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpc-*-eabi}powerpc-*-eabi
+@heading @anchor{powerpc-x-eabi}powerpc-*-eabi
 Embedded PowerPC system in big endian mode.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpcle-*-elf}powerpcle-*-elf, powerpcle-*-sysv4
+@heading @anchor{powerpcle-x-elf}powerpcle-*-elf, powerpcle-*-sysv4
 PowerPC system in little endian mode, running System V.4.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpcle-*-eabisim}powerpcle-*-eabisim
+@heading @anchor{powerpcle-x-eabisim}powerpcle-*-eabisim
 Embedded PowerPC system in little endian mode for use in running under
 the PSIM simulator.
 
 @html
 <hr />
 @end html
-@heading @anchor{powerpcle-*-eabi}powerpcle-*-eabi
+@heading @anchor{powerpcle-x-eabi}powerpcle-*-eabi
 Embedded PowerPC system in little endian mode.
 
 @html
 <hr />
 @end html
-@heading @anchor{s390-*-linux*}s390-*-linux*
+@heading @anchor{s390-x-linux}s390-*-linux*
 S/390 system running GNU/Linux for S/390@.
 
 @html
 <hr />
 @end html
-@heading @anchor{s390x-*-linux*}s390x-*-linux*
+@heading @anchor{s390x-x-linux}s390x-*-linux*
 zSeries system (64-bit) running GNU/Linux for zSeries@.
 
 @html
 <hr />
 @end html
-@heading @anchor{s390x-ibm-tpf*}s390x-ibm-tpf*
+@heading @anchor{s390x-ibm-tpf}s390x-ibm-tpf*
 zSeries system (64-bit) running TPF.  This platform is
 supported as cross-compilation target only.
 
@@ -3418,7 +3414,7 @@ supported as cross-compilation target only.
 @c with 2.0 until 2.6, 7, 8, etc.  Solaris 1 was a marketing name for
 @c SunOS 4 releases which we don't use to avoid confusion.  Solaris
 @c alone is too unspecific and must be avoided.
-@heading @anchor{*-*-solaris2*}*-*-solaris2*
+@heading @anchor{x-x-solaris2}*-*-solaris2*
 
 Sun does not ship a C compiler with Solaris 2.  To bootstrap and install
 GCC you first have to install a pre-built compiler, see the
@@ -3502,7 +3498,7 @@ SPARC, 117172-11 or newer for Intel) that address this problem.
 @html
 <hr />
 @end html
-@heading @anchor{sparc-sun-solaris2*}sparc-sun-solaris2*
+@heading @anchor{sparc-sun-solaris2}sparc-sun-solaris2*
 
 When GCC is configured to use binutils 2.11.2 or later the binaries
 produced are smaller than the ones produced using Sun's native tools;
@@ -3565,7 +3561,7 @@ plain @option{-g}.
 @html
 <hr />
 @end html
-@heading @anchor{sparc-sun-solaris2.7}sparc-sun-solaris2.7
+@heading @anchor{sparc-sun-solaris27}sparc-sun-solaris2.7
 
 Sun patch 107058-01 (1999-01-13) for Solaris 7/SPARC triggers a bug in
 the dynamic linker.  This problem (Sun bug 4210064) affects GCC 2.8
@@ -3616,7 +3612,7 @@ This bug has been fixed in the final 5.0 version of the assembler.
 @html
 <hr />
 @end html
-@heading @anchor{sparc-*-linux*}sparc-*-linux*
+@heading @anchor{sparc-x-linux}sparc-*-linux*
 
 GCC versions 3.0 and higher require binutils 2.11.2 and glibc 2.2.4
 or newer on this platform.  All earlier binutils and glibc
@@ -3626,7 +3622,7 @@ releases mishandled unaligned relocations on @code{sparc-*-*} targets.
 @html
 <hr />
 @end html
-@heading @anchor{sparc64-*-solaris2*}sparc64-*-solaris2*
+@heading @anchor{sparc64-x-solaris2}sparc64-*-solaris2*
 
 The following compiler flags must be specified in the configure
 step in order to bootstrap this target with the Sun compiler:
@@ -3641,14 +3637,14 @@ specifies the SPARC-V9 architecture to the Sun linker and assembler.
 @html
 <hr />
 @end html
-@heading @anchor{sparcv9-*-solaris2*}sparcv9-*-solaris2*
+@heading @anchor{sparcv9-x-solaris2}sparcv9-*-solaris2*
 
 This is a synonym for sparc64-*-solaris2*.
 
 @html
 <hr />
 @end html
-@heading @anchor{#*-*-sysv*}*-*-sysv*
+@heading @anchor{x-x-sysv}*-*-sysv*
 On System V release 3, you may get this error message
 while linking:
 
@@ -3689,7 +3685,7 @@ in some cases (for example, when @code{alloca} is used).
 @html
 <hr />
 @end html
-@heading @anchor{*-*-vxworks*}*-*-vxworks*
+@heading @anchor{x-x-vxworks}*-*-vxworks*
 Support for VxWorks is in flux.  At present GCC supports @emph{only} the
 very recent VxWorks 5.5 (aka Tornado 2.2) release, and only on PowerPC.
 We welcome patches for other architectures supported by VxWorks 5.5.
@@ -3724,7 +3720,7 @@ VxWorks will incorporate this module.)
 @html
 <hr />
 @end html
-@heading @anchor{x86_64-*-*}x86_64-*-*, amd64-*-*
+@heading @anchor{x86-64-x-x}x86_64-*-*, amd64-*-*
 
 GCC supports the x86-64 architecture implemented by the AMD64 processor
 (amd64-*-* is an alias for x86_64-*-*) on GNU/Linux, FreeBSD and NetBSD.
@@ -3734,7 +3730,7 @@ both 64-bit x86-64 and 32-bit x86 code (via the @option{-m32} switch).
 @html
 <hr />
 @end html
-@heading @anchor{xtensa-*-elf}xtensa-*-elf
+@heading @anchor{xtensa-x-elf}xtensa-*-elf
 
 This target is intended for embedded Xtensa systems using the
 @samp{newlib} C library.  It uses ELF but does not support shared
@@ -3752,7 +3748,7 @@ which you can use to replace the default header file.
 @html
 <hr />
 @end html
-@heading @anchor{xtensa-*-linux*}xtensa-*-linux*
+@heading @anchor{xtensa-x-linux}xtensa-*-linux*
 
 This target is for Xtensa systems running GNU/Linux.  It supports ELF
 shared objects and the GNU C library (glibc).  It also generates
@@ -3837,7 +3833,7 @@ current GCC) is to be found in the GCC texinfo manual.
 @html
 <hr />
 @end html
-@heading @anchor{elf_targets}all ELF targets (SVR4, Solaris 2, etc.)
+@heading @anchor{elf}all ELF targets (SVR4, Solaris 2, etc.)
 
 C++ support is significantly better on ELF targets if you use the
 @uref{./configure.html#with-gnu-ld,,GNU linker}; duplicate copies of
index 920d329..3475408 100644 (file)
@@ -1,12 +1,12 @@
 @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-@c 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+@c 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
 
 @ignore
 @c man begin COPYRIGHT
 Copyright @copyright{} 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.2 or
@@ -188,7 +188,7 @@ in the following sections.
 -Weffc++  -Wno-deprecated @gol
 -Wno-non-template-friend  -Wold-style-cast @gol
 -Woverloaded-virtual  -Wno-pmf-conversions @gol
--Wsign-promo  -Wsynth}
+-Wsign-promo}
 
 @item Objective-C Language Options
 @xref{Objective-C Dialect Options,,Options Controlling Objective-C Dialect}.
@@ -421,7 +421,7 @@ in the following sections.
 -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
 -mnew-mnemonics  -mold-mnemonics @gol
 -mfull-toc   -mminimal-toc  -mno-fp-in-toc  -mno-sum-in-toc @gol
--m64  -m32  -mxl-call  -mno-xl-call  -mpe @gol
+-m64  -m32  -mxl-compat  -mno-xl-compat  -mpe @gol
 -malign-power  -malign-natural @gol
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
@@ -605,8 +605,11 @@ in the following sections.
 -mconstant-gp  -mauto-pic  -minline-float-divide-min-latency @gol
 -minline-float-divide-max-throughput @gol
 -minline-int-divide-min-latency @gol
--minline-int-divide-max-throughput  -mno-dwarf2-asm @gol
--mfixed-range=@var{register-range}}
+-minline-int-divide-max-throughput  @gol
+-minline-sqrt-min-latency -minline-sqrt-max-throughput @gol
+-mno-dwarf2-asm -mearly-stop-bits @gol
+-mfixed-range=@var{register-range} -mtls-size=@var{tls-size} @gol
+-mtune=@var{cpu-type} -mt -pthread -milp32 -mlp64}
 
 @emph{D30V Options}
 @gccoptlist{-mextmem  -mextmemory  -monchip  -mno-asm-optimize @gol
@@ -1701,13 +1704,6 @@ enumerated type to a signed type, over a conversion to an unsigned type of
 the same size.  Previous versions of G++ would try to preserve
 unsignedness, but the standard mandates the current behavior.
 
-@item -Wsynth @r{(C++ only)}
-@opindex Wsynth
-@cindex warning for synthesized methods
-@cindex synthesized methods, warning
-Warn when G++'s synthesis behavior does not match that of cfront.  For
-instance:
-
 @smallexample
 struct A @{
   operator int ();
@@ -4829,6 +4825,12 @@ order to make tracer effective.
 
 Maximum number of basic blocks on path that cse considers.
 
+@item max-last-value-rtl
+
+The maximum size measured as number of RTLs that can be recorded in an
+expression in combiner for a pseudo register as last known value of that
+register.  The default is 10000.
+
 @item ggc-min-expand
 
 GCC uses a garbage collector to manage its own memory allocation.  This
@@ -6161,7 +6163,7 @@ These @samp{-m} options are supported on the SPARC:
 @opindex mapp-regs
 Specify @option{-mapp-regs} to generate output using the global registers
 2 through 4, which the SPARC SVR4 ABI reserves for applications.  This
-is the default.
+is the default, except on Solaris.
 
 To be fully SVR4 ABI compliant at the cost of some performance loss,
 specify @option{-mno-app-regs}.  You should compile libraries and system
@@ -6384,7 +6386,7 @@ on SPARC-V9 processors in 64-bit environments:
 @item -mlittle-endian
 @opindex mlittle-endian
 Generate code for a processor running in little-endian mode. It is only
-available for a few configurations and most notably not on Solaris.
+available for a few configurations and most notably not on Solaris and Linux.
 
 @item -m32
 @itemx -m64
@@ -7050,7 +7052,7 @@ Supported values for @var{cpu_type} are @samp{401}, @samp{403},
 @samp{601}, @samp{602}, @samp{603}, @samp{603e}, @samp{604},
 @samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400},
 @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
-@samp{860}, @samp{970}, @samp{common}, @samp{ec603e}, @samp{G3},
+@samp{860}, @samp{970}, @samp{8540}, @samp{common}, @samp{ec603e}, @samp{G3},
 @samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3},
 @samp{power4}, @samp{power5}, @samp{powerpc}, @samp{powerpc64},
 @samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64a}.
@@ -7178,13 +7180,17 @@ Specifying @option{-maix64} implies @option{-mpowerpc64} and
 @option{-mpowerpc}, while @option{-maix32} disables the 64-bit ABI and
 implies @option{-mno-powerpc64}.  GCC defaults to @option{-maix32}.
 
-@item -mxl-call
-@itemx -mno-xl-call
-@opindex mxl-call
-@opindex mno-xl-call
-On AIX, pass floating-point arguments to prototyped functions beyond the
-register save area (RSA) on the stack in addition to argument FPRs.  The
-AIX calling convention was extended but not initially documented to
+@item -mxl-compat
+@itemx -mno-xl-compat
+@opindex mxl-compat
+@opindex mno-xl-compat
+Produce code that conforms more closely to IBM XLC semantics when using
+AIX-compatible ABI.  Pass floating-point arguments to prototyped
+functions beyond the register save area (RSA) on the stack in addition
+to argument FPRs.  Do not assume that most significant double in 128
+bit long double value is properly rounded when comparing values.
+
+The AIX calling convention was extended but not initially documented to
 handle an obscure K&R C case of calling a function that takes the
 address of its arguments with fewer arguments than declared.  AIX XL
 compilers access floating point arguments which do not fit in the
@@ -10031,6 +10037,16 @@ using the minimum latency algorithm.
 Generate code for inline divides of integer values
 using the maximum throughput algorithm.
 
+@item -minline-sqrt-min-latency
+@opindex minline-sqrt-min-latency
+Generate code for inline square roots
+using the minimum latency algorithm.
+
+@item -minline-sqrt-max-throughput
+@opindex minline-sqrt-max-throughput
+Generate code for inline square roots
+using the maximum throughput algorithm.
+
 @item -mno-dwarf2-asm
 @itemx -mdwarf2-asm
 @opindex mno-dwarf2-asm
@@ -10038,6 +10054,14 @@ using the maximum throughput algorithm.
 Don't (or do) generate assembler code for the DWARF2 line number debugging
 info.  This may be useful when not using the GNU assembler.
 
+@item -mearly-stop-bits
+@itemx -mno-early-stop-bits
+@opindex mearly-stop-bits
+@opindex mno-early-stop-bits
+Allow stop bits to be placed earlier than immediately preceding the
+instruction that triggered the stop bit.  This can improve instruction
+scheduling, but does not always do so.
+
 @item -mfixed-range=@var{register-range}
 @opindex mfixed-range
 Generate code treating the given register range as fixed registers.
@@ -10046,13 +10070,34 @@ useful when compiling kernel code.  A register range is specified as
 two registers separated by a dash.  Multiple register ranges can be
 specified separated by a comma.
 
-@item -mearly-stop-bits
-@itemx -mno-early-stop-bits
-@opindex mearly-stop-bits
-@opindex mno-early-stop-bits
-Allow stop bits to be placed earlier than immediately preceding the
-instruction that triggered the stop bit.  This can improve instruction
-scheduling, but does not always do so.
+@item -mtls-size=@var{tls-size}
+@opindex mtls-size
+Specify bit size of immediate TLS offsets.  Valid values are 14, 22, and
+64.
+
+@item -mtune-arch=@var{cpu-type}
+@opindex mtune-arch
+Tune the instruction scheduling for a particular CPU, Valid values are
+itanium, itanium1, merced, itanium2, and mckinley.
+
+@item -mt
+@itemx -pthread
+@opindex mt
+@opindex pthread
+Add support for multithreading using the POSIX threads library.  This
+option sets flags for both the preprocessor and linker.  It does
+not affect the thread safety of object code produced by the compiler or
+that of libraries supplied with it.  These are HP-UX specific flags.
+
+@item -milp32
+@itemx -mlp64
+@opindex milp32
+@opindex mlp64
+Generate code for a 32-bit or 64-bit environment.
+The 32-bit environment sets int, long and pointer to 32 bits.
+The 64-bit environment sets int to 32 bits and long and pointer
+to 64 bits.  These are HP-UX specific flags.
+
 @end table
 
 @node D30V Options
index 11e2915..b73f325 100644 (file)
@@ -1257,7 +1257,9 @@ instruction is defined:
 @end smallexample
 @end ifset
 GCC can only handle one commutative pair in an asm; if you use more,
-the compiler may fail.
+the compiler may fail.  Note that you need not use the modifier if
+the two alternatives are strictly identical; this would only waste
+time in the reload pass.
 
 @cindex @samp{#} in constraint
 @item #
index 16d66f2..73b8ec2 100644 (file)
@@ -6953,6 +6953,15 @@ If @code{SET_ASM_OP} is defined, a default definition is provided which is
 correct for most systems.
 @end defmac
 
+@defmac TARGET_DEFERRED_OUTPUT_DEFS (@var{decl_of_name}, @var{decl_of_value})
+A C statement that evaluates to true if the assembler code which defines
+(equates) the symbol whose tree node is @var{decl_of_name} to have the value
+of the tree node @var{decl_of_value} should be emitted near the end of the
+current compilation unit.  The default is to not defer output of defines.
+This macro affects defines output by @samp{ASM_OUTPUT_DEF} and
+@samp{ASM_OUTPUT_DEF_FROM_DECLS}.
+@end defmac
+
 @defmac ASM_OUTPUT_WEAK_ALIAS (@var{stream}, @var{name}, @var{value})
 A C statement to output to the stdio stream @var{stream} assembler code
 which defines (equates) the weak symbol @var{name} to have the value
index 6b9569b..b232576 100644 (file)
@@ -1,6 +1,6 @@
 /* Convert tree expression to rtl instructions, for GNU compiler.
    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -33,7 +33,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "expr.h"
 #include "optabs.h"
 #include "langhooks.h"
+#include "ggc.h"
 
+static bool prefer_and_bit_test (enum machine_mode, int);
 static void do_jump_by_parts_greater (tree, int, rtx, rtx);
 static void do_jump_by_parts_equality (tree, rtx, rtx);
 static void do_compare_and_jump        (tree, enum rtx_code, enum rtx_code, rtx,
@@ -48,6 +50,15 @@ init_pending_stack_adjust (void)
   pending_stack_adjust = 0;
 }
 
+/* Discard any pending stack adjustment.  This avoid relying on the
+   RTL optimizers to remove useless adjustments when we know the
+   stack pointer value is dead.  */
+void discard_pending_stack_adjust (void)
+{
+  stack_pointer_delta -= pending_stack_adjust;
+  pending_stack_adjust = 0;
+}
+
 /* When exiting from function, if safe, clear out any pending stack adjust
    so the adjustment won't get done.
 
@@ -62,10 +73,7 @@ clear_pending_stack_adjust (void)
       && EXIT_IGNORE_STACK
       && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
       && ! flag_inline_functions)
-    {
-      stack_pointer_delta -= pending_stack_adjust,
-      pending_stack_adjust = 0;
-    }
+    discard_pending_stack_adjust ();
 }
 
 /* Pop any previously-pushed arguments that have not been popped yet.  */
@@ -101,6 +109,45 @@ jumpif (tree exp, rtx label)
   do_jump (exp, NULL_RTX, label);
 }
 
+/* Used internally by prefer_and_bit_test.  */
+
+static GTY(()) rtx and_reg;
+static GTY(()) rtx and_test;
+static GTY(()) rtx shift_test;
+
+/* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1"
+   where X is an arbitrary register of mode MODE.  Return true if the former
+   is preferred.  */
+
+static bool
+prefer_and_bit_test (enum machine_mode mode, int bitnum)
+{
+  if (and_test == 0)
+    {
+      /* Set up rtxes for the two variations.  Use NULL as a placeholder
+        for the BITNUM-based constants.  */
+      and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER);
+      and_test = gen_rtx_AND (mode, and_reg, NULL);
+      shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL),
+                               const1_rtx);
+    }
+  else
+    {
+      /* Change the mode of the previously-created rtxes.  */
+      PUT_MODE (and_reg, mode);
+      PUT_MODE (and_test, mode);
+      PUT_MODE (shift_test, mode);
+      PUT_MODE (XEXP (shift_test, 0), mode);
+    }
+
+  /* Fill in the integers.  */
+  XEXP (and_test, 1) = GEN_INT ((unsigned HOST_WIDE_INT) 1 << bitnum);
+  XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
+
+  return (rtx_cost (and_test, IF_THEN_ELSE)
+         <= rtx_cost (shift_test, IF_THEN_ELSE));
+}
+
 /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
    the result is zero, or IF_TRUE_LABEL if the result is one.
    Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
@@ -206,6 +253,59 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label)
       break;
 
     case BIT_AND_EXPR:
+      /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1.
+        See if the former is preferred for jump tests and restore it
+        if so.  */
+      if (integer_onep (TREE_OPERAND (exp, 1)))
+       {
+         tree exp0 = TREE_OPERAND (exp, 0);
+         rtx set_label, clr_label;
+
+         /* Strip narrowing integral type conversions.  */
+         while ((TREE_CODE (exp0) == NOP_EXPR
+                 || TREE_CODE (exp0) == CONVERT_EXPR
+                 || TREE_CODE (exp0) == NON_LVALUE_EXPR)
+                && TREE_OPERAND (exp0, 0) != error_mark_node
+                && TYPE_PRECISION (TREE_TYPE (exp0))
+                   <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp0, 0))))
+           exp0 = TREE_OPERAND (exp0, 0);
+
+         /* "exp0 ^ 1" inverts the sense of the single bit test.  */
+         if (TREE_CODE (exp0) == BIT_XOR_EXPR
+             && integer_onep (TREE_OPERAND (exp0, 1)))
+           {
+             exp0 = TREE_OPERAND (exp0, 0);
+             clr_label = if_true_label;
+             set_label = if_false_label;
+           }
+         else
+           {
+             clr_label = if_false_label;
+             set_label = if_true_label;
+           }
+
+         if (TREE_CODE (exp0) == RSHIFT_EXPR)
+           {
+             tree arg = TREE_OPERAND (exp0, 0);
+             tree shift = TREE_OPERAND (exp0, 1);
+             tree argtype = TREE_TYPE (arg);
+             if (TREE_CODE (shift) == INTEGER_CST
+                 && compare_tree_int (shift, 0) >= 0
+                 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0
+                 && prefer_and_bit_test (TYPE_MODE (argtype),
+                                         TREE_INT_CST_LOW (shift)))
+               {
+                 HOST_WIDE_INT mask = (HOST_WIDE_INT) 1
+                                      << TREE_INT_CST_LOW (shift);
+                 tree t = build_int_2 (mask, 0);
+                 TREE_TYPE (t) = argtype;
+                 do_jump (build (BIT_AND_EXPR, argtype, arg, t),
+                          clr_label, set_label);
+                 break;
+               }
+           }
+       }
+
       /* If we are AND'ing with a small constant, do this comparison in the
          smallest type that fits.  If the machine doesn't have comparisons
          that small, it will be converted back to the wider comparison.
@@ -997,3 +1097,5 @@ do_compare_and_jump (tree exp, enum rtx_code signed_code,
                             ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
                            if_false_label, if_true_label);
 }
+
+#include "gt-dojump.h"
index 651d229..d59cc1d 100644 (file)
@@ -1,6 +1,6 @@
 /* Output Dwarf2 format symbol table information from GCC.
    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Gary Funck (gary@intrepid.com).
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
    Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -3649,6 +3649,7 @@ static bool is_java (void);
 static bool is_fortran (void);
 static bool is_ada (void);
 static void remove_AT (dw_die_ref, enum dwarf_attribute);
+static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
 static inline void free_die (dw_die_ref);
 static void remove_children (dw_die_ref);
 static void add_child_die (dw_die_ref, dw_die_ref);
@@ -5055,6 +5056,34 @@ remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
     }
 }
 
+/* Remove child die whose die_tag is specified tag.  */
+
+static void
+remove_child_TAG (dw_die_ref die, enum dwarf_tag tag)
+{
+  dw_die_ref current, prev, next;
+  current = die->die_child;
+  prev = NULL;
+  while (current != NULL)
+    {
+      if (current->die_tag == tag)
+       {
+         next = current->die_sib;
+         if (prev == NULL)
+           die->die_child = next;
+         else
+           prev->die_sib = next;
+         free_die (current);
+         current = next;
+       }
+      else
+       {
+         prev = current;
+         current = current->die_sib;
+       }
+    }
+}
+
 /* Free up the memory used by DIE.  */
 
 static inline void
@@ -10235,7 +10264,8 @@ scope_die_for (tree t, dw_die_ref context_die)
   if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE)
     containing_scope = NULL_TREE;
 
-  if (containing_scope == NULL_TREE)
+  if (containing_scope == NULL_TREE 
+      || TREE_CODE (containing_scope) == TRANSLATION_UNIT_DECL)
     scope_die = comp_unit_die;
   else if (TYPE_P (containing_scope))
     {
@@ -10872,9 +10902,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
        {
          subr_die = old_die;
 
-         /* Clear out the declaration attribute and the parm types.  */
+         /* Clear out the declaration attribute and the formal parameters.  */
          remove_AT (subr_die, DW_AT_declaration);
-         remove_children (subr_die);
+         remove_child_TAG (subr_die, DW_TAG_formal_parameter);
        }
       else
        {
index f6e44f9..9df2d6c 100644 (file)
@@ -2910,11 +2910,19 @@ get_first_nonnote_insn (void)
 {
   rtx insn = first_insn;
 
-  while (insn)
+  if (insn)
     {
-      insn = next_insn (insn);
-      if (insn == 0 || GET_CODE (insn) != NOTE)
-       break;
+      if (NOTE_P (insn))
+       for (insn = next_insn (insn);
+            insn && NOTE_P (insn);
+            insn = next_insn (insn))
+         continue;
+      else
+       {
+         if (GET_CODE (insn) == INSN
+             && GET_CODE (PATTERN (insn)) == SEQUENCE)
+           insn = XVECEXP (PATTERN (insn), 0, 0);
+       }
     }
 
   return insn;
@@ -2928,11 +2936,20 @@ get_last_nonnote_insn (void)
 {
   rtx insn = last_insn;
 
-  while (insn)
+  if (insn)
     {
-      insn = previous_insn (insn);
-      if (insn == 0 || GET_CODE (insn) != NOTE)
-       break;
+      if (NOTE_P (insn))
+       for (insn = previous_insn (insn);
+            insn && NOTE_P (insn);
+            insn = previous_insn (insn))
+         continue;
+      else
+       {
+         if (GET_CODE (insn) == INSN
+             && GET_CODE (PATTERN (insn)) == SEQUENCE)
+           insn = XVECEXP (PATTERN (insn), 0,
+                           XVECLEN (PATTERN (insn), 0) - 1);
+       }
     }
 
   return insn;
index c1de4c8..01eda84 100644 (file)
@@ -951,6 +951,7 @@ emit_stack_save (enum save_level save_level, rtx *psave, rtx after)
       rtx seq;
 
       start_sequence ();
+      do_pending_stack_adjust ();
       /* We must validize inside the sequence, to ensure that any instructions
         created by the validize call also get moved to the right place.  */
       if (sa != 0)
@@ -962,6 +963,7 @@ emit_stack_save (enum save_level save_level, rtx *psave, rtx after)
     }
   else
     {
+      do_pending_stack_adjust ();
       if (sa != 0)
        sa = validize_mem (sa);
       emit_insn (fcn (sa, stack_pointer_rtx));
@@ -1018,6 +1020,8 @@ emit_stack_restore (enum save_level save_level, rtx sa, rtx after)
                    gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
     }
 
+  discard_pending_stack_adjust ();
+
   if (after)
     {
       rtx seq;
index aa80ae6..fcb5b0c 100644 (file)
@@ -8107,7 +8107,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
       /* At this point, a MEM target is no longer useful; we will get better
         code without it.  */
 
-      if (GET_CODE (target) == MEM)
+      if (! REG_P (target))
        target = gen_reg_rtx (mode);
 
       /* If op1 was placed in target, swap op0 and op1.  */
@@ -8118,6 +8118,11 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
          op1 = tem;
        }
 
+      /* We generate better code and avoid problems with op1 mentioning
+        target by forcing op1 into a pseudo if it isn't a constant.  */
+      if (! CONSTANT_P (op1))
+       op1 = force_reg (mode, op1);
+
       if (target != op0)
        emit_move_insn (target, op0);
 
index dd7ac9c..ccf3a10 100644 (file)
@@ -526,6 +526,9 @@ extern rtx expand_expr_real (tree, rtx, enum machine_mode,
    arguments waiting to be popped.  */
 extern void init_pending_stack_adjust (void);
 
+/* Discard any pending stack adjustment.  */
+extern void discard_pending_stack_adjust (void);
+
 /* When exiting from function, if safe, clear out any pending stack adjust
    so the adjustment won't get done.  */
 extern void clear_pending_stack_adjust (void);
index 9b34df0..fcba273 100644 (file)
@@ -11,7 +11,7 @@
 @c in the standalone derivations of this file (e.g. NEWS).
 @set copyrights-news 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
 
-@set last-update-news 2004-06-17
+@set last-update-news 2004-12-29
 
 @ifset DOC-NEWS
 @include root.texi
@@ -62,7 +62,7 @@ such changes to @command{g77}.
 
 @ifclear USERVISONLY
 
-@emph{@code{GCC} 3.4.x is the last edition of @code{GCC} to contain @command{g77} - from @code{GCC} 3.5 onwards, use @command{gfortran}}
+@emph{@code{GCC} 3.4.x is the last edition of @code{GCC} to contain @command{g77} - from @code{GCC} 4.0 onwards, use @command{gfortran}}
 
 Changes made to recent versions of GNU Fortran are listed
 below, with the most recent version first.
index 94a27c3..fed908d 100644 (file)
@@ -1591,7 +1591,7 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
       pbi->cc0_live = 0;
 
       if (libcall_is_dead)
-       prev = propagate_block_delete_libcall ( insn, note);
+       prev = propagate_block_delete_libcall (insn, note);
       else
        {
 
@@ -2268,7 +2268,7 @@ libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
     {
       rtx r = SET_SRC (x);
 
-      if (GET_CODE (r) == REG)
+      if (GET_CODE (r) == REG || GET_CODE (r) == SUBREG)
        {
          rtx call = XEXP (note, 0);
          rtx call_pat;
@@ -2302,10 +2302,20 @@ libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
              call_pat = XVECEXP (call_pat, 0, i);
            }
 
-         return insn_dead_p (pbi, call_pat, 1, REG_NOTES (call));
+         if (! insn_dead_p (pbi, call_pat, 1, REG_NOTES (call)))
+           return 0;
+
+         while ((insn = PREV_INSN (insn)) != call)
+           {
+             if (! INSN_P (insn))
+               continue;
+             if (! insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn)))
+               return 0;
+           }
+         return 1;
        }
     }
-  return 1;
+  return 0;
 }
 
 /* Return 1 if register REGNO was used before it was set, i.e. if it is
index b2bbf30..b34422f 100644 (file)
@@ -1828,7 +1828,8 @@ fold_convert (tree type, tree arg)
   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
     return fold (build1 (NOP_EXPR, type, arg));
 
-  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
+      || TREE_CODE (type) == OFFSET_TYPE)
     {
       if (TREE_CODE (arg) == INTEGER_CST)
        {
@@ -1836,7 +1837,8 @@ fold_convert (tree type, tree arg)
          if (tem != NULL_TREE)
            return tem;
        }
-      if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig))
+      if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
+         || TREE_CODE (orig) == OFFSET_TYPE)
         return fold (build1 (NOP_EXPR, type, arg));
       if (TREE_CODE (orig) == COMPLEX_TYPE)
        {
@@ -4486,7 +4488,21 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
        return t1;
       break;
 
-    case NEGATE_EXPR:  case ABS_EXPR:
+    case ABS_EXPR:
+      /* If widening the type changes it from signed to unsigned, then we
+         must avoid building ABS_EXPR itself as unsigned.  */
+      if (TREE_UNSIGNED (ctype) && !TREE_UNSIGNED (type))
+        {
+          tree cstype = (*lang_hooks.types.signed_type) (ctype);
+          if ((t1 = extract_muldiv (op0, c, code, cstype)) != 0)
+            {
+              t1 = fold (build1 (tcode, cstype, fold_convert (cstype, t1)));
+              return fold_convert (ctype, t1);
+            }
+          break;
+        }
+      /* FALLTHROUGH */
+    case NEGATE_EXPR:
       if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
        return fold (build1 (tcode, ctype, fold_convert (ctype, t1)));
       break;
index 747f123..087467c 100644 (file)
@@ -236,7 +236,7 @@ static rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
                                 struct function *);
 static struct temp_slot *find_temp_slot_from_address (rtx);
 static void put_reg_into_stack (struct function *, rtx, tree, enum machine_mode,
-                               enum machine_mode, int, unsigned int, int, htab_t);
+                               unsigned int, bool, bool, bool, htab_t);
 static void schedule_fixup_var_refs (struct function *, rtx, tree, enum machine_mode,
                                     htab_t);
 static void fixup_var_refs (rtx, enum machine_mode, int, rtx, htab_t);
@@ -506,6 +506,7 @@ get_frame_size (void)
    ALIGN controls the amount of alignment for the address of the slot:
    0 means according to MODE,
    -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
+   -2 means use BITS_PER_UNIT,
    positive specifies alignment boundary in bits.
 
    We do not round to stack_boundary here.
@@ -543,6 +544,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
       alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
       size = CEIL_ROUND (size, alignment);
     }
+  else if (align == -2)
+    alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
   else
     alignment = align / BITS_PER_UNIT;
 
@@ -1291,9 +1294,9 @@ put_var_into_stack (tree decl, int rescan)
   enum machine_mode promoted_mode, decl_mode;
   struct function *function = 0;
   tree context;
-  int can_use_addressof;
-  int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
-  int usedp = (TREE_USED (decl)
+  bool can_use_addressof_p;
+  bool volatile_p = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
+  bool used_p = (TREE_USED (decl)
               || (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));
 
   context = decl_function_context (decl);
@@ -1340,7 +1343,7 @@ put_var_into_stack (tree decl, int rescan)
   /* If this variable lives in the current function and we don't need to put it
      in the stack for the sake of setjmp or the non-locality, try to keep it in
      a register until we know we actually need the address.  */
-  can_use_addressof
+  can_use_addressof_p
     = (function == 0
        && ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
        && optimize > 0
@@ -1353,7 +1356,8 @@ put_var_into_stack (tree decl, int rescan)
 
   /* If we can't use ADDRESSOF, make sure we see through one we already
      generated.  */
-  if (! can_use_addressof && GET_CODE (reg) == MEM
+  if (! can_use_addressof_p
+      && GET_CODE (reg) == MEM
       && GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
     reg = XEXP (XEXP (reg, 0), 0);
 
@@ -1361,11 +1365,11 @@ put_var_into_stack (tree decl, int rescan)
 
   if (GET_CODE (reg) == REG)
     {
-      if (can_use_addressof)
+      if (can_use_addressof_p)
        gen_mem_addressof (reg, decl, rescan);
       else
-       put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
-                           decl_mode, volatilep, 0, usedp, 0);
+       put_reg_into_stack (function, reg, TREE_TYPE (decl), decl_mode,
+                           0, volatile_p, used_p, false, 0);
     }
   else if (GET_CODE (reg) == CONCAT)
     {
@@ -1381,14 +1385,14 @@ put_var_into_stack (tree decl, int rescan)
 #ifdef FRAME_GROWS_DOWNWARD
       /* Since part 0 should have a lower address, do it second.  */
       put_reg_into_stack (function, hipart, part_type, part_mode,
-                         part_mode, volatilep, 0, 0, 0);
+                         0, volatile_p, false, false, 0);
       put_reg_into_stack (function, lopart, part_type, part_mode,
-                         part_mode, volatilep, 0, 0, 0);
+                         0, volatile_p, false, true, 0);
 #else
       put_reg_into_stack (function, lopart, part_type, part_mode,
-                         part_mode, volatilep, 0, 0, 0);
+                         0, volatile_p, false, false, 0);
       put_reg_into_stack (function, hipart, part_type, part_mode,
-                         part_mode, volatilep, 0, 0, 0);
+                         0, volatile_p, false, true, 0);
 #endif
 
       /* Change the CONCAT into a combined MEM for both parts.  */
@@ -1409,7 +1413,7 @@ put_var_into_stack (tree decl, int rescan)
       /* Prevent sharing of rtl that might lose.  */
       if (GET_CODE (XEXP (reg, 0)) == PLUS)
        XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
-      if (usedp && rescan)
+      if (used_p && rescan)
        {
          schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
                                   promoted_mode, 0);
@@ -1423,20 +1427,24 @@ put_var_into_stack (tree decl, int rescan)
 
 /* Subroutine of put_var_into_stack.  This puts a single pseudo reg REG
    into the stack frame of FUNCTION (0 means the current function).
+   TYPE is the user-level data type of the value hold in the register.
    DECL_MODE is the machine mode of the user-level data type.
-   PROMOTED_MODE is the machine mode of the register.
-   VOLATILE_P is nonzero if this is for a "volatile" decl.
-   USED_P is nonzero if this reg might have already been used in an insn.  */
+   ORIGINAL_REGNO must be set if the real regno is not visible in REG.
+   VOLATILE_P is true if this is for a "volatile" decl.
+   USED_P is true if this reg might have already been used in an insn.
+   CONSECUTIVE_P is true if the stack slot assigned to reg must be
+   consecutive with the previous stack slot.  */
 
 static void
 put_reg_into_stack (struct function *function, rtx reg, tree type,
-                   enum machine_mode promoted_mode,
-                   enum machine_mode decl_mode, int volatile_p,
-                   unsigned int original_regno, int used_p, htab_t ht)
+                   enum machine_mode decl_mode, unsigned int original_regno,
+                   bool volatile_p, bool used_p, bool consecutive_p,
+                   htab_t ht)
 {
   struct function *func = function ? function : cfun;
-  rtx new = 0;
+  enum machine_mode mode = GET_MODE (reg);
   unsigned int regno = original_regno;
+  rtx new = 0;
 
   if (regno == 0)
     regno = REGNO (reg);
@@ -1449,7 +1457,8 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
     }
 
   if (new == 0)
-    new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
+    new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode),
+                               consecutive_p ? -2 : 0, func);
 
   PUT_CODE (reg, MEM);
   PUT_MODE (reg, decl_mode);
@@ -1471,7 +1480,7 @@ put_reg_into_stack (struct function *function, rtx reg, tree type,
     }
 
   if (used_p)
-    schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
+    schedule_fixup_var_refs (function, reg, type, mode, ht);
 }
 
 /* Make sure that all refs to the variable, previously made
@@ -1639,7 +1648,7 @@ fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_m
   tmp.key = var;
   ime = htab_find (ht, &tmp);
   for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
-    if (INSN_P (XEXP (insn_list, 0)))
+    if (INSN_P (XEXP (insn_list, 0)) && !INSN_DELETED_P (XEXP (insn_list, 0)))
       fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
                           unsignedp, 1, may_share);
 }
@@ -2907,7 +2916,7 @@ static void
 put_addressof_into_stack (rtx r, htab_t ht)
 {
   tree decl, type;
-  int volatile_p, used_p;
+  bool volatile_p, used_p;
 
   rtx reg = XEXP (r, 0);
 
@@ -2926,12 +2935,12 @@ put_addressof_into_stack (rtx r, htab_t ht)
   else
     {
       type = NULL_TREE;
-      volatile_p = 0;
-      used_p = 1;
+      volatile_p = false;
+      used_p = true;
     }
 
-  put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
-                     volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
+  put_reg_into_stack (0, reg, type, GET_MODE (reg), ADDRESSOF_REGNO (r),
+                     volatile_p, used_p, false, ht);
 }
 
 /* List of replacements made below in purge_addressof_1 when creating
index dd69b6e..5d77e23 100644 (file)
@@ -746,7 +746,7 @@ static const char *cpp_unique_options =
  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
  %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
  %{E|M|MM:%W{o*}}";
 
 /* This contains cpp options which are common with cc1_options and are passed
@@ -755,8 +755,9 @@ static const char *cpp_unique_options =
    options used to set target flags.  Those special target flags settings may
    in turn cause preprocessor symbols to be defined specially.  */
 static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
+ %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*}\
+ %{undef}";
 
 /* This contains cpp options which are not passed when the preprocessor
    output will be used by another program.  */
@@ -767,7 +768,7 @@ static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
  %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
  %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
  %{Qn:-fno-ident} %{--help:--help}\
  %{--target-help:--target-help}\
@@ -912,7 +913,7 @@ static const struct compiler default_compilers[] =
                cc1 %(cpp_unique_options) %(cc1_options)}}}\
         %{!fsyntax-only:%(invoke_as)}}}}", 0},
   {"-",
-   "%{!E:%e-E required when input is from standard input}\
+   "%{!E:%e-E or -x required when input is from standard input}\
     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
@@ -1647,7 +1648,11 @@ init_spec (void)
                            "-lgcc",
                            "-lgcc_eh"
 #ifdef USE_LIBUNWIND_EXCEPTIONS
+# ifdef HAVE_LD_STATIC_DYNAMIC
+                           " %{!static:-Bstatic} -lunwind %{!static:-Bdynamic}"
+# else
                            " -lunwind"
+# endif
 #endif
                            );
 
index e83c516..6879829 100644 (file)
@@ -230,11 +230,15 @@ typedef HOST_WIDEST_INT gcov_type;
 
 #endif /* !IN_LIBGCOV */
 
-/* In gcov we want function linkage to be static. In libgcov we need
-   these functions to be extern, so prefix them with __gcov.  In the
-   compiler we want it extern, so that they can be accessed from
-   elsewhere.  */
+/* In gcov we want function linkage to be static.  In the compiler we want
+   it extern, so that they can be accessed from elsewhere.  In libgcov we
+   need these functions to be extern, so prefix them with __gcov.  In
+   libgcov they must also be hidden so that the instance in the executable
+   is not also used in a DSO.  */
 #if IN_LIBGCOV
+
+#include "auto-host.h"   /* for HAVE_GAS_HIDDEN */
+
 #define gcov_var __gcov_var
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
@@ -255,6 +259,16 @@ typedef HOST_WIDEST_INT gcov_type;
 #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
 #pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
 
+#ifdef HAVE_GAS_HIDDEN
+#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
+#else
+#define ATTRIBUTE_HIDDEN
+#endif
+
+#else
+
+#define ATTRIBUTE_HIDDEN
+
 #endif
 
 #ifndef GCOV_LINKAGE
@@ -433,20 +447,20 @@ struct gcov_info
 };
 
 /* Register a new object file module.  */
-extern void __gcov_init (struct gcov_info *);
+extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
 
 /* Called before fork, to avoid double counting.  */
-extern void __gcov_flush (void);
+extern void __gcov_flush (void) ATTRIBUTE_HIDDEN;
 
 /* The merge function that just sums the counters.  */
-extern void __gcov_merge_add (gcov_type *, unsigned);
+extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
 
 /* The merge function to choose the most common value.  */
-extern void __gcov_merge_single (gcov_type *, unsigned);
+extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
 
 /* The merge function to choose the most common difference between
    consecutive values.  */
-extern void __gcov_merge_delta (gcov_type *, unsigned);
+extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
 #endif /* IN_LIBGCOV */
 
 #if IN_LIBGCOV >= 0
@@ -476,7 +490,7 @@ GCOV_LINKAGE struct gcov_var
   size_t alloc;
   gcov_unsigned_t *buffer;
 #endif
-} gcov_var;
+} gcov_var ATTRIBUTE_HIDDEN;
 
 /* Functions for reading and writing gcov files. In libgcov you can
    open the file for reading then writing. Elsewhere you can open the
@@ -488,31 +502,33 @@ GCOV_LINKAGE struct gcov_var
    functions for writing.  Your file may become corrupted if you break
    these invariants.  */
 #if IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/);
+GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 #else
 GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
-GCOV_LINKAGE int gcov_close (void);
+GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 
 /* Available everywhere.  */
 static gcov_position_t gcov_position (void);
 static int gcov_is_error (void);
 static int gcov_is_eof (void);
 
-GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void);
-GCOV_LINKAGE gcov_type gcov_read_counter (void);
-GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *);
+GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN;
 
 #if IN_LIBGCOV
 /* Available only in libgcov */
-GCOV_LINKAGE void gcov_write_counter (gcov_type);
-GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
+GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
+    ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
-                                     const struct gcov_summary *);
+                                     const struct gcov_summary *)
+    ATTRIBUTE_HIDDEN;
 static void gcov_truncate (void);
 static void gcov_rewrite (void);
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
+GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 #else
 /* Available outside libgcov */
 GCOV_LINKAGE const char *gcov_read_string (void);
@@ -522,7 +538,7 @@ GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
 
 #if !IN_GCOV
 /* Available outside gcov */
-GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t);
+GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN;
 #endif
 
 #if !IN_GCOV && !IN_LIBGCOV
index 640ab2c..b9a5038 100644 (file)
@@ -1193,6 +1193,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   rtx a = if_info->a;
   rtx b = if_info->b;
   rtx x = if_info->x;
+  rtx orig_a, orig_b;
   rtx insn_a, insn_b;
   rtx tmp, target;
   int is_mem = 0;
@@ -1248,6 +1249,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
 
   start_sequence ();
 
+  orig_a = a;
+  orig_b = b;
+
   /* If either operand is complex, load it into a register first.
      The best way to do this is to copy the original insn.  In this
      way we preserve any clobbers etc that the insn may have had.
@@ -1279,7 +1283,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
     }
   if (! general_operand (b, GET_MODE (b)))
     {
-      rtx set;
+      rtx set, last;
 
       if (no_new_pseudos)
        goto end_seq_and_fail;
@@ -1287,9 +1291,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       if (is_mem)
        {
           tmp = gen_reg_rtx (GET_MODE (b));
-         tmp = emit_insn (gen_rtx_SET (VOIDmode,
-                                       tmp,
-                                       b));
+         tmp = gen_rtx_SET (VOIDmode, tmp, b);
        }
       else if (! insn_b)
        goto end_seq_and_fail;
@@ -1299,8 +1301,22 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
          tmp = copy_rtx (insn_b);
          set = single_set (tmp);
          SET_DEST (set) = b;
-         tmp = emit_insn (PATTERN (tmp));
+         tmp = PATTERN (tmp);
+       }
+
+      /* If insn to set up A clobbers any registers B depends on, try to
+        swap insn that sets up A with the one that sets up B.  If even
+        that doesn't help, punt.  */
+      last = get_last_insn ();
+      if (last && modified_in_p (orig_b, last))
+       {
+         tmp = emit_insn_before (tmp, get_insns ());
+         if (modified_in_p (orig_a, tmp))
+           goto end_seq_and_fail;
        }
+      else
+       tmp = emit_insn (tmp);
+
       if (recog_memoized (tmp) < 0)
        goto end_seq_and_fail;
     }
index 8a3529b..4f45b09 100644 (file)
@@ -73,7 +73,7 @@ __negdi2 (DWtype u)
 
 #ifdef L_addvsi3
 Wtype
-__addvsi3 (Wtype a, Wtype b)
+__addvSI3 (Wtype a, Wtype b)
 {
   const Wtype w = a + b;
 
@@ -82,11 +82,23 @@ __addvsi3 (Wtype a, Wtype b)
 
   return w;
 }
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__addvsi3 (SItype a, SItype b)
+{
+  const SItype w = a + b;
+
+  if (b >= 0 ? w < a : w > a)
+    abort ();
+
+  return w;
+}
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_addvdi3
 DWtype
-__addvdi3 (DWtype a, DWtype b)
+__addvDI3 (DWtype a, DWtype b)
 {
   const DWtype w = a + b;
 
@@ -99,20 +111,32 @@ __addvdi3 (DWtype a, DWtype b)
 \f
 #ifdef L_subvsi3
 Wtype
-__subvsi3 (Wtype a, Wtype b)
+__subvSI3 (Wtype a, Wtype b)
 {
-  const DWtype w = a - b;
+  const Wtype w = a - b;
 
   if (b >= 0 ? w > a : w < a)
     abort ();
 
   return w;
 }
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__subvsi3 (SItype a, SItype b)
+{
+  const SItype w = a - b;
+
+  if (b >= 0 ? w > a : w < a)
+    abort ();
+
+  return w;
+}
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_subvdi3
 DWtype
-__subvdi3 (DWtype a, DWtype b)
+__subvDI3 (DWtype a, DWtype b)
 {
   const DWtype w = a - b;
 
@@ -126,7 +150,7 @@ __subvdi3 (DWtype a, DWtype b)
 #ifdef L_mulvsi3
 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 Wtype
-__mulvsi3 (Wtype a, Wtype b)
+__mulvSI3 (Wtype a, Wtype b)
 {
   const DWtype w = (DWtype) a * (DWtype) b;
 
@@ -135,11 +159,25 @@ __mulvsi3 (Wtype a, Wtype b)
 
   return w;
 }
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+#undef WORD_SIZE
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+SItype
+__mulvsi3 (SItype a, SItype b)
+{
+  const DItype w = (DItype) a * (DItype) b;
+
+  if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
+    abort ();
+
+  return w;
+}
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_negvsi2
 Wtype
-__negvsi2 (Wtype a)
+__negvSI2 (Wtype a)
 {
   const Wtype w = -a;
 
@@ -148,11 +186,23 @@ __negvsi2 (Wtype a)
 
    return w;
 }
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__negvsi2 (SItype a)
+{
+  const SItype w = -a;
+
+  if (a >= 0 ? w > 0 : w < 0)
+    abort ();
+
+   return w;
+}
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_negvdi2
 DWtype
-__negvdi2 (DWtype a)
+__negvDI2 (DWtype a)
 {
   const DWtype w = -a;
 
@@ -165,10 +215,28 @@ __negvdi2 (DWtype a)
 \f
 #ifdef L_absvsi2
 Wtype
-__absvsi2 (Wtype a)
+__absvSI2 (Wtype a)
 {
   Wtype w = a;
 
+  if (a < 0)
+#ifdef L_negvsi2
+    w = __negvSI2 (a);
+#else
+    w = -a;
+
+  if (w < 0)
+    abort ();
+#endif
+
+   return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__absvsi2 (SItype a)
+{
+  SItype w = a;
+
   if (a < 0)
 #ifdef L_negvsi2
     w = __negvsi2 (a);
@@ -181,17 +249,18 @@ __absvsi2 (Wtype a)
 
    return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_absvdi2
 DWtype
-__absvdi2 (DWtype a)
+__absvDI2 (DWtype a)
 {
   DWtype w = a;
 
   if (a < 0)
 #ifdef L_negvdi2
-    w = __negvdi2 (a);
+    w = __negvDI2 (a);
 #else
     w = -a;
 
@@ -206,7 +275,7 @@ __absvdi2 (DWtype a)
 #ifdef L_mulvdi3
 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 DWtype
-__mulvdi3 (DWtype u, DWtype v)
+__mulvDI3 (DWtype u, DWtype v)
 {
   /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
      but the checked multiplication needs only two.  */
index 0bd6d2e..3e4f687 100644 (file)
@@ -135,6 +135,16 @@ typedef int word_type __attribute__ ((mode (__word__)));
 #define float bogus_type
 #define double bogus_type
 
+/* Versions prior to 3.4.4 were not taking into account the word size for
+   the 5 trapping arithmetic functions absv, addv, subv, mulv and negv.  As
+   a consequence, the si and di variants were always and the only ones emitted.
+   To maintain backward compatibility, COMPAT_SIMODE_TRAPPING_ARITHMETIC is
+   defined on platforms where it makes sense to still have the si variants
+   emitted.  As a bonus, their implementation is now correct.  Note that the
+   same mechanism should have been implemented for the di variants, but it
+   turns out that no platform would define COMPAT_DIMODE_TRAPPING_ARITHMETIC
+   if it existed.  */
+
 #if MIN_UNITS_PER_WORD > 4
 #define W_TYPE_SIZE (8 * BITS_PER_UNIT)
 #define Wtype  DItype
@@ -145,6 +155,7 @@ typedef int word_type __attribute__ ((mode (__word__)));
 #define UDWtype        UTItype
 #define __NW(a,b)      __ ## a ## di ## b
 #define __NDW(a,b)     __ ## a ## ti ## b
+#define COMPAT_SIMODE_TRAPPING_ARITHMETIC
 #elif MIN_UNITS_PER_WORD > 2 \
       || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)
 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
@@ -210,6 +221,17 @@ typedef int word_type __attribute__ ((mode (__word__)));
 #define __fixunsdfSI   __NW(fixunsdf,)
 #define __fixunssfSI   __NW(fixunssf,)
 
+#define __absvSI2      __NW(absv,2)
+#define __addvSI3      __NW(addv,3)
+#define __subvSI3      __NW(subv,3)
+#define __mulvSI3      __NW(mulv,3)
+#define __negvSI2      __NW(negv,2)
+#define __absvDI2      __NDW(absv,2)
+#define __addvDI3      __NDW(addv,3)
+#define __subvDI3      __NDW(subv,3)
+#define __mulvDI3      __NDW(mulv,3)
+#define __negvDI2      __NDW(negv,2)
+
 #define __ffsSI2       __NW(ffs,2)
 #define __clzSI2       __NW(clz,2)
 #define __ctzSI2       __NW(ctz,2)
@@ -251,16 +273,24 @@ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
 extern word_type __cmpdi2 (DWtype, DWtype);
 extern word_type __ucmpdi2 (DWtype, DWtype);
 
-extern Wtype __absvsi2 (Wtype);
-extern DWtype __absvdi2 (DWtype);
-extern Wtype __addvsi3 (Wtype, Wtype);
-extern DWtype __addvdi3 (DWtype, DWtype);
-extern Wtype __subvsi3 (Wtype, Wtype);
-extern DWtype __subvdi3 (DWtype, DWtype);
-extern Wtype __mulvsi3 (Wtype, Wtype);
-extern DWtype __mulvdi3 (DWtype, DWtype);
-extern Wtype __negvsi2 (Wtype);
-extern DWtype __negvdi2 (DWtype);
+extern Wtype __absvSI2 (Wtype);
+extern Wtype __addvSI3 (Wtype, Wtype);
+extern Wtype __subvSI3 (Wtype, Wtype);
+extern Wtype __mulvSI3 (Wtype, Wtype);
+extern Wtype __negvSI2 (Wtype);
+extern DWtype __absvDI2 (DWtype);
+extern DWtype __addvDI3 (DWtype, DWtype);
+extern DWtype __subvDI3 (DWtype, DWtype);
+extern DWtype __mulvDI3 (DWtype, DWtype);
+extern DWtype __negvDI2 (DWtype);
+
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+extern SItype __absvsi2 (SItype);
+extern SItype __addvsi3 (SItype, SItype);
+extern SItype __subvsi3 (SItype, SItype);
+extern SItype __mulvsi3 (SItype, SItype);
+extern SItype __negvsi2 (SItype);
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 
 #if BITS_PER_UNIT == 8
 extern DWtype __fixdfdi (DFtype);
index aae1757..4852bb2 100644 (file)
@@ -1269,7 +1269,9 @@ unroll_loop_stupid (struct loops *loops, struct loop *loop)
 /* Expand a bct instruction in a branch and an increment.
    If flag_inc is set, the induction variable does not need to be
    incremented.  */
-void expand_bct (edge e, int flag_inc)
+
+static void
+expand_bct (edge e, int flag_inc)
 {
   rtx bct_insn = BB_END (e->src);
   rtx cmp;
@@ -1278,12 +1280,11 @@ void expand_bct (edge e, int flag_inc)
 
   rtx tgt;
   rtx condition;
-  rtx label;
+  rtx labelref;
   rtx reg;
-  rtx jump;
-  rtx pattern = PATTERN(bct_insn);
+  rtx pattern = PATTERN (bct_insn);
   
-  if (!(is_bct_cond(bct_insn)))
+  if (!is_bct_cond (bct_insn))
     return;
 
   inc = get_var_set_from_bct (bct_insn);
@@ -1299,14 +1300,12 @@ void expand_bct (edge e, int flag_inc)
     }
 
   condition = XEXP (SET_SRC (cmp), 0);
-  label = XEXP (SET_SRC (cmp), 1);
+  labelref = XEXP (SET_SRC (cmp), 1);
 
   do_compare_rtx_and_jump (copy_rtx (reg), XEXP (condition, 1), 
                           GET_CODE (condition), 0,
                           GET_MODE (reg), NULL_RTX, NULL_RTX,
-                          label);
-  jump = get_last_insn ();
-  JUMP_LABEL (jump) = label;
+                          XEXP (labelref, 0));
   seq = get_insns ();
   end_sequence ();
   emit_insn_after (seq, bct_insn);
index 5a47309..4ddd77a 100644 (file)
@@ -303,6 +303,14 @@ static void record_giv (const struct loop *, struct induction *, rtx, rtx,
                        rtx, rtx, rtx, rtx, int, enum g_types, int, int,
                        rtx *);
 static void update_giv_derive (const struct loop *, rtx);
+static HOST_WIDE_INT get_monotonic_increment (struct iv_class *);
+static bool biased_biv_fits_mode_p (const struct loop *, struct iv_class *,
+                                   HOST_WIDE_INT, enum machine_mode,
+                                   unsigned HOST_WIDE_INT);
+static bool biv_fits_mode_p (const struct loop *, struct iv_class *,
+                            HOST_WIDE_INT, enum machine_mode, bool);
+static bool extension_within_bounds_p (const struct loop *, struct iv_class *,
+                                      HOST_WIDE_INT, rtx);
 static void check_ext_dependent_givs (const struct loop *, struct iv_class *);
 static int basic_induction_var (const struct loop *, rtx, enum machine_mode,
                                rtx, rtx, rtx *, rtx *, rtx **);
@@ -765,6 +773,9 @@ scan_loop (struct loop *loop, int flags)
        in_libcall--;
       if (GET_CODE (p) == INSN)
        {
+         /* Do not scan past an optimization barrier.  */
+         if (GET_CODE (PATTERN (p)) == ASM_INPUT)
+           break;
          temp = find_reg_note (p, REG_LIBCALL, NULL_RTX);
          if (temp)
            in_libcall++;
@@ -3856,7 +3867,7 @@ emit_prefetch_instructions (struct loop *loop)
   struct prefetch_info info[MAX_PREFETCHES];
   struct loop_ivs *ivs = LOOP_IVS (loop);
 
-  if (!HAVE_prefetch)
+  if (!HAVE_prefetch || PREFETCH_BLOCK == 0)
     return;
 
   /* Consider only loops w/o calls.  When a call is done, the loop is probably
@@ -7364,192 +7375,204 @@ combine_givs_p (struct induction *g1, struct induction *g2)
   return NULL_RTX;
 }
 \f
-/* Check each extension dependent giv in this class to see if its
-   root biv is safe from wrapping in the interior mode, which would
-   make the giv illegal.  */
+/* See if BL is monotonic and has a constant per-iteration increment.
+   Return the increment if so, otherwise return 0.  */
 
-static void
-check_ext_dependent_givs (const struct loop *loop, struct iv_class *bl)
+static HOST_WIDE_INT
+get_monotonic_increment (struct iv_class *bl)
 {
-  struct loop_info *loop_info = LOOP_INFO (loop);
-  int ze_ok = 0, se_ok = 0, info_ok = 0;
-  enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
-  HOST_WIDE_INT start_val;
-  unsigned HOST_WIDE_INT u_end_val = 0;
-  unsigned HOST_WIDE_INT u_start_val = 0;
-  rtx incr = pc_rtx;
   struct induction *v;
+  rtx incr;
+
+  /* Get the total increment and check that it is constant.  */
+  incr = biv_total_increment (bl);
+  if (incr == 0 || GET_CODE (incr) != CONST_INT)
+    return 0;
+