public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/gcc] rhel-f41-base: 4.4.0-5
@ 2026-06-29 12:24 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2026-06-29 12:24 UTC (permalink / raw)
  To: git-commits

A new commit has been pushed.

Repo   : rpms/gcc
Branch : rhel-f41-base
Commit : c3b415bb004e172d471197c7df5f335aa23d3ee3
Author : Jakub Jelinek <jakub@fedoraproject.org>
Date   : 2009-05-14T08:52:31+00:00
Stats  : +4220/-681 in 15 file(s)
URL    : https://src.fedoraproject.org/rpms/gcc/c/c3b415bb004e172d471197c7df5f335aa23d3ee3?branch=rhel-f41-base

Log:
4.4.0-5

---
diff --git a/.cvsignore b/.cvsignore
index 973d5b9..23f2f52 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,2 +1,2 @@
 fastjar-0.97.tar.gz
-gcc-4.4.0-20090414.tar.bz2
+gcc-4.4.0-20090514.tar.bz2

diff --git a/gcc.spec b/gcc.spec
index 1f9990a..5c77bbc 100644
--- a/gcc.spec
+++ b/gcc.spec
@@ -1,40 +1,41 @@
-%define DATE 20090414
-%define SVNREV 146037
-%define gcc_version 4.4.0
+%global DATE 20090514
+%global SVNREV 147523
+%global gcc_version 4.4.0
 # Note, gcc_release must be integer, if you want to add suffixes to
 # %{release}, append them after %{gcc_release} on Release: line.
-%define gcc_release 0.34
-%define _unpackaged_files_terminate_build 0
-%define multilib_64_archs sparc64 ppc64 s390x x86_64
-%define include_gappletviewer 1
+%global gcc_release 5
+%global _unpackaged_files_terminate_build 0
+%global multilib_64_archs sparc64 ppc64 s390x x86_64
+%global include_gappletviewer 1
 %ifarch %{ix86} x86_64 ia64 ppc ppc64 alpha
-%define build_ada 1
+%global build_ada 1
 %else
-%define build_ada 0
+%global build_ada 0
 %endif
-%define build_java 1
+%global build_java 1
 %ifarch %{sparc}
-%define build_cloog 0
+%global build_cloog 0
 %else
-%define build_cloog 1
+%global build_cloog 1
 %endif
+%global build_libstdcxx_docs 1
 # If you don't have already a usable gcc-java and libgcj for your arch,
 # do on some arch which has it rpmbuild -bc --with java_tar gcc41.spec
 # which creates libjava-classes-%{version}-%{release}.tar.bz2
 # With this then on the new arch do rpmbuild -ba -v --with java_bootstrap gcc41.spec
-%define bootstrap_java %{?_with_java_bootstrap:%{build_java}}%{!?_with_java_bootstrap:0}
-%define build_java_tar %{?_with_java_tar:%{build_java}}%{!?_with_java_tar:0}
+%global bootstrap_java %{?_with_java_bootstrap:%{build_java}}%{!?_with_java_bootstrap:0}
+%global build_java_tar %{?_with_java_tar:%{build_java}}%{!?_with_java_tar:0}
 %ifarch s390x
-%define multilib_32_arch s390
+%global multilib_32_arch s390
 %endif
 %ifarch sparc64
-%define multilib_32_arch sparcv9
+%global multilib_32_arch sparcv9
 %endif
 %ifarch ppc64
-%define multilib_32_arch ppc
+%global multilib_32_arch ppc
 %endif
 %ifarch x86_64
-%define multilib_32_arch i586
+%global multilib_32_arch i586
 %endif
 Summary: Various compilers (C, C++, Objective-C, Java, ...)
 Name: gcc
@@ -52,7 +53,7 @@ Source0: gcc-%{version}-%{DATE}.tar.bz2
 Source1: libgcc_post_upgrade.c
 Source2: README.libgcjwebplugin.so
 Source3: protoize.1
-%define fastjar_ver 0.97
+%global fastjar_ver 0.97
 Source4: http://download.savannah.nongnu.org/releases/fastjar/fastjar-%{fastjar_ver}.tar.gz
 URL: http://gcc.gnu.org
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -99,6 +100,10 @@ BuildRequires: libunwind >= 0.98
 %if %{build_cloog}
 BuildRequires: ppl >= 0.10, ppl-devel >= 0.10, cloog-ppl >= 0.15, cloog-ppl-devel >= 0.15
 %endif
+%if %{build_libstdcxx_docs}
+BuildRequires: doxygen
+BuildRequires: graphviz
+%endif
 Requires: cpp = %{version}-%{release}
 # Need .eh_frame ld optimizations
 # Need proper visibility support
@@ -127,7 +132,8 @@ Obsoletes: libgnat < %{version}-%{release}
 %if %{build_cloog}
 Requires: cloog-ppl >= 0.15
 %endif
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 AutoReq: true
 
 Patch0: gcc44-hack.patch
@@ -147,26 +153,29 @@ Patch20: gcc44-libtool-no-rpath.patch
 Patch21: gcc44-cloog-dl.patch
 Patch22: gcc44-raw-string.patch
 Patch24: gcc44-atom.patch
-Patch26: gcc44-power7.patch
+Patch25: gcc44-power7.patch
+Patch26: gcc44-power7-2.patch
+Patch27: gcc44-power7-3.patch
 Patch28: gcc44-pr38757.patch
-Patch30: gcc44-pr39543.patch
-Patch31: gcc44-pr39763.patch
+Patch29: gcc44-pr39856.patch
+Patch30: gcc44-libstdc++-docs.patch
+Patch31: gcc44-pr39942.patch
 
 Patch1000: fastjar-0.97-segfault.patch
 
 # On ARM EABI systems, we do want -gnueabi to be part of the
 # target triple.
 %ifnarch %{arm}
-%define _gnu %{nil}
+%global _gnu %{nil}
 %endif
 %ifarch sparcv9
-%define gcc_target_platform sparc64-%{_vendor}-%{_target_os}
+%global gcc_target_platform sparc64-%{_vendor}-%{_target_os}
 %endif
 %ifarch ppc
-%define gcc_target_platform ppc64-%{_vendor}-%{_target_os}
+%global gcc_target_platform ppc64-%{_vendor}-%{_target_os}
 %endif
 %ifnarch sparcv9 ppc
-%define gcc_target_platform %{_target_platform}
+%global gcc_target_platform %{_target_platform}
 %endif
 
 %description
@@ -215,6 +224,15 @@ This is the GNU implementation of the standard C++ libraries.  This
 package includes the header files and libraries needed for C++
 development. This includes rewritten implementation of STL.
 
+%package -n libstdc++-docs
+Summary: Documentation for the GNU standard C++ library
+Group: Development/Libraries
+Autoreq: true
+
+%description -n libstdc++-docs
+Manual, doxygen generated API information and Frequently Asked Questions
+for the GNU standard C++ library.
+
 %package objc
 Summary: Objective-C support for GCC
 Group: Development/Languages
@@ -251,7 +269,8 @@ Group: Development/Languages
 Requires: gcc = %{version}-%{release}
 Requires: libgfortran = %{version}-%{release}
 BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 Autoreq: true
 
 %description gfortran
@@ -270,7 +289,8 @@ Fortran dynamically linked programs.
 %package -n libgomp
 Summary: GCC OpenMP v3.0 shared support library
 Group: System Environment/Libraries
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 
 %description -n libgomp
 This package contains GCC shared support library which is needed
@@ -305,7 +325,8 @@ Requires: gcc = %{version}-%{release}
 Requires: libgcj = %{version}-%{release}
 Requires: libgcj-devel = %{version}-%{release}
 Requires: /usr/share/java/eclipse-ecj.jar
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 Autoreq: true
 
 %description java
@@ -315,7 +336,8 @@ bytecode into native code.
 %package -n libgcj
 Summary: Java runtime library for gcc
 Group: System Environment/Libraries
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 Requires: zip >= 2.1
 Requires: gtk2 >= 2.4.0
 Requires: glib2 >= 2.4.0
@@ -360,7 +382,8 @@ The Java(tm) runtime library sources for use in Eclipse.
 %package -n cpp
 Summary: The C Preprocessor
 Group: Development/Languages
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 Autoreq: true
 
 %description -n cpp
@@ -390,7 +413,8 @@ Summary: Ada 95 support for GCC
 Group: Development/Languages
 Requires: gcc = %{version}-%{release}
 Requires: libgnat = %{version}-%{release}, libgnat-devel = %{version}-%{release}
-Prereq: /sbin/install-info
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
 Autoreq: true
 
 %description gnat
@@ -436,10 +460,15 @@ which are required to compile with the GNAT.
 %endif
 %patch22 -p0 -b .raw-string~
 %patch24 -p0 -b .atom~
-%patch26 -p0 -b .power7~
+%patch25 -p0 -b .power7~
+%patch26 -p0 -b .power7-2~
+%patch27 -p0 -b .power7-3~
 %patch28 -p0 -b .pr38757~
-#%patch30 -p0 -b .pr39543~
-%patch31 -p0 -b .pr39763~
+%patch29 -p0 -b .pr39856~
+%if %{build_libstdcxx_docs}
+%patch30 -p0 -b .libstdc++-docs~
+%endif
+%patch31 -p0 -b .pr39942~
 
 # This testcase doesn't compile.
 rm libjava/testsuite/libjava.lang/PR35020*
@@ -493,7 +522,7 @@ fi
 # fastjar, build it anyway.
 mkdir fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}
 cd fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}
-../configure CFLAGS="$RPM_OPT_FLAGS" --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir}
+../configure CFLAGS="%{optflags}" --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir}
 make %{?_smp_mflags}
 export PATH=`pwd`${PATH:+:$PATH}
 cd ../../
@@ -533,7 +562,7 @@ cd ..
 %endif
 
 CC=gcc
-OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/\(-Wp,\)\?-D_FORTIFY_SOURCE=[12]//g'`
+OPT_FLAGS=`echo %{optflags}|sed -e 's/\(-Wp,\)\?-D_FORTIFY_SOURCE=[12]//g'`
 OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'`
 %ifarch sparc
 OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mcpu=ultrasparc/-mtune=ultrasparc/g;s/-mcpu=v[78]//g'`
@@ -632,19 +661,6 @@ CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" 
 #GCJFLAGS="$OPT_FLAGS" make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap
 GCJFLAGS="$OPT_FLAGS" make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" profiledbootstrap
 
-# run the tests.
-make %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector}'" || :
-echo ====================TESTING=========================
-( ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}'
-echo ====================TESTING END=====================
-mkdir testlogs-%{_target_platform}-%{version}-%{release}
-for i in `find . -name \*.log | grep -F testsuite/ | grep -v 'config.log\|acats\|ada'`; do
-  ln $i testlogs-%{_target_platform}-%{version}-%{release}/ || :
-done
-tar cf - testlogs-%{_target_platform}-%{version}-%{release} | bzip2 -9c \
-  | uuencode testlogs-%{_target_platform}.tar.bz2 || :
-rm -rf testlogs-%{_target_platform}-%{version}-%{release}
-
 # Make protoize
 make -C gcc CC="./xgcc -B ./ -O2" proto
 
@@ -656,6 +672,14 @@ done
 make -C gcc generated-manpages
 for i in ../gcc/doc/*.texi; do mv -f $i.orig $i; done
 
+# Make generated doxygen pages.
+%if %{build_libstdcxx_docs}
+cd %{gcc_target_platform}/libstdc++-v3
+make doc-html-doxygen
+make doc-man-doxygen
+cd ../..
+%endif
+
 # Copy various doc files here and there
 cd ..
 mkdir -p rpm.doc/gfortran rpm.doc/objc
@@ -704,11 +728,7 @@ tar cf - -T libjava-classes.list | bzip2 -9 > $RPM_SOURCE_DIR/libjava-classes-%{
 %endif
 
 %install
-rm -fr $RPM_BUILD_ROOT
-
-perl -pi -e \
-  's~href="l(ibstdc|atest)~href="http://gcc.gnu.org/onlinedocs/libstdc++/l\1~' \
-  libstdc++-v3/doc/html/api.html
+rm -fr %{buildroot}
 
 cd obj-%{gcc_target_platform}
 
@@ -724,31 +744,31 @@ TARGET_PLATFORM=%{gcc_target_platform}
 # There are some MP bugs in libstdc++ Makefiles
 make -C %{gcc_target_platform}/libstdc++-v3
 
-make prefix=$RPM_BUILD_ROOT%{_prefix} mandir=$RPM_BUILD_ROOT%{_mandir} \
-  infodir=$RPM_BUILD_ROOT%{_infodir} install
+make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \
+  infodir=%{buildroot}%{_infodir} install
 %if %{build_java}
-make DESTDIR=$RPM_BUILD_ROOT -C %{gcc_target_platform}/libjava install-src.zip
+make DESTDIR=%{buildroot} -C %{gcc_target_platform}/libjava install-src.zip
 %endif
 %if %{build_ada}
-chmod 644 $RPM_BUILD_ROOT%{_infodir}/gnat*
+chmod 644 %{buildroot}%{_infodir}/gnat*
 %endif
 
-FULLPATH=$RPM_BUILD_ROOT%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
-FULLEPATH=$RPM_BUILD_ROOT%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}
+FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
+FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}
 
 # fix some things
-ln -sf gcc $RPM_BUILD_ROOT%{_prefix}/bin/cc
-mkdir -p $RPM_BUILD_ROOT/lib
-ln -sf ..%{_prefix}/bin/cpp $RPM_BUILD_ROOT/lib/cpp
-ln -sf gfortran $RPM_BUILD_ROOT%{_prefix}/bin/f95
-rm -f $RPM_BUILD_ROOT%{_infodir}/dir
-gzip -9 $RPM_BUILD_ROOT%{_infodir}/*.info*
-ln -sf gcc $RPM_BUILD_ROOT%{_prefix}/bin/gnatgcc
+ln -sf gcc %{buildroot}%{_prefix}/bin/cc
+mkdir -p %{buildroot}/lib
+ln -sf ..%{_prefix}/bin/cpp %{buildroot}/lib/cpp
+ln -sf gfortran %{buildroot}%{_prefix}/bin/f95
+rm -f %{buildroot}%{_infodir}/dir
+gzip -9 %{buildroot}%{_infodir}/*.info*
+ln -sf gcc %{buildroot}%{_prefix}/bin/gnatgcc
 
 cxxconfig="`find %{gcc_target_platform}/libstdc++-v3/include -name c++config.h`"
 for i in `find %{gcc_target_platform}/[36]*/libstdc++-v3/include -name c++config.h 2>/dev/null`; do
   if ! diff -up $cxxconfig $i; then
-    cat > $RPM_BUILD_ROOT%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/bits/c++config.h <<EOF
+    cat > %{buildroot}%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/bits/c++config.h <<EOF
 #ifndef _CPP_CPPCONFIG_WRAPPER
 #define _CPP_CPPCONFIG_WRAPPER 1
 #include <bits/wordsize.h>
@@ -771,7 +791,7 @@ EOF
   fi
 done
 
-for f in `find $RPM_BUILD_ROOT%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/ -name c++config.h`; do
+for f in `find %{buildroot}%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/ -name c++config.h`; do
   for i in 1 2 4 8; do
     sed -i -e 's/#define _GLIBCXX_ATOMIC_BUILTINS_'$i' 1/#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_'$i'\
 &\
@@ -788,15 +808,25 @@ done
 # 4) it is huge
 # People can always precompile on their own whatever they want, but
 # shipping this for everybody is unnecessary.
-rm -rf $RPM_BUILD_ROOT%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/bits/stdc++.h.gch
+rm -rf %{buildroot}%{_prefix}/include/c++/%{gcc_version}/%{gcc_target_platform}/bits/stdc++.h.gch
+
+%if %{build_libstdcxx_docs}
+libstdcxx_doc_builddir=%{gcc_target_platform}/libstdc++-v3/doc/doxygen
+mkdir -p ../rpm.doc/libstdc++-v3
+cp -r -p ../libstdc++-v3/doc/html ../rpm.doc/libstdc++-v3/html
+mv $libstdcxx_doc_builddir/html ../rpm.doc/libstdc++-v3/html/api
+mkdir -p %{buildroot}%{_mandir}
+mv $libstdcxx_doc_builddir/man/man3 %{buildroot}%{_mandir}/man3/
+find ../rpm.doc/libstdc++-v3 -name \*~ | xargs rm
+%endif
 
 %ifarch sparcv9 sparc64
-ln -f $RPM_BUILD_ROOT%{_prefix}/bin/%{gcc_target_platform}-gcc \
-  $RPM_BUILD_ROOT%{_prefix}/bin/sparc-%{_vendor}-%{_target_os}-gcc
+ln -f %{buildroot}%{_prefix}/bin/%{gcc_target_platform}-gcc \
+  %{buildroot}%{_prefix}/bin/sparc-%{_vendor}-%{_target_os}-gcc
 %endif
 %ifarch ppc ppc64
-ln -f $RPM_BUILD_ROOT%{_prefix}/bin/%{gcc_target_platform}-gcc \
-  $RPM_BUILD_ROOT%{_prefix}/bin/ppc-%{_vendor}-%{_target_os}-gcc
+ln -f %{buildroot}%{_prefix}/bin/%{gcc_target_platform}-gcc \
+  %{buildroot}%{_prefix}/bin/ppc-%{_vendor}-%{_target_os}-gcc
 %endif
 
 %ifarch sparcv9 ppc
@@ -811,24 +841,24 @@ else
   FULLLPATH=$FULLPATH
 fi
 
-find $RPM_BUILD_ROOT -name \*.la | xargs rm -f
+find %{buildroot} -name \*.la | xargs rm -f
 %if %{build_java}
 # gcj -static doesn't work properly anyway, unless using --whole-archive
 # and saving 35MB is not bad.
-find $RPM_BUILD_ROOT -name libgcj.a -o -name libgtkpeer.a \
+find %{buildroot} -name libgcj.a -o -name libgtkpeer.a \
 		     -o -name libgjsmalsa.a -o -name libgcj-tools.a -o -name libjvm.a \
 		     -o -name libgij.a -o -name libgcj_bc.a -o -name libjavamath.a \
   | xargs rm -f
 
-mv $RPM_BUILD_ROOT%{_prefix}/lib/libgcj.spec $FULLPATH/
+mv %{buildroot}%{_prefix}/lib/libgcj.spec $FULLPATH/
 sed -i -e 's/lib: /&%%{static:%%eJava programs cannot be linked statically}/' \
   $FULLPATH/libgcj.spec
 %endif
 
-mkdir -p $RPM_BUILD_ROOT/%{_lib}
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgcc_s.so.1 $RPM_BUILD_ROOT/%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1
-chmod 755 $RPM_BUILD_ROOT/%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1
-ln -sf libgcc_s-%{gcc_version}-%{DATE}.so.1 $RPM_BUILD_ROOT/%{_lib}/libgcc_s.so.1
+mkdir -p %{buildroot}/%{_lib}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1
+chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1
+ln -sf libgcc_s-%{gcc_version}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1
 ln -sf /%{_lib}/libgcc_s.so.1 $FULLPATH/libgcc_s.so
 %ifarch sparcv9 ppc
 ln -sf /lib64/libgcc_s.so.1 $FULLPATH/64/libgcc_s.so
@@ -837,30 +867,30 @@ ln -sf /lib64/libgcc_s.so.1 $FULLPATH/64/libgcc_s.so
 ln -sf /lib/libgcc_s.so.1 $FULLPATH/32/libgcc_s.so
 %endif
 
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgomp.spec $FULLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.spec $FULLPATH/
 
 %if %{build_ada}
-mv -f $FULLPATH/adalib/libgnarl-*.so $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
-mv -f $FULLPATH/adalib/libgnat-*.so $RPM_BUILD_ROOT%{_prefix}/%{_lib}/
+mv -f $FULLPATH/adalib/libgnarl-*.so %{buildroot}%{_prefix}/%{_lib}/
+mv -f $FULLPATH/adalib/libgnat-*.so %{buildroot}%{_prefix}/%{_lib}/
 rm -f $FULLPATH/adalib/libgnarl.so* $FULLPATH/adalib/libgnat.so*
 %endif
 
-mkdir -p $RPM_BUILD_ROOT%{_prefix}/libexec/getconf
+mkdir -p %{buildroot}%{_prefix}/libexec/getconf
 if gcc/xgcc -B gcc/ -E -dD -xc /dev/null | grep __LONG_MAX__.*2147483647; then
-  ln -sf POSIX_V6_ILP32_OFF32 $RPM_BUILD_ROOT%{_prefix}/libexec/getconf/default
+  ln -sf POSIX_V6_ILP32_OFF32 %{buildroot}%{_prefix}/libexec/getconf/default
 else
-  ln -sf POSIX_V6_LP64_OFF64 $RPM_BUILD_ROOT%{_prefix}/libexec/getconf/default
+  ln -sf POSIX_V6_LP64_OFF64 %{buildroot}%{_prefix}/libexec/getconf/default
 fi
 
 %if %{build_java}
 pushd ../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}
-make install DESTDIR=$RPM_BUILD_ROOT
+make install DESTDIR=%{buildroot}
 popd
 
 if [ "%{_lib}" != "lib" ]; then
-  mkdir -p $RPM_BUILD_ROOT%{_prefix}/%{_lib}/pkgconfig
-  sed '/^libdir/s/lib$/%{_lib}/' $RPM_BUILD_ROOT%{_prefix}/lib/pkgconfig/libgcj-*.pc \
-    > $RPM_BUILD_ROOT%{_prefix}/%{_lib}/pkgconfig/`basename $RPM_BUILD_ROOT%{_prefix}/lib/pkgconfig/libgcj-*.pc`
+  mkdir -p %{buildroot}%{_prefix}/%{_lib}/pkgconfig
+  sed '/^libdir/s/lib$/%{_lib}/' %{buildroot}%{_prefix}/lib/pkgconfig/libgcj-*.pc \
+    > %{buildroot}%{_prefix}/%{_lib}/pkgconfig/`basename %{buildroot}%{_prefix}/lib/pkgconfig/libgcj-*.pc`
 fi
 %endif
 
@@ -891,14 +921,14 @@ ln -sf ../../../../%{_lib}/libgij.so.10.* libgij.so
 %endif
 fi
 %if %{build_java}
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgcj_bc.so $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgcj_bc.so $FULLLPATH/
 %endif
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libstdc++.*a $FULLLPATH/
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libsupc++.*a .
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgfortran.*a .
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libobjc.*a .
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgomp.*a .
-mv -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libmudflap{,th}.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libsupc++.*a .
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgfortran.*a .
+mv -f %{buildroot}%{_prefix}/%{_lib}/libobjc.*a .
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.*a .
+mv -f %{buildroot}%{_prefix}/%{_lib}/libmudflap{,th}.*a $FULLLPATH/
 
 %if %{build_ada}
 %ifarch sparcv9 ppc
@@ -956,10 +986,10 @@ ln -sf ../`echo ../../../../lib/libgij.so.10.* | sed s~/lib/~/lib64/~` 64/libgij
 ln -sf lib32/libgcj_bc.so libgcj_bc.so
 ln -sf ../lib64/libgcj_bc.so 64/libgcj_bc.so
 %endif
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib64/libsupc++.*a 64/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib64/libgfortran.*a 64/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib64/libobjc.*a 64/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib64/libgomp.*a 64/
+mv -f %{buildroot}%{_prefix}/lib64/libsupc++.*a 64/
+mv -f %{buildroot}%{_prefix}/lib64/libgfortran.*a 64/
+mv -f %{buildroot}%{_prefix}/lib64/libobjc.*a 64/
+mv -f %{buildroot}%{_prefix}/lib64/libgomp.*a 64/
 ln -sf lib32/libstdc++.a libstdc++.a
 ln -sf ../lib64/libstdc++.a 64/libstdc++.a
 ln -sf lib32/libmudflap.a libmudflap.a
@@ -989,10 +1019,10 @@ ln -sf ../`echo ../../../../lib64/libgcj.so.10.* | sed s~/../lib64/~/~` 32/libgc
 ln -sf ../`echo ../../../../lib64/libgcj-tools.so.10.* | sed s~/../lib64/~/~` 32/libgcj-tools.so
 ln -sf ../`echo ../../../../lib64/libgij.so.10.* | sed s~/../lib64/~/~` 32/libgij.so
 %endif
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib/libsupc++.*a 32/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib/libgfortran.*a 32/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib/libobjc.*a 32/
-mv -f $RPM_BUILD_ROOT%{_prefix}/lib/libgomp.*a 32/
+mv -f %{buildroot}%{_prefix}/lib/libsupc++.*a 32/
+mv -f %{buildroot}%{_prefix}/lib/libgfortran.*a 32/
+mv -f %{buildroot}%{_prefix}/lib/libobjc.*a 32/
+mv -f %{buildroot}%{_prefix}/lib/libgomp.*a 32/
 %endif
 %ifarch sparc64 ppc64
 ln -sf ../lib32/libstdc++.a 32/libstdc++.a
@@ -1031,14 +1061,14 @@ strip -g `find . \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \
 		    -o -name libmudflap.a -o -name libmudflapth.a \
 		    -o -name libgcc.a -o -name libgcov.a \) -a -type f`
 popd
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgfortran.so.3.*
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgomp.so.1.*
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libmudflap{,th}.so.0.*
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libobjc.so.2.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgfortran.so.3.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgomp.so.1.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libmudflap{,th}.so.0.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libobjc.so.2.*
 
 %if %{build_ada}
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgnarl*so*
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgnat*so*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnarl*so*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnat*so*
 %endif
 
 mv $FULLPATH/include-fixed/syslimits.h $FULLPATH/include/syslimits.h
@@ -1051,7 +1081,7 @@ for h in `find $FULLPATH/include -name \*.h`; do
   fi
 done
 
-cat > $RPM_BUILD_ROOT%{_prefix}/bin/c89 <<"EOF"
+cat > %{buildroot}%{_prefix}/bin/c89 <<"EOF"
 #!/bin/sh
 fl="-std=c89"
 for opt; do
@@ -1063,7 +1093,7 @@ for opt; do
 done
 exec gcc $fl ${1+"$@"}
 EOF
-cat > $RPM_BUILD_ROOT%{_prefix}/bin/c99 <<"EOF"
+cat > %{buildroot}%{_prefix}/bin/c99 <<"EOF"
 #!/bin/sh
 fl="-std=c99"
 for opt; do
@@ -1075,11 +1105,11 @@ for opt; do
 done
 exec gcc $fl ${1+"$@"}
 EOF
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/bin/c?9
+chmod 755 %{buildroot}%{_prefix}/bin/c?9
 
-mkdir -p $RPM_BUILD_ROOT%{_prefix}/sbin
-gcc -static -Os %{SOURCE1} -o $RPM_BUILD_ROOT%{_prefix}/sbin/libgcc_post_upgrade
-strip $RPM_BUILD_ROOT%{_prefix}/sbin/libgcc_post_upgrade
+mkdir -p %{buildroot}%{_prefix}/sbin
+gcc -static -Os %{SOURCE1} -o %{buildroot}%{_prefix}/sbin/libgcc_post_upgrade
+strip %{buildroot}%{_prefix}/sbin/libgcc_post_upgrade
 
 cd ..
 %find_lang %{name}
@@ -1087,38 +1117,54 @@ cd ..
 
 # Remove binaries we will not be including, so that they don't end up in
 # gcc-debuginfo
-rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/{libffi*,libiberty.a}
+rm -f %{buildroot}%{_prefix}/%{_lib}/{libffi*,libiberty.a}
 rm -f $FULLEPATH/install-tools/{mkheaders,fixincl}
-rm -f $RPM_BUILD_ROOT%{_prefix}/lib/{32,64}/libiberty.a
-rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libssp*
-rm -f $RPM_BUILD_ROOT%{_prefix}/bin/gnative2ascii
+rm -f %{buildroot}%{_prefix}/lib/{32,64}/libiberty.a
+rm -f %{buildroot}%{_prefix}/%{_lib}/libssp*
+rm -f %{buildroot}%{_prefix}/bin/gnative2ascii
 
 %ifarch %{multilib_64_archs}
 # Remove libraries for the other arch on multilib arches
-rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.so*
-rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.a
+rm -f %{buildroot}%{_prefix}/lib/lib*.so*
+rm -f %{buildroot}%{_prefix}/lib/lib*.a
 %else
 %ifarch sparcv9 ppc
-rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.so*
-rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.a
+rm -f %{buildroot}%{_prefix}/lib64/lib*.so*
+rm -f %{buildroot}%{_prefix}/lib64/lib*.a
 %endif
 %endif
 
 %if %{build_java}
-mkdir -p $RPM_BUILD_ROOT%{_prefix}/share/java/gcj-endorsed \
-	 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-%{version}/classmap.db.d
-chmod 755 $RPM_BUILD_ROOT%{_prefix}/share/java/gcj-endorsed \
-	  $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-%{version} \
-	  $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-%{version}/classmap.db.d
-touch $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj-%{version}/classmap.db
+mkdir -p %{buildroot}%{_prefix}/share/java/gcj-endorsed \
+	 %{buildroot}%{_prefix}/%{_lib}/gcj-%{version}/classmap.db.d
+chmod 755 %{buildroot}%{_prefix}/share/java/gcj-endorsed \
+	  %{buildroot}%{_prefix}/%{_lib}/gcj-%{version} \
+	  %{buildroot}%{_prefix}/%{_lib}/gcj-%{version}/classmap.db.d
+touch %{buildroot}%{_prefix}/%{_lib}/gcj-%{version}/classmap.db
 %endif
 
-install -m644 %{SOURCE3} $RPM_BUILD_ROOT%{_mandir}/man1/protoize.1
-echo '.so man1/protoize.1' > $RPM_BUILD_ROOT%{_mandir}/man1/unprotoize.1
-chmod 644 $RPM_BUILD_ROOT%{_mandir}/man1/unprotoize.1
+install -m644 %{SOURCE3} %{buildroot}%{_mandir}/man1/protoize.1
+echo '.so man1/protoize.1' > %{buildroot}%{_mandir}/man1/unprotoize.1
+chmod 644 %{buildroot}%{_mandir}/man1/unprotoize.1
+
+%check
+cd obj-%{gcc_target_platform}
+
+# run the tests.
+make %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector}'" || :
+echo ====================TESTING=========================
+( LC_ALL=C ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}'
+echo ====================TESTING END=====================
+mkdir testlogs-%{_target_platform}-%{version}-%{release}
+for i in `find . -name \*.log | grep -F testsuite/ | grep -v 'config.log\|acats\|ada'`; do
+  ln $i testlogs-%{_target_platform}-%{version}-%{release}/ || :
+done
+tar cf - testlogs-%{_target_platform}-%{version}-%{release} | bzip2 -9c \
+  | uuencode testlogs-%{_target_platform}.tar.bz2 || :
+rm -rf testlogs-%{_target_platform}-%{version}-%{release}
 
 %clean
-rm -rf $RPM_BUILD_ROOT
+rm -rf %{buildroot}
 
 %post
 /sbin/install-info \
@@ -1164,7 +1210,7 @@ fi
 /sbin/install-info \
   --info-dir=%{_infodir} %{_infodir}/gnat_rm.info.gz || :
 /sbin/install-info \
-  --info-dir=%{_infodir} %{_infodir}/gnat_ugn_unw.info.gz || :
+  --info-dir=%{_infodir} %{_infodir}/gnat_ugn.info.gz || :
 /sbin/install-info \
   --info-dir=%{_infodir} %{_infodir}/gnat-style.info.gz || :
 
@@ -1173,7 +1219,7 @@ if [ $1 = 0 ]; then
   /sbin/install-info --delete \
     --info-dir=%{_infodir} %{_infodir}/gnat_rm.info.gz || :
   /sbin/install-info --delete \
-    --info-dir=%{_infodir} %{_infodir}/gnat_ugn_unw.info.gz || :
+    --info-dir=%{_infodir} %{_infodir}/gnat_ugn.info.gz || :
   /sbin/install-info --delete \
     --info-dir=%{_infodir} %{_infodir}/gnat-style.info.gz || :
 fi
@@ -1234,7 +1280,7 @@ fi
 %postun -n libmudflap -p /sbin/ldconfig
 
 %files -f %{name}.lang
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/cc
 %{_prefix}/bin/c89
 %{_prefix}/bin/c99
@@ -1357,7 +1403,7 @@ fi
 %doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog* gcc/COPYING*
 
 %files -n cpp -f cpplib.lang
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 /lib/cpp
 %{_prefix}/bin/cpp
 %{_mandir}/man1/cpp.1*
@@ -1368,14 +1414,14 @@ fi
 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1
 
 %files -n libgcc
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 /%{_lib}/libgcc_s-%{gcc_version}-%{DATE}.so.1
 /%{_lib}/libgcc_s.so.1
 %{_prefix}/sbin/libgcc_post_upgrade
 %doc gcc/COPYING.LIB
 
 %files c++
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/%{gcc_target_platform}-*++
 %{_prefix}/bin/g++
 %{_prefix}/bin/c++
@@ -1409,11 +1455,11 @@ fi
 %doc rpm.doc/changelogs/gcc/cp/ChangeLog*
 
 %files -n libstdc++
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libstdc++.so.6*
 
 %files -n libstdc++-devel
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/include/c++
 %dir %{_prefix}/include/c++/%{gcc_version}
 %{_prefix}/include/c++/%{gcc_version}/[^gjos]*
@@ -1437,10 +1483,17 @@ fi
 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libstdc++.so
 %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}/libsupc++.a
 %endif
-%doc rpm.doc/changelogs/libstdc++-v3/ChangeLog* libstdc++-v3/README* libstdc++-v3/doc/html/
+%doc rpm.doc/changelogs/libstdc++-v3/ChangeLog* libstdc++-v3/README*
 
-%files objc
+%if %{build_libstdcxx_docs}
+%files -n libstdc++-docs
 %defattr(-,root,root)
+%{_mandir}/man3/*
+%doc rpm.doc/libstdc++-v3/html
+%endif
+
+%files objc
+%defattr(-,root,root,-)
 %dir %{_prefix}/lib/gcc
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
@@ -1466,18 +1519,18 @@ fi
 %doc libobjc/THREADS* rpm.doc/changelogs/libobjc/ChangeLog*
 
 %files objc++
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/libexec/gcc
 %dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
 %dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}
 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/cc1objplus
 
 %files -n libobjc
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libobjc.so.2*
 
 %files gfortran
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/gfortran
 %{_prefix}/bin/f95
 %{_mandir}/man1/gfortran.1*
@@ -1512,12 +1565,12 @@ fi
 %doc rpm.doc/gfortran/*
 
 %files -n libgfortran
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libgfortran.so.3*
 
 %if %{build_java}
 %files java
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/gcj
 %{_prefix}/bin/gjavah
 %{_prefix}/bin/gcjh
@@ -1559,7 +1612,7 @@ fi
 %doc rpm.doc/changelogs/gcc/java/ChangeLog*
 
 %files -n libgcj
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/jv-convert
 %{_prefix}/bin/gij
 %{_prefix}/bin/gjar
@@ -1620,7 +1673,7 @@ fi
 %endif
 
 %files -n libgcj-devel
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/lib/gcc
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
@@ -1653,7 +1706,7 @@ fi
 %doc rpm.doc/libjava/*
 
 %files -n libgcj-src
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/share/java
 %{_prefix}/share/java/src*.zip
 %{_prefix}/share/java/libgcj-tools-%{version}.jar
@@ -1661,7 +1714,7 @@ fi
 
 %if %{build_ada}
 %files gnat
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/bin/gnat*
 %{_infodir}/gnat*
 %dir %{_prefix}/lib/gcc
@@ -1688,12 +1741,12 @@ fi
 %doc rpm.doc/changelogs/gcc/ada/ChangeLog*
 
 %files -n libgnat
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libgnat-*.so
 %{_prefix}/%{_lib}/libgnarl-*.so
 
 %files -n libgnat-devel
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/lib/gcc
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
@@ -1714,18 +1767,18 @@ fi
 %endif
 
 %files -n libgomp
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libgomp.so.1*
 %{_infodir}/libgomp.info*
 %doc rpm.doc/changelogs/libgomp/ChangeLog*
 
 %files -n libmudflap
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %{_prefix}/%{_lib}/libmudflap.so.0*
 %{_prefix}/%{_lib}/libmudflapth.so.0*
 
 %files -n libmudflap-devel
-%defattr(-,root,root)
+%defattr(-,root,root,-)
 %dir %{_prefix}/lib/gcc
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}
 %dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_version}
@@ -1750,6 +1803,68 @@ fi
 %doc rpm.doc/changelogs/libmudflap/ChangeLog*
 
 %changelog
+* Thu May 14 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-5
+- update from gcc-4_4-branch
+  - PRs c++/17395, c/39983, fortran/38863, fortran/38956, fortran/39879,
+	fortran/40018, libstdc++/39546, libstdc++/40038, middle-end/39986,
+	middle-end/40021, middle-end/40023, middle-end/40043,
+	middle-end/40057, middle-end/40080, target/37179,
+	tree-optimization/40062, tree-optimization/40074
+- fix Fortran FMT= character array arguments (#492209, PR fortran/39865)
+- allow putting breakpoints on Fortran END{SUBROUTINE,FUNCTION}
+  (PR fortran/34153)
+- incorporate changes suggested in gcc44 package review (#498911)
+
+* Wed May  6 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-4
+- update from gcc-4_4-branch
+  - PRs c++/40013, libgcj/39899, libstdc++/39868, libstdc++/39880,
+	libstdc++/39881, libstdc++/39882, libstdc++/39909, middle-end/39937,
+	rtl-optimization/39914, target/39565, testsuite/39769,
+	testsuite/39776, testsuite/39790, testsuite/39807,
+	tree-optimization/39941
+  - fix phiprop tuplification (#496400, PR tree-optimization/40022)
+- don't add artificial default case label if switch labels already
+  cover the whole range (PR middle-end/39666)
+- fix DSE with block reads (PR middle-end/40035)
+- fix debuginfo for C++ typedef struct {...} T (PR debug/35463)
+- remove some unnecessary padding on x86_64/i386 added for >= 4 control
+  flow insns in a 16-byte block (PR target/39942)
+- don't create invalid DWARF location lists containing DW_OP_reg*
+  followed by DW_OP_deref*, instead use DW_OP_breg* 0 (#481675)
+- add libstdc++-docs subpackage, move html manual to it, add doxygen
+  generated html and man pages
+
+* Mon Apr 27 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-3
+- update from gcc-4_4-branch
+  - PR bootstrap/39739
+  - fix -Wunused-value (#497545, PR c/39889)
+- backport further power7-meissner branch changes (#497816)
+- fix reg-stack ICE on SPEC2k6 453.povray with -m32 -O3 -msse3
+  (PR target/39856)
+- fix x86_64 ICE on passing structure with flexible array member
+  (PR target/39903)
+
+* Fri Apr 24 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-2
+- update from gcc-4_4-branch
+  - PR c++/38228
+- fix folding of cond expr with comparison to MAX/MIN (PR middle-end/39867)
+- fix up gcc-gnat install-info arguments (#452783)
+
+* Thu Apr 23 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-1
+- update from gcc-4_4-branch
+  - GCC 4.4.0 release
+  - PRs libstdc++/39802, c++/39639, c/39855, rtl-optimization/39762,
+	testsuite/39781, tree-optimization/39824
+- fix up DSE (PR rtl-optimization/39794)
+- debuginfo fixes for VLA and nested/contained functions (#459374)
+- improve -ftree-switch-conversion optimization if the constant is the
+  same in all cases
+
+* Mon Apr 20 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-0.35
+- update from gcc-4_4-branch
+  - PRs middle-end/39804, target/39678, target/39767, tree-optimization/39675,
+	tree-optimization/39764
+
 * Tue Apr 14 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-0.34
 - update from gcc-4_4-branch
   - GCC 4.4.0-rc1
@@ -1787,7 +1902,7 @@ fi
 	tree-optimization/39557
 - emit debuginfo for block local externs in C (PR debug/39563)
 - fix -maltivec conditional vector macro (PR target/39558)
-- teach fwprop to handle asm (PR rtl-optimization/39543)
+- teach fwprop to handle asm (PR inline-asm/39543)
 
 * Tue Mar 24 2009 Jakub Jelinek <jakub@redhat.com> 4.4.0-0.29
 - update from trunk
@@ -1824,7 +1939,7 @@ fi
 - fix memcmp builtin asm redirection (PR middle-end/39443)
 - fix sparcv9 profiledbootstrap (PR bootstrap/39454)
 
-* Thu Mar 12 2009 Dennis Gilmore <dennis@ausil.us> 
+* Thu Mar 12 2009 Dennis Gilmore <dennis@ausil.us>
 - don't build with graphite support on sparc arches
   - still missing some deps
 

diff --git a/gcc44-atom.patch b/gcc44-atom.patch
index e122e46..bddd13e 100644
--- a/gcc44-atom.patch
+++ b/gcc44-atom.patch
@@ -2409,7 +2409,7 @@
      | m_NOCONA | m_CORE2 | m_GENERIC;
  
  static enum stringop_alg stringop_alg = no_stringop;
-@@ -1952,7 +2038,8 @@ static const struct ptt processor_target
+@@ -1953,7 +2039,8 @@ static const struct ptt processor_target
    {&core2_cost, 16, 10, 16, 10, 16},
    {&generic32_cost, 16, 7, 16, 7, 16},
    {&generic64_cost, 16, 10, 16, 10, 16},
@@ -2419,7 +2419,7 @@
  };
  
  static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
-@@ -1970,6 +2057,7 @@ static const char *const cpu_names[TARGE
+@@ -1971,6 +2058,7 @@ static const char *const cpu_names[TARGE
    "prescott",
    "nocona",
    "core2",
@@ -2427,7 +2427,7 @@
    "geode",
    "k6",
    "k6-2",
-@@ -2528,6 +2616,9 @@ override_options (bool main_args_p)
+@@ -2529,6 +2617,9 @@ override_options (bool main_args_p)
        {"core2", PROCESSOR_CORE2, CPU_CORE2,
  	PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
  	| PTA_SSSE3 | PTA_CX16},
@@ -2437,7 +2437,7 @@
        {"geode", PROCESSOR_GEODE, CPU_GEODE,
  	PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
        {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
-@@ -12866,6 +12957,263 @@ ix86_expand_unary_operator (enum rtx_cod
+@@ -12903,6 +12994,263 @@ ix86_expand_unary_operator (enum rtx_cod
      emit_move_insn (operands[0], dst);
  }
  
@@ -2701,7 +2701,7 @@
  /* Return TRUE or FALSE depending on whether the unary operator meets the
     appropriate constraints.  */
  
-@@ -18985,6 +19333,7 @@ ix86_issue_rate (void)
+@@ -19022,6 +19370,7 @@ ix86_issue_rate (void)
    switch (ix86_tune)
      {
      case PROCESSOR_PENTIUM:
@@ -2709,7 +2709,7 @@
      case PROCESSOR_K6:
        return 2;
  
-@@ -19051,41 +19400,21 @@ ix86_flags_dependent (rtx insn, rtx dep_
+@@ -19088,41 +19437,21 @@ ix86_flags_dependent (rtx insn, rtx dep_
    return 1;
  }
  
@@ -2764,7 +2764,7 @@
  }
  
  static int
-@@ -19113,8 +19442,19 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19150,8 +19479,19 @@ ix86_adjust_cost (rtx insn, rtx link, rt
      {
      case PROCESSOR_PENTIUM:
        /* Address Generation Interlock adds a cycle of latency.  */
@@ -2786,7 +2786,7 @@
  
        /* ??? Compares pair with jump/setcc.  */
        if (ix86_flags_dependent (insn, dep_insn, insn_type))
-@@ -19123,7 +19463,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19160,7 +19500,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
        /* Floating point stores require value to be ready one cycle earlier.  */
        if (insn_type == TYPE_FMOV
  	  && get_attr_memory (insn) == MEMORY_STORE
@@ -2795,7 +2795,7 @@
  	cost += 1;
        break;
  
-@@ -19146,7 +19486,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19183,7 +19523,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
  	 in parallel with previous instruction in case
  	 previous instruction is not needed to compute the address.  */
        if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
@@ -2804,7 +2804,7 @@
  	{
  	  /* Claim moves to take one cycle, as core can issue one load
  	     at time and the next load can start cycle later.  */
-@@ -19175,7 +19515,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19212,7 +19552,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
  	 in parallel with previous instruction in case
  	 previous instruction is not needed to compute the address.  */
        if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
@@ -2813,7 +2813,7 @@
  	{
  	  /* Claim moves to take one cycle, as core can issue one load
  	     at time and the next load can start cycle later.  */
-@@ -19192,6 +19532,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19229,6 +19569,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
      case PROCESSOR_ATHLON:
      case PROCESSOR_K8:
      case PROCESSOR_AMDFAM10:
@@ -2821,7 +2821,7 @@
      case PROCESSOR_GENERIC32:
      case PROCESSOR_GENERIC64:
        memory = get_attr_memory (insn);
-@@ -19200,7 +19541,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
+@@ -19237,7 +19578,7 @@ ix86_adjust_cost (rtx insn, rtx link, rt
  	 in parallel with previous instruction in case
  	 previous instruction is not needed to compute the address.  */
        if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)

diff --git a/gcc44-libjava-i386.patch b/gcc44-libjava-i386.patch
deleted file mode 100644
index 8dad094..0000000
--- a/gcc44-libjava-i386.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -up ./libjava/configure.ac.sav ./libjava/configure.ac
---- ./libjava/configure.ac.sav	2009-04-03 14:56:35.000000000 -0400
-+++ ./libjava/configure.ac	2009-04-03 14:56:50.000000000 -0400
-@@ -1881,7 +1881,7 @@ then
-     case ${host} in
-       *-mingw* | *-cygwin*)
-         host_cpu=x86;;
--      i486-* | i586-* | i686-*)
-+      i386-* | i486-* | i586-* | i686-*)
-         host_cpu=i386;;
-       x86_64-*)
-         host_cpu=amd64;;
-diff -up ./libjava/configure.sav ./libjava/configure
---- ./libjava/configure.sav	2009-04-03 14:56:27.000000000 -0400
-+++ ./libjava/configure	2009-04-03 15:02:55.000000000 -0400
-@@ -28285,7 +28285,7 @@ echo "${ECHO_T}host is ${host}" >&6
-     case ${host} in
-       *-mingw* | *-cygwin*)
-         host_cpu=x86;;
--      i486-* | i586-* | i686-*)
-+      i386-* | i486-* | i586-* | i686-*)
-         host_cpu=i386;;
-       x86_64-*)
-         host_cpu=amd64;;

diff --git a/gcc44-libstdc++-docs.patch b/gcc44-libstdc++-docs.patch
new file mode 100644
index 0000000..45caafe
--- /dev/null
+++ b/gcc44-libstdc++-docs.patch
@@ -0,0 +1,47 @@
+--- libstdc++-v3/doc/html/index.html	2009-01-14 12:06:37.000000000 +0100
++++ libstdc++-v3/doc/html/index.html	2009-05-06 09:17:30.000000000 +0200
+@@ -12,7 +12,8 @@
+ <div>
+ <h1>The GNU C++ Library Documentation</h1>
+ 
+-<p>Copyright 2008 FSF</p>
++<p>Release 4.4.0</p>
++<p>Copyright 2008, 2009 FSF</p>
+ 
+ <p>
+   Permission is granted to copy, distribute and/or modify this
+--- libstdc++-v3/doc/html/api.html	2009-04-20 21:21:15.000000000 +0200
++++ libstdc++-v3/doc/html/api.html	2009-05-06 09:17:24.000000000 +0200
+@@ -17,27 +17,12 @@ useful for examining the signatures of p
+ the library classes, finding out what is in a particular include
+ file, looking at inheritance diagrams, etc.
+ </p><p>
+-The source-level documentation for the most recent releases can be
+-viewed online:
+-</p><div class="itemizedlist"><ul type="disc"><li><p>
+-      <a class="ulink" href="libstdc++-html-USERS-3.4/index.html" target="_top">for the 3.4 release
++The source-level documentation can be viewed here:
++</p>
++<div class="itemizedlist"><ul type="disc">
++    <li><p>
++      <a class="ulink" href="api/index.html" target="_top">for the 4.4 release
+       </a>
+-    </p></li><li><p>
+-      <a class="ulink" href="libstdc++-html-USERS-4.1/index.html" target="_top">for the 4.1 release
+-      </a>
+-    </p></li><li><p>
+-      <a class="ulink" href="libstdc++-html-USERS-4.2/index.html" target="_top">for the 4.2 release
+-      </a>
+-    </p></li><li><p>
+-      <a class="ulink" href="libstdc++-html-USERS-4.3/index.html" target="_top">for the 4.3 release
+-      </a>
+-    </p></li><li><p>
+-      <a class="ulink" href="libstdc++-html-USERS-4.4/index.html" target="_top">for the 4.4 release
+-      </a>
+-    </p></li><li><p>
+-      <a class="ulink" href="latest-doxygen/index.html" target="_top">"the latest collection"
+-      </a>
+-      (For the main development tree; see the date on the first page.)
+     </p></li></ul></div><p>
+ This generated HTML collection, as above, is also available for download in the libstdc++ snapshots directory at
+    <code class="literal">&lt;URL:ftp://gcc.gnu.org/pub/gcc/libstdc++/doxygen/&gt;</code>.

diff --git a/gcc44-power7-2.patch b/gcc44-power7-2.patch
new file mode 100644
index 0000000..a296217
--- /dev/null
+++ b/gcc44-power7-2.patch
@@ -0,0 +1,267 @@
+2009-04-14  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	* config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Handle
+	more possible combinations of addresses.
+
+	* config/rs6000/vector.md (vec_reload_and_plus_<mptrsize>): Allow
+	register+small constant in addition to register+register, and
+	restrict the insn to only match during reload and afterwards.
+	(vec_reload_and_reg_<mptrsize>): Allow for and of register
+	indirect to not generate insn not found message.
+
+--- gcc/config/rs6000/vector.md	(revision 146069)
++++ gcc/config/rs6000/vector.md	(revision 146118)
+@@ -129,14 +129,15 @@ (define_expand "reload_<VEC_R:mode>_<P:m
+ })
+ 
+ ;; Reload sometimes tries to move the address to a GPR, and can generate
+-;; invalid RTL for addresses involving AND -16.
++;; invalid RTL for addresses involving AND -16.  Allow addresses involving
++;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
+ 
+ (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
+   [(set (match_operand:P 0 "gpc_reg_operand" "=b")
+ 	(and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
+-		       (match_operand:P 2 "gpc_reg_operand" "r"))
++		       (match_operand:P 2 "reg_or_cint_operand" "rI"))
+ 	       (const_int -16)))]
+-  "TARGET_ALTIVEC || TARGET_VSX"
++  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
+   "#"
+   "&& reload_completed"
+   [(set (match_dup 0)
+@@ -146,6 +147,21 @@ (define_insn_and_split "*vec_reload_and_
+ 		   (and:P (match_dup 0)
+ 			  (const_int -16)))
+ 	      (clobber:CC (scratch:CC))])])
++
++;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16
++;; address to a register because there is no clobber of a (scratch), so we add
++;; it here.
++(define_insn_and_split "*vec_reload_and_reg_<mptrsize>"
++  [(set (match_operand:P 0 "gpc_reg_operand" "=b")
++	(and:P (match_operand:P 1 "gpc_reg_operand" "r")
++	       (const_int -16)))]
++  "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
++  "#"
++  "&& reload_completed"
++  [(parallel [(set (match_dup 0)
++		   (and:P (match_dup 1)
++			  (const_int -16)))
++	      (clobber:CC (scratch:CC))])])
+ \f
+ ;; Generic floating point vector arithmetic support
+ (define_expand "add<mode>3"
+--- gcc/config/rs6000/rs6000.c	(revision 146069)
++++ gcc/config/rs6000/rs6000.c	(revision 146118)
+@@ -12574,6 +12574,11 @@ rs6000_secondary_reload_inner (rtx reg, 
+   enum reg_class rclass;
+   rtx addr;
+   rtx and_op2 = NULL_RTX;
++  rtx addr_op1;
++  rtx addr_op2;
++  rtx scratch_or_premodify = scratch;
++  rtx and_rtx;
++  rtx cc_clobber;
+ 
+   if (TARGET_DEBUG_ADDR)
+     {
+@@ -12595,7 +12600,8 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 
+   switch (rclass)
+     {
+-      /* Move reg+reg addresses into a scratch register for GPRs.  */
++      /* GPRs can handle reg + small constant, all other addresses need to use
++	 the scratch register.  */
+     case GENERAL_REGS:
+     case BASE_REGS:
+       if (GET_CODE (addr) == AND)
+@@ -12603,70 +12609,152 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 	  and_op2 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
++
++      if (GET_CODE (addr) == PRE_MODIFY)
++	{
++	  scratch_or_premodify = XEXP (addr, 0);
++	  gcc_assert (REG_P (scratch_or_premodify));
++	  gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
++	  addr = XEXP (addr, 1);
++	}
++
+       if (GET_CODE (addr) == PLUS
+ 	  && (!rs6000_legitimate_offset_address_p (TImode, addr, true)
+ 	      || and_op2 != NULL_RTX))
+ 	{
+-	  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
+-	      || GET_CODE (addr) == CONST_INT)
+-	    rs6000_emit_move (scratch, addr, GET_MODE (addr));
+-	  else
+-	    emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
+-	  addr = scratch;
++	  addr_op1 = XEXP (addr, 0);
++	  addr_op2 = XEXP (addr, 1);
++	  gcc_assert (legitimate_indirect_address_p (addr_op1, true));
++
++	  if (!REG_P (addr_op2)
++	      && (GET_CODE (addr_op2) != CONST_INT
++		  || !satisfies_constraint_I (addr_op2)))
++	    {
++	      rs6000_emit_move (scratch, addr_op2, Pmode);
++	      addr_op2 = scratch;
++	    }
++
++	  emit_insn (gen_rtx_SET (VOIDmode,
++				  scratch_or_premodify,
++				  gen_rtx_PLUS (Pmode,
++						addr_op1,
++						addr_op2)));
++
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
+ 	}
+-      else if (GET_CODE (addr) == PRE_MODIFY
+-	       && REG_P (XEXP (addr, 0))
+-	       && GET_CODE (XEXP (addr, 1)) == PLUS)
++      else if (!legitimate_indirect_address_p (addr, true)
++	       && !rs6000_legitimate_offset_address_p (TImode, addr, true))
+ 	{
+-	  emit_insn (gen_rtx_SET (VOIDmode, XEXP (addr, 0), XEXP (addr, 1)));
+-	  addr = XEXP (addr, 0);
++	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
+ 	}
+       break;
+ 
++      /* Float/Altivec registers can only handle reg+reg addressing.  Move
++	 other addresses into a scratch register.  */
++    case FLOAT_REGS:
++    case VSX_REGS:
++    case ALTIVEC_REGS:
++
+       /* With float regs, we need to handle the AND ourselves, since we can't
+ 	 use the Altivec instruction with an implicit AND -16.  Allow scalar
+ 	 loads to float registers to use reg+offset even if VSX.  */
+-    case FLOAT_REGS:
+-    case VSX_REGS:
+-      if (GET_CODE (addr) == AND)
++      if (GET_CODE (addr) == AND
++	  && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16))
+ 	{
+ 	  and_op2 = XEXP (addr, 1);
+ 	  addr = XEXP (addr, 0);
+ 	}
+-      /* fall through */
+ 
+-      /* Move reg+offset addresses into a scratch register.  */
+-    case ALTIVEC_REGS:
+-      if (!legitimate_indirect_address_p (addr, true)
+-	  && !legitimate_indexed_address_p (addr, true)
+-	  && (GET_CODE (addr) != PRE_MODIFY
+-	      || !legitimate_indexed_address_p (XEXP (addr, 1), true))
+-	  && (rclass != FLOAT_REGS
+-	      || GET_MODE_SIZE (mode) != 8
++      /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
++	 as the address later.  */
++      if (GET_CODE (addr) == PRE_MODIFY
++	  && (!VECTOR_MEM_VSX_P (mode)
+ 	      || and_op2 != NULL_RTX
+-	      || !rs6000_legitimate_offset_address_p (mode, addr, true)))
++	      || !legitimate_indexed_address_p (XEXP (addr, 1), true)))
+ 	{
+-	  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
+-	      || GET_CODE (addr) == CONST_INT)
+-	    rs6000_emit_move (scratch, addr, GET_MODE (addr));
+-	  else
+-	    emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
+-	  addr = scratch;
++	  scratch_or_premodify = XEXP (addr, 0);
++	  gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
++						     true));
++	  gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
++	  addr = XEXP (addr, 1);
++	}
++
++      if (legitimate_indirect_address_p (addr, true)	/* reg */
++	  || legitimate_indexed_address_p (addr, true)	/* reg+reg */
++	  || GET_CODE (addr) == PRE_MODIFY		/* VSX pre-modify */
++	  || GET_CODE (addr) == AND			/* Altivec memory */
++	  || (rclass == FLOAT_REGS			/* legacy float mem */
++	      && GET_MODE_SIZE (mode) == 8
++	      && and_op2 == NULL_RTX
++	      && scratch_or_premodify == scratch
++	      && rs6000_legitimate_offset_address_p (mode, addr, true)))
++	;
++
++      else if (GET_CODE (addr) == PLUS)
++	{
++	  addr_op1 = XEXP (addr, 0);
++	  addr_op2 = XEXP (addr, 1);
++	  gcc_assert (REG_P (addr_op1));
++
++	  rs6000_emit_move (scratch, addr_op2, Pmode);
++	  emit_insn (gen_rtx_SET (VOIDmode,
++				  scratch_or_premodify,
++				  gen_rtx_PLUS (Pmode,
++						addr_op1,
++						scratch)));
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
+ 	}
++
++      else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
++	       || GET_CODE (addr) == CONST_INT)
++	{
++	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
++	  addr = scratch_or_premodify;
++	  scratch_or_premodify = scratch;
++	}
++
++      else
++	gcc_unreachable ();
++
+       break;
+ 
+     default:
+       gcc_unreachable ();
+     }
+ 
+-  /* If the original address involved an AND -16 that is part of the Altivec
+-     addresses, recreate the and now.  */
++  /* If the original address involved a pre-modify that we couldn't use the VSX
++     memory instruction with update, and we haven't taken care of already,
++     store the address in the pre-modify register and use that as the
++     address.  */
++  if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
++    {
++      emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
++      addr = scratch_or_premodify;
++    }
++
++  /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
++     memory instruction, recreate the AND now, including the clobber which is
++     generated by the general ANDSI3/ANDDI3 patterns for the
++     andi. instruction.  */
+   if (and_op2 != NULL_RTX)
+     {
+-      rtx and_rtx = gen_rtx_SET (VOIDmode,
+-				 scratch,
+-				 gen_rtx_AND (Pmode, addr, and_op2));
+-      rtx cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
++      if (! legitimate_indirect_address_p (addr, true))
++	{
++	  emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
++	  addr = scratch;
++	}
++
++      and_rtx = gen_rtx_SET (VOIDmode,
++			     scratch,
++			     gen_rtx_AND (Pmode,
++					  addr,
++					  and_op2));
++
++      cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
+       emit_insn (gen_rtx_PARALLEL (VOIDmode,
+ 				   gen_rtvec (2, and_rtx, cc_clobber)));
+       addr = scratch;

diff --git a/gcc44-power7-3.patch b/gcc44-power7-3.patch
new file mode 100644
index 0000000..ef81e03
--- /dev/null
+++ b/gcc44-power7-3.patch
@@ -0,0 +1,3523 @@
+2009-04-26  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	* config/rs6000/vector.md (vector_vsel<mode>): Generate the insns
+	directly instead of calling VSX/Altivec expanders.
+
+	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Map VSX
+	builtins that are identical to Altivec, to the Altivec vesion.
+	(altivec_overloaded_builtins): Add V2DF/V2DI sel, perm support.
+	(altivec_resolve_overloaded_builtin): Add V2DF/V2DI support.
+
+	* config/rs6000/rs6000.c (rs6000_expand_vector_init): Rename VSX
+	splat functions.
+	(expand_vector_set): Merge V2DF/V2DI code.
+	(expand_vector_extract): Ditto.
+	(bdesc_3arg): Add more VSX builtins.
+	(bdesc_2arg): Ditto.
+	(bdesc_1arg): Ditto.
+	(rs6000_expand_ternop_builtin): Require xxpermdi 3rd argument to
+	be 2 bit-constant, and V2DF/V2DI set to be a 1 bit-constant.
+	(altivec_expand_builtin): Add support for VSX overloaded builtins.
+	(altivec_init_builtins): Ditto.
+	(rs6000_common_init_builtins): Ditto.
+	(rs6000_init_builtins): Add V2DI types and vector long support.
+	(rs6000_handle_altivec_attribute): Ditto.
+	(rs6000_mange_type): Ditto.
+
+	* config/rs6000/vsx.md (UNSPEC_*): Add new UNSPEC constants.
+	(vsx_vsel<mode>): Add support for all vector types, including
+	Altivec types.
+	(vsx_ftrunc<mode>2): Emit the correct instruction.
+	(vsx_x<VSv>r<VSs>i): New builtin rounding mode insns.
+	(vsx_x<VSv>r<VSs>ic): Ditto.
+	(vsx_concat_<mode>): Key off of VSX memory instructions being
+	generated instead of the vector arithmetic unit to enable V2DI
+	mode.
+	(vsx_extract_<mode>): Ditto.
+	(vsx_set_<mode>): Rewrite as an unspec.
+	(vsx_xxpermdi2_<mode>): Rename old vsx_xxpermdi_<mode> here.  Key
+	off of VSX memory instructions instead of arithmetic unit.
+	(vsx_xxpermdi_<mode>): New insn for __builtin_vsx_xxpermdi.
+	(vsx_splat_<mode>): Rename from vsx_splat<mode>.
+	(vsx_xxspltw_<mode>): Change from V4SF only to V4SF/V4SI modes.
+	Fix up constraints.  Key off of memory instructions instead of
+	arithmetic instructions to allow use with V4SI.
+	(vsx_xxmrghw_<mode>): Ditto.
+	(vsx_xxmrglw_<mode>): Ditto.
+	(vsx_xxsldwi_<mode>): Implement vector shift double by word
+	immediate.
+
+	* config/rs6000/rs6000.h (VSX_BUILTIN_*): Update for current
+	builtins being generated.
+	(RS6000_BTI_unsigned_V2DI): Add vector long support.
+	(RS6000_BTI_bool_long): Ditto.
+	(RS6000_BTI_bool_V2DI): Ditto.
+	(unsigned_V2DI_type_node): Ditto.
+	(bool_long_type_node): Ditto.
+	(bool_V2DI_type_node): Ditto.
+
+	* config/rs6000/altivec.md (altivec_vsel<mode>): Add '*' since we
+	don't need the generator function now.  Use VSX instruction if
+	-mvsx.
+	(altivec_vmrghw): Use VSX instruction if -mvsx.
+	(altivec_vmrghsf): Ditto.
+	(altivec_vmrglw): Ditto.
+	(altivec_vmrglsf): Ditto.
+
+	* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions):
+	Document that under VSX, vector double/long are available.
+
+testsuite/
+	* gcc.target/powerpc/vsx-builtin-3.c: New test for VSX builtins.
+
+2009-04-23  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	* config/rs6000/vector.md (VEC_E): New iterator to add V2DImode.
+	(vec_init<mode>): Use VEC_E instead of VEC_C iterator, to add
+	V2DImode support.
+	(vec_set<mode>): Ditto.
+	(vec_extract<mode>): Ditto.
+
+	* config/rs6000/predicates.md (easy_vector_constant): Add support
+	for setting TImode to 0.
+
+	* config/rs6000/rs6000.opt (-mvsx-vector-memory): Delete old debug
+	switch that is no longer used.
+	(-mvsx-vector-float): Ditto.
+	(-mvsx-vector-double): Ditto.
+	(-mvsx-v4sf-altivec-regs): Ditto.
+	(-mreload-functions): Ditto.
+	(-mallow-timode): New debug switch.
+
+	* config/rs6000/rs6000.c (rs6000_ira_cover_classes): New target
+	hook for IRA cover classes, to know that under VSX the float and
+	altivec registers are part of the same register class, but before
+	they weren't.
+	(TARGET_IRA_COVER_CLASSES): Set ira cover classes target hookd.
+	(rs6000_hard_regno_nregs): Key off of whether VSX/Altivec memory
+	instructions are supported, and not whether the vector unit has
+	arithmetic support to enable V2DI/TI mode.
+	(rs6000_hard_regno_mode_ok): Ditto.
+	(rs6000_init_hard_regno_mode_ok): Add V2DImode, TImode support.
+	Drop several of the debug switches.
+	(rs6000_emit_move): Force TImode constants to memory if we have
+	either Altivec or VSX.
+	(rs6000_builtin_conversion): Use correct insns for V2DI<->V2DF
+	conversions.
+	(rs6000_expand_vector_init): Add V2DI support.
+	(rs6000_expand_vector_set): Ditto.
+	(avoiding_indexed_address_p): Simplify tests to say if the mode
+	uses VSX/Altivec memory instructions we can't eliminate reg+reg
+	addressing.
+	(rs6000_legitimize_address): Move VSX/Altivec REG+REG support
+	before the large integer support.
+	(rs6000_legitimate_address): Add support for TImode in VSX/Altivec
+	registers.
+	(rs6000_emit_move): Ditto.
+	(def_builtin): Change internal error message to provide more
+	information.
+	(bdesc_2arg): Add conversion builtins.
+	(builtin_hash_function): New function for hashing all of the types
+	for builtin functions.
+	(builtin_hash_eq): Ditto.
+	(builtin_function_type): Ditto.
+	(builtin_mode_to_type): New static for builtin argument hashing.
+	(builtin_hash_table): Ditto.
+	(rs6000_common_init_builtins): Rewrite so that types for builtin
+	functions are only created when we need them, and use a hash table
+	to store all of the different argument combinations that are
+	created.  Add support for VSX conversion builtins.
+	(rs6000_preferred_reload_class): Add TImode support.
+	(reg_classes_cannot_change_mode_class): Be stricter about VSX and
+	Altivec vector types.
+	(rs6000_emit_vector_cond_expr): Use VSX_MOVE_MODE, not
+	VSX_VECTOR_MOVE_MODE.
+	(rs6000_handle_altivec_attribute): Allow __vector long on VSX.
+
+	* config/rs6000/vsx.md (VSX_D): New iterator for vectors with
+	64-bit elements.
+	(VSX_M): New iterator for 128 bit types for moves, except for
+	TImode.
+	(VSm, VSs, VSr): Add TImode.
+	(VSr4, VSr5): New mode attributes for float<->double conversion.
+	(VSX_SPDP): New iterator for float<->double conversion.
+	(VS_spdp_*): New mode attributes for float<->double conversion.
+	(UNSPEC_VSX_*): Rename unspec constants to remove XV from the
+	names.  Change all users.
+	(vsx_mov<mode>): Drop TImode support here.
+	(vsx_movti): New TImode support, allow GPRs, but favor VSX
+	registers.
+	(vsx_<VS_spdp_insn>): New support for float<->double conversions.
+	(vsx_xvcvdpsp): Delete, move into vsx_<VS_spdp_insn>.
+	(vsx_xvcvspdp): Ditto.
+	(vsx_xvcvuxdsp): New conversion insn.
+	(vsx_xvcvspsxds): Ditto.
+	(vsx_xvcvspuxds): Ditto.
+	(vsx_concat_<mode>): Generalize V2DF permute/splat operations to
+	include V2DI.
+	(vsx_set_<mode>): Ditto.
+	(vsx_extract_<mode>): Ditto.
+	(vsx_xxpermdi_<mode>): Ditto.
+	(vsx_splat<mode>): Ditto.
+
+	* config/rs6000/rs6000.h (VSX_VECTOR_MOVE_MODE): Delete.
+	(VSX_MOVE_MODE): Add TImode.
+	(IRA_COVER_CLASSES): Delete.
+	(IRA_COVER_CLASSES_PRE_VSX): New cover classes for machines
+	without VSX where float and altivec are different registers.
+	(IRA_COVER_CLASS_VSX): New cover classes for machines with VSX
+	where float and altivec are part of the same register class.
+
+	* config/rs6000/altivec.md (VM2): New iterator for 128-bit types,
+	except TImode.
+	(altivec_mov<mode>): Drop movti mode here.
+	(altivec_movti): Add movti insn, and allow GPRs, but favor altivec
+	registers.
+
+2009-04-16  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+	* config/rs6000/rs6000-protos.h (rs6000_has_indirect_jump_p): New
+	declaration.
+	(rs6000_set_indirect_jump): Ditto.
+
+	* config/rs6000/rs6000.c (struct machine_function): Add
+	indirect_jump_p field.
+	(rs6000_override_options): Wrap warning messages in N_().  If
+	-mvsx was implicitly set, don't give a warning for -msoft-float,
+	just silently turn off vsx.
+	(rs6000_secondary_reload_inner): Don't use strict register
+	checking, since pseudos may still be present.
+	(register_move_cost): If -mdebug=cost, print out cost information.
+	(rs6000_memory_move_cost): Ditto.
+	(rs6000_has_indirect_jump_p): New function, return true if
+	current function has an indirect jump.
+	(rs6000_set_indirect_jump): New function, note that an indirect
+	jump has been generated.
+
+	* config/rs6000/rs6000.md (indirect_jump): Note that we've
+	generated an indirect jump.
+	(tablejump): Ditto.
+	(doloop_end): Do not generate decrement ctr and branch
+	instructions if an indirect jump has been generated.
+
+--- gcc/doc/extend.texi	(revision 146119)
++++ gcc/doc/extend.texi	(revision 146798)
+@@ -7094,7 +7094,7 @@ instructions, but allow the compiler to 
+ * MIPS Loongson Built-in Functions::
+ * Other MIPS Built-in Functions::
+ * picoChip Built-in Functions::
+-* PowerPC AltiVec Built-in Functions::
++* PowerPC AltiVec/VSX Built-in Functions::
+ * SPARC VIS Built-in Functions::
+ * SPU Built-in Functions::
+ @end menu
+@@ -9571,7 +9571,7 @@ GCC defines the preprocessor macro @code
+ when this function is available.
+ @end table
+ 
+-@node PowerPC AltiVec Built-in Functions
++@node PowerPC AltiVec/VSX Built-in Functions
+ @subsection PowerPC AltiVec Built-in Functions
+ 
+ GCC provides an interface for the PowerPC family of processors to access
+@@ -9597,6 +9597,19 @@ vector bool int
+ vector float
+ @end smallexample
+ 
++If @option{-mvsx} is used the following additional vector types are
++implemented.
++
++@smallexample
++vector unsigned long
++vector signed long
++vector double
++@end smallexample
++
++The long types are only implemented for 64-bit code generation, and
++the long type is only used in the floating point/integer conversion
++instructions.
++
+ GCC's implementation of the high-level language interface available from
+ C and C++ code differs from Motorola's documentation in several ways.
+ 
+--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c	(revision 0)
++++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c	(revision 146798)
+@@ -0,0 +1,212 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_vsx_ok } */
++/* { dg-options "-O2 -mcpu=power7" } */
++/* { dg-final { scan-assembler "xxsel" } } */
++/* { dg-final { scan-assembler "vperm" } } */
++/* { dg-final { scan-assembler "xvrdpi" } } */
++/* { dg-final { scan-assembler "xvrdpic" } } */
++/* { dg-final { scan-assembler "xvrdpim" } } */
++/* { dg-final { scan-assembler "xvrdpip" } } */
++/* { dg-final { scan-assembler "xvrdpiz" } } */
++/* { dg-final { scan-assembler "xvrspi" } } */
++/* { dg-final { scan-assembler "xvrspic" } } */
++/* { dg-final { scan-assembler "xvrspim" } } */
++/* { dg-final { scan-assembler "xvrspip" } } */
++/* { dg-final { scan-assembler "xvrspiz" } } */
++/* { dg-final { scan-assembler "xsrdpi" } } */
++/* { dg-final { scan-assembler "xsrdpic" } } */
++/* { dg-final { scan-assembler "xsrdpim" } } */
++/* { dg-final { scan-assembler "xsrdpip" } } */
++/* { dg-final { scan-assembler "xsrdpiz" } } */
++/* { dg-final { scan-assembler "xsmaxdp" } } */
++/* { dg-final { scan-assembler "xsmindp" } } */
++/* { dg-final { scan-assembler "xxland" } } */
++/* { dg-final { scan-assembler "xxlandc" } } */
++/* { dg-final { scan-assembler "xxlnor" } } */
++/* { dg-final { scan-assembler "xxlor" } } */
++/* { dg-final { scan-assembler "xxlxor" } } */
++/* { dg-final { scan-assembler "xvcmpeqdp" } } */
++/* { dg-final { scan-assembler "xvcmpgtdp" } } */
++/* { dg-final { scan-assembler "xvcmpgedp" } } */
++/* { dg-final { scan-assembler "xvcmpeqsp" } } */
++/* { dg-final { scan-assembler "xvcmpgtsp" } } */
++/* { dg-final { scan-assembler "xvcmpgesp" } } */
++/* { dg-final { scan-assembler "xxsldwi" } } */
++/* { dg-final { scan-assembler-not "call" } } */
++
++extern __vector int si[][4];
++extern __vector short ss[][4];
++extern __vector signed char sc[][4];
++extern __vector float f[][4];
++extern __vector unsigned int ui[][4];
++extern __vector unsigned short us[][4];
++extern __vector unsigned char uc[][4];
++extern __vector __bool int bi[][4];
++extern __vector __bool short bs[][4];
++extern __vector __bool char bc[][4];
++extern __vector __pixel p[][4];
++#ifdef __VSX__
++extern __vector double d[][4];
++extern __vector long sl[][4];
++extern __vector unsigned long ul[][4];
++extern __vector __bool long bl[][4];
++#endif
++
++int do_sel(void)
++{
++  int i = 0;
++
++  si[i][0] = __builtin_vsx_xxsel_4si (si[i][1], si[i][2], si[i][3]); i++;
++  ss[i][0] = __builtin_vsx_xxsel_8hi (ss[i][1], ss[i][2], ss[i][3]); i++;
++  sc[i][0] = __builtin_vsx_xxsel_16qi (sc[i][1], sc[i][2], sc[i][3]); i++;
++  f[i][0] = __builtin_vsx_xxsel_4sf (f[i][1], f[i][2], f[i][3]); i++;
++  d[i][0] = __builtin_vsx_xxsel_2df (d[i][1], d[i][2], d[i][3]); i++;
++
++  si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], bi[i][3]); i++;
++  ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], bs[i][3]); i++;
++  sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], bc[i][3]); i++;
++  f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], bi[i][3]); i++;
++  d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], bl[i][3]); i++;
++
++  si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], ui[i][3]); i++;
++  ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], us[i][3]); i++;
++  sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], uc[i][3]); i++;
++  f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], ui[i][3]); i++;
++  d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], ul[i][3]); i++;
++
++  return i;
++}
++
++int do_perm(void)
++{
++  int i = 0;
++
++  si[i][0] = __builtin_vsx_vperm_4si (si[i][1], si[i][2], sc[i][3]); i++;
++  ss[i][0] = __builtin_vsx_vperm_8hi (ss[i][1], ss[i][2], sc[i][3]); i++;
++  sc[i][0] = __builtin_vsx_vperm_16qi (sc[i][1], sc[i][2], sc[i][3]); i++;
++  f[i][0] = __builtin_vsx_vperm_4sf (f[i][1], f[i][2], sc[i][3]); i++;
++  d[i][0] = __builtin_vsx_vperm_2df (d[i][1], d[i][2], sc[i][3]); i++;
++
++  si[i][0] = __builtin_vsx_vperm (si[i][1], si[i][2], uc[i][3]); i++;
++  ss[i][0] = __builtin_vsx_vperm (ss[i][1], ss[i][2], uc[i][3]); i++;
++  sc[i][0] = __builtin_vsx_vperm (sc[i][1], sc[i][2], uc[i][3]); i++;
++  f[i][0] = __builtin_vsx_vperm (f[i][1], f[i][2], uc[i][3]); i++;
++  d[i][0] = __builtin_vsx_vperm (d[i][1], d[i][2], uc[i][3]); i++;
++
++  return i;
++}
++
++int do_xxperm (void)
++{
++  int i = 0;
++
++  d[i][0] = __builtin_vsx_xxpermdi_2df (d[i][1], d[i][2], 0); i++;
++  d[i][0] = __builtin_vsx_xxpermdi (d[i][1], d[i][2], 1); i++;
++  return i;
++}
++
++double x, y;
++void do_concat (void)
++{
++  d[0][0] = __builtin_vsx_concat_2df (x, y);
++}
++
++void do_set (void)
++{
++  d[0][0] = __builtin_vsx_set_2df (d[0][1], x, 0);
++  d[1][0] = __builtin_vsx_set_2df (d[1][1], y, 1);
++}
++
++extern double z[][4];
++
++int do_math (void)
++{
++  int i = 0;
++
++  d[i][0] = __builtin_vsx_xvrdpi  (d[i][1]); i++;
++  d[i][0] = __builtin_vsx_xvrdpic (d[i][1]); i++;
++  d[i][0] = __builtin_vsx_xvrdpim (d[i][1]); i++;
++  d[i][0] = __builtin_vsx_xvrdpip (d[i][1]); i++;
++  d[i][0] = __builtin_vsx_xvrdpiz (d[i][1]); i++;
++
++  f[i][0] = __builtin_vsx_xvrspi  (f[i][1]); i++;
++  f[i][0] = __builtin_vsx_xvrspic (f[i][1]); i++;
++  f[i][0] = __builtin_vsx_xvrspim (f[i][1]); i++;
++  f[i][0] = __builtin_vsx_xvrspip (f[i][1]); i++;
++  f[i][0] = __builtin_vsx_xvrspiz (f[i][1]); i++;
++
++  z[i][0] = __builtin_vsx_xsrdpi  (z[i][1]); i++;
++  z[i][0] = __builtin_vsx_xsrdpic (z[i][1]); i++;
++  z[i][0] = __builtin_vsx_xsrdpim (z[i][1]); i++;
++  z[i][0] = __builtin_vsx_xsrdpip (z[i][1]); i++;
++  z[i][0] = __builtin_vsx_xsrdpiz (z[i][1]); i++;
++  z[i][0] = __builtin_vsx_xsmaxdp (z[i][1], z[i][0]); i++;
++  z[i][0] = __builtin_vsx_xsmindp (z[i][1], z[i][0]); i++;
++  return i;
++}
++
++int do_cmp (void)
++{
++  int i = 0;
++
++  d[i][0] = __builtin_vsx_xvcmpeqdp (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xvcmpgtdp (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xvcmpgedp (d[i][1], d[i][2]); i++;
++
++  f[i][0] = __builtin_vsx_xvcmpeqsp (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xvcmpgtsp (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xvcmpgesp (f[i][1], f[i][2]); i++;
++  return i;
++}
++
++int do_logical (void)
++{
++  int i = 0;
++
++  si[i][0] = __builtin_vsx_xxland (si[i][1], si[i][2]); i++;
++  si[i][0] = __builtin_vsx_xxlandc (si[i][1], si[i][2]); i++;
++  si[i][0] = __builtin_vsx_xxlnor (si[i][1], si[i][2]); i++;
++  si[i][0] = __builtin_vsx_xxlor (si[i][1], si[i][2]); i++;
++  si[i][0] = __builtin_vsx_xxlxor (si[i][1], si[i][2]); i++;
++
++  ss[i][0] = __builtin_vsx_xxland (ss[i][1], ss[i][2]); i++;
++  ss[i][0] = __builtin_vsx_xxlandc (ss[i][1], ss[i][2]); i++;
++  ss[i][0] = __builtin_vsx_xxlnor (ss[i][1], ss[i][2]); i++;
++  ss[i][0] = __builtin_vsx_xxlor (ss[i][1], ss[i][2]); i++;
++  ss[i][0] = __builtin_vsx_xxlxor (ss[i][1], ss[i][2]); i++;
++
++  sc[i][0] = __builtin_vsx_xxland (sc[i][1], sc[i][2]); i++;
++  sc[i][0] = __builtin_vsx_xxlandc (sc[i][1], sc[i][2]); i++;
++  sc[i][0] = __builtin_vsx_xxlnor (sc[i][1], sc[i][2]); i++;
++  sc[i][0] = __builtin_vsx_xxlor (sc[i][1], sc[i][2]); i++;
++  sc[i][0] = __builtin_vsx_xxlxor (sc[i][1], sc[i][2]); i++;
++
++  d[i][0] = __builtin_vsx_xxland (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xxlandc (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xxlnor (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xxlor (d[i][1], d[i][2]); i++;
++  d[i][0] = __builtin_vsx_xxlxor (d[i][1], d[i][2]); i++;
++
++  f[i][0] = __builtin_vsx_xxland (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xxlandc (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xxlnor (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xxlor (f[i][1], f[i][2]); i++;
++  f[i][0] = __builtin_vsx_xxlxor (f[i][1], f[i][2]); i++;
++  return i;
++}
++
++int do_xxsldwi (void)
++{
++  int i = 0;
++
++  si[i][0] = __builtin_vsx_xxsldwi (si[i][1], si[i][2], 0); i++;
++  ss[i][0] = __builtin_vsx_xxsldwi (ss[i][1], ss[i][2], 1); i++;
++  sc[i][0] = __builtin_vsx_xxsldwi (sc[i][1], sc[i][2], 2); i++;
++  ui[i][0] = __builtin_vsx_xxsldwi (ui[i][1], ui[i][2], 3); i++;
++  us[i][0] = __builtin_vsx_xxsldwi (us[i][1], us[i][2], 0); i++;
++  uc[i][0] = __builtin_vsx_xxsldwi (uc[i][1], uc[i][2], 1); i++;
++  f[i][0] = __builtin_vsx_xxsldwi (f[i][1], f[i][2], 2); i++;
++  d[i][0] = __builtin_vsx_xxsldwi (d[i][1], d[i][2], 3); i++;
++  return i;
++}
+--- gcc/config/rs6000/vector.md	(revision 146119)
++++ gcc/config/rs6000/vector.md	(revision 146798)
+@@ -39,6 +39,9 @@ (define_mode_iterator VEC_M [V16QI V8HI 
+ ;; Vector comparison modes
+ (define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF])
+ 
++;; Vector init/extract modes
++(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF])
++
+ ;; Vector reload iterator
+ (define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI])
+ 
+@@ -347,34 +350,13 @@ (define_expand "vector_geu<mode>"
+ ;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask
+ ;; which is in the reverse order that we want
+ (define_expand "vector_vsel<mode>"
+-  [(match_operand:VEC_F 0 "vlogical_operand" "")
+-   (match_operand:VEC_F 1 "vlogical_operand" "")
+-   (match_operand:VEC_F 2 "vlogical_operand" "")
+-   (match_operand:VEC_F 3 "vlogical_operand" "")]
++  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
++	(if_then_else:VEC_L (ne (match_operand:VEC_L 3 "vlogical_operand" "")
++				(const_int 0))
++			    (match_operand:VEC_L 2 "vlogical_operand" "")
++			    (match_operand:VEC_L 1 "vlogical_operand" "")))]
+   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
+-  "
+-{
+-  if (VECTOR_UNIT_VSX_P (<MODE>mode))
+-    emit_insn (gen_vsx_vsel<mode> (operands[0], operands[3],
+-				   operands[2], operands[1]));
+-  else
+-    emit_insn (gen_altivec_vsel<mode> (operands[0], operands[3],
+-				       operands[2], operands[1]));
+-  DONE;
+-}")
+-
+-(define_expand "vector_vsel<mode>"
+-  [(match_operand:VEC_I 0 "vlogical_operand" "")
+-   (match_operand:VEC_I 1 "vlogical_operand" "")
+-   (match_operand:VEC_I 2 "vlogical_operand" "")
+-   (match_operand:VEC_I 3 "vlogical_operand" "")]
+-  "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+-  "
+-{
+-  emit_insn (gen_altivec_vsel<mode> (operands[0], operands[3],
+-				     operands[2], operands[1]));
+-  DONE;
+-}")
++  "")
+ 
+ \f
+ ;; Vector logical instructions
+@@ -475,19 +457,23 @@ (define_expand "fixuns_trunc<mode><VEC_i
+ \f
+ ;; Vector initialization, set, extract
+ (define_expand "vec_init<mode>"
+-  [(match_operand:VEC_C 0 "vlogical_operand" "")
+-   (match_operand:VEC_C 1 "vec_init_operand" "")]
+-  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
++  [(match_operand:VEC_E 0 "vlogical_operand" "")
++   (match_operand:VEC_E 1 "vec_init_operand" "")]
++  "(<MODE>mode == V2DImode
++    ? VECTOR_MEM_VSX_P (V2DImode)
++    : VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode))"
+ {
+   rs6000_expand_vector_init (operands[0], operands[1]);
+   DONE;
+ })
+ 
+ (define_expand "vec_set<mode>"
+-  [(match_operand:VEC_C 0 "vlogical_operand" "")
++  [(match_operand:VEC_E 0 "vlogical_operand" "")
+    (match_operand:<VEC_base> 1 "register_operand" "")
+    (match_operand 2 "const_int_operand" "")]
+-  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
++  "(<MODE>mode == V2DImode
++    ? VECTOR_MEM_VSX_P (V2DImode)
++    : VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode))"
+ {
+   rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
+   DONE;
+@@ -495,9 +481,11 @@ (define_expand "vec_set<mode>"
+ 
+ (define_expand "vec_extract<mode>"
+   [(match_operand:<VEC_base> 0 "register_operand" "")
+-   (match_operand:VEC_C 1 "vlogical_operand" "")
++   (match_operand:VEC_E 1 "vlogical_operand" "")
+    (match_operand 2 "const_int_operand" "")]
+-  "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
++  "(<MODE>mode == V2DImode
++    ? VECTOR_MEM_VSX_P (V2DImode)
++    : VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode))"
+ {
+   rs6000_expand_vector_extract (operands[0], operands[1],
+ 				INTVAL (operands[2]));
+--- gcc/config/rs6000/predicates.md	(revision 146119)
++++ gcc/config/rs6000/predicates.md	(revision 146798)
+@@ -327,6 +327,9 @@ (define_predicate "easy_vector_constant"
+   if (TARGET_PAIRED_FLOAT)
+     return false;
+ 
++  if ((VSX_VECTOR_MODE (mode) || mode == TImode) && zero_constant (op, mode))
++    return true;
++
+   if (ALTIVEC_VECTOR_MODE (mode))
+     {
+       if (zero_constant (op, mode))
+--- gcc/config/rs6000/rs6000-protos.h	(revision 146119)
++++ gcc/config/rs6000/rs6000-protos.h	(revision 146798)
+@@ -176,6 +176,8 @@ extern int rs6000_register_move_cost (en
+ 				      enum reg_class, enum reg_class);
+ extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
+ extern bool rs6000_tls_referenced_p (rtx);
++extern bool rs6000_has_indirect_jump_p (void);
++extern void rs6000_set_indirect_jump (void);
+ extern void rs6000_conditional_register_usage (void);
+ 
+ /* Declare functions in rs6000-c.c */
+--- gcc/config/rs6000/rs6000-c.c	(revision 146119)
++++ gcc/config/rs6000/rs6000-c.c	(revision 146798)
+@@ -336,7 +336,20 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
+   if (TARGET_NO_LWSYNC)
+     builtin_define ("__NO_LWSYNC__");
+   if (TARGET_VSX)
+-    builtin_define ("__VSX__");
++    {
++      builtin_define ("__VSX__");
++
++      /* For the VSX builtin functions identical to Altivec functions, just map
++	 the altivec builtin into the vsx version (the altivec functions
++	 generate VSX code if -mvsx).  */
++      builtin_define ("__builtin_vsx_xxland=__builtin_vec_and");
++      builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc");
++      builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor");
++      builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or");
++      builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor");
++      builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel");
++      builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm");
++    }
+ 
+   /* May be overridden by target configuration.  */
+   RS6000_CPU_CPP_ENDIAN_BUILTINS();
+@@ -400,7 +413,7 @@ struct altivec_builtin_types
+ };
+ 
+ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
+-  /* Unary AltiVec builtins.  */
++  /* Unary AltiVec/VSX builtins.  */
+   { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI,
+     RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
+   { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI,
+@@ -496,7 +509,7 @@ const struct altivec_builtin_types altiv
+   { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB,
+     RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
+ 
+-  /* Binary AltiVec builtins.  */
++  /* Binary AltiVec/VSX builtins.  */
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+     RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+@@ -2206,7 +2219,7 @@ const struct altivec_builtin_types altiv
+   { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+ 
+-  /* Ternary AltiVec builtins.  */
++  /* Ternary AltiVec/VSX builtins.  */
+   { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
+     RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI },
+   { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
+@@ -2407,6 +2420,10 @@ const struct altivec_builtin_types altiv
+     RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI },
+   { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP,
+     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SF,
+     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI,
+@@ -2433,11 +2450,29 @@ const struct altivec_builtin_types altiv
+     RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI,
+     RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI },
+   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
+     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI },
+   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
+     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI },
+   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
++    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
++    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
+     RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI },
+   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
+     RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI },
+@@ -2805,6 +2840,37 @@ const struct altivec_builtin_types altiv
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL,
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
++    RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
++    RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
++    RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
++    RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
++    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
++    RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
++    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
++    RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF,
++    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF,
++    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
++    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
++  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
++    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
++    RS6000_BTI_NOT_OPAQUE },
+ 
+   /* Predicates.  */
+   { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P,
+@@ -3108,6 +3174,10 @@ altivec_resolve_overloaded_builtin (tree
+ 	goto bad;
+       switch (TYPE_MODE (type))
+ 	{
++	  case DImode:
++	    type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
++	    size = 2;
++	    break;
+ 	  case SImode:
+ 	    type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
+ 	    size = 4;
+@@ -3121,6 +3191,7 @@ altivec_resolve_overloaded_builtin (tree
+ 	    size = 16;
+ 	    break;
+ 	  case SFmode: type = V4SF_type_node; size = 4; break;
++	  case DFmode: type = V2DF_type_node; size = 2; break;
+ 	  default:
+ 	    goto bad;
+ 	}
+--- gcc/config/rs6000/rs6000.opt	(revision 146119)
++++ gcc/config/rs6000/rs6000.opt	(revision 146798)
+@@ -119,18 +119,6 @@ mvsx
+ Target Report Mask(VSX)
+ Use vector/scalar (VSX) instructions
+ 
+-mvsx-vector-memory
+-Target Undocumented Report Var(TARGET_VSX_VECTOR_MEMORY) Init(-1)
+-; If -mvsx, use VSX vector load/store instructions instead of Altivec instructions
+-
+-mvsx-vector-float
+-Target Undocumented Report Var(TARGET_VSX_VECTOR_FLOAT) Init(-1)
+-; If -mvsx, use VSX arithmetic instructions for float vectors (on by default)
+-
+-mvsx-vector-double
+-Target Undocumented Report Var(TARGET_VSX_VECTOR_DOUBLE) Init(-1)
+-; If -mvsx, use VSX arithmetic instructions for double vectors (on by default)
+-
+ mvsx-scalar-double
+ Target Undocumented Report Var(TARGET_VSX_SCALAR_DOUBLE) Init(-1)
+ ; If -mvsx, use VSX arithmetic instructions for scalar double (on by default)
+@@ -139,18 +127,14 @@ mvsx-scalar-memory
+ Target Undocumented Report Var(TARGET_VSX_SCALAR_MEMORY)
+ ; If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default)
+ 
+-mvsx-v4sf-altivec-regs
+-Target Undocumented Report Var(TARGET_V4SF_ALTIVEC_REGS) Init(-1)
+-; If -mvsx, prefer V4SF types to use Altivec regs and not the floating registers
+-
+-mreload-functions
+-Target Undocumented Report Var(TARGET_RELOAD_FUNCTIONS) Init(-1)
+-; If -mvsx or -maltivec, enable reload functions
+-
+ mpower7-adjust-cost
+ Target Undocumented Var(TARGET_POWER7_ADJUST_COST)
+ ; Add extra cost for setting CR registers before a branch like is done for Power5
+ 
++mallow-timode
++Target Undocumented Var(TARGET_ALLOW_TIMODE)
++; Allow VSX/Altivec to target loading TImode variables.
++
+ mdisallow-float-in-lr-ctr
+ Target Undocumented Var(TARGET_DISALLOW_FLOAT_IN_LR_CTR) Init(-1)
+ ; Disallow floating point in LR or CTR, causes some reload bugs
+--- gcc/config/rs6000/rs6000.c	(revision 146119)
++++ gcc/config/rs6000/rs6000.c	(revision 146798)
+@@ -130,6 +130,8 @@ typedef struct machine_function GTY(())
+      64-bits wide and is allocated early enough so that the offset
+      does not overflow the 16-bit load/store offset field.  */
+   rtx sdmode_stack_slot;
++  /* Whether an indirect jump or table jump was generated.  */
++  bool indirect_jump_p;
+ } machine_function;
+ 
+ /* Target cpu type */
+@@ -917,6 +919,11 @@ static rtx rs6000_expand_binop_builtin (
+ static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
+ static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+ static void altivec_init_builtins (void);
++static unsigned builtin_hash_function (const void *);
++static int builtin_hash_eq (const void *, const void *);
++static tree builtin_function_type (enum machine_mode, enum machine_mode,
++				   enum machine_mode, enum machine_mode,
++				   const char *name);
+ static void rs6000_common_init_builtins (void);
+ static void rs6000_init_libfuncs (void);
+ 
+@@ -1018,6 +1025,8 @@ static enum reg_class rs6000_secondary_r
+ 					       enum machine_mode,
+ 					       struct secondary_reload_info *);
+ 
++static const enum reg_class *rs6000_ira_cover_classes (void);
++
+ const int INSN_NOT_AVAILABLE = -1;
+ static enum machine_mode rs6000_eh_return_filter_mode (void);
+ 
+@@ -1033,6 +1042,16 @@ struct toc_hash_struct GTY(())
+ };
+ 
+ static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
++
++/* Hash table to keep track of the argument types for builtin functions.  */
++
++struct builtin_hash_struct GTY(())
++{
++  tree type;
++  enum machine_mode mode[4];	/* return value + 3 arguments */
++};
++
++static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
+ \f
+ /* Default register names.  */
+ char rs6000_reg_names[][8] =
+@@ -1350,6 +1369,9 @@ static const char alt_reg_names[][8] =
+ #undef TARGET_SECONDARY_RELOAD
+ #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
+ 
++#undef TARGET_IRA_COVER_CLASSES
++#define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
+ \f
+ /* Return number of consecutive hard regs needed starting at reg REGNO
+@@ -1370,7 +1392,7 @@ rs6000_hard_regno_nregs_internal (int re
+   unsigned HOST_WIDE_INT reg_size;
+ 
+   if (FP_REGNO_P (regno))
+-    reg_size = (VECTOR_UNIT_VSX_P (mode)
++    reg_size = (VECTOR_MEM_VSX_P (mode)
+ 		? UNITS_PER_VSX_WORD
+ 		: UNITS_PER_FP_WORD);
+ 
+@@ -1452,7 +1474,7 @@ rs6000_hard_regno_mode_ok (int regno, en
+ 
+   /* AltiVec only in AldyVec registers.  */
+   if (ALTIVEC_REGNO_P (regno))
+-    return VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode);
++    return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
+ 
+   /* ...but GPRs can hold SIMD data on the SPE in one register.  */
+   if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
+@@ -1613,10 +1635,8 @@ rs6000_init_hard_regno_mode_ok (void)
+       rs6000_vector_reload[m][1] = CODE_FOR_nothing;
+     }
+ 
+-  /* TODO, add TI/V2DI mode for moving data if Altivec or VSX.  */
+-
+   /* V2DF mode, VSX only.  */
+-  if (float_p && TARGET_VSX && TARGET_VSX_VECTOR_DOUBLE)
++  if (float_p && TARGET_VSX)
+     {
+       rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
+       rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
+@@ -1624,17 +1644,11 @@ rs6000_init_hard_regno_mode_ok (void)
+     }
+ 
+   /* V4SF mode, either VSX or Altivec.  */
+-  if (float_p && TARGET_VSX && TARGET_VSX_VECTOR_FLOAT)
++  if (float_p && TARGET_VSX)
+     {
+       rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
+-      if (TARGET_VSX_VECTOR_MEMORY || !TARGET_ALTIVEC)
+-	{
+-	  rs6000_vector_align[V4SFmode] = 32;
+-	  rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
+-	} else {
+-	  rs6000_vector_align[V4SFmode] = 128;
+-	  rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
+-      }
++      rs6000_vector_align[V4SFmode] = 32;
++      rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
+     }
+   else if (float_p && TARGET_ALTIVEC)
+     {
+@@ -1655,7 +1669,7 @@ rs6000_init_hard_regno_mode_ok (void)
+       rs6000_vector_reg_class[V8HImode] = ALTIVEC_REGS;
+       rs6000_vector_reg_class[V4SImode] = ALTIVEC_REGS;
+ 
+-      if (TARGET_VSX && TARGET_VSX_VECTOR_MEMORY)
++      if (TARGET_VSX)
+ 	{
+ 	  rs6000_vector_mem[V4SImode] = VECTOR_VSX;
+ 	  rs6000_vector_mem[V8HImode] = VECTOR_VSX;
+@@ -1675,6 +1689,23 @@ rs6000_init_hard_regno_mode_ok (void)
+ 	}
+     }
+ 
++  /* V2DImode, prefer vsx over altivec, since the main use will be for
++     vectorized floating point conversions.  */
++  if (float_p && TARGET_VSX)
++    {
++      rs6000_vector_mem[V2DImode] = VECTOR_VSX;
++      rs6000_vector_unit[V2DImode] = VECTOR_NONE;
++      rs6000_vector_reg_class[V2DImode] = vsx_rc;
++      rs6000_vector_align[V2DImode] = 64;
++    }
++  else if (TARGET_ALTIVEC)
++    {
++      rs6000_vector_mem[V2DImode] = VECTOR_ALTIVEC;
++      rs6000_vector_unit[V2DImode] = VECTOR_NONE;
++      rs6000_vector_reg_class[V2DImode] = ALTIVEC_REGS;
++      rs6000_vector_align[V2DImode] = 128;
++    }
++
+   /* DFmode, see if we want to use the VSX unit.  */
+   if (float_p && TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
+     {
+@@ -1684,16 +1715,30 @@ rs6000_init_hard_regno_mode_ok (void)
+ 	= (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
+     }
+ 
+-  /* TODO, add SPE and paired floating point vector support.  */
++  /* TImode.  Until this is debugged, only add it under switch control.  */
++  if (TARGET_ALLOW_TIMODE)
++    {
++      if (float_p && TARGET_VSX)
++	{
++	  rs6000_vector_mem[TImode] = VECTOR_VSX;
++	  rs6000_vector_unit[TImode] = VECTOR_NONE;
++	  rs6000_vector_reg_class[TImode] = vsx_rc;
++	  rs6000_vector_align[TImode] = 64;
++	}
++      else if (TARGET_ALTIVEC)
++	{
++	  rs6000_vector_mem[TImode] = VECTOR_ALTIVEC;
++	  rs6000_vector_unit[TImode] = VECTOR_NONE;
++	  rs6000_vector_reg_class[TImode] = ALTIVEC_REGS;
++	  rs6000_vector_align[TImode] = 128;
++	}
++    }
++
++  /* TODO add SPE and paired floating point vector support.  */
+ 
+   /* Set the VSX register classes.  */
+-
+-  /* For V4SF, prefer the Altivec registers, because there are a few operations
+-     that want to use Altivec operations instead of VSX.  */
+   rs6000_vector_reg_class[V4SFmode]
+-    = ((VECTOR_UNIT_VSX_P (V4SFmode)
+-	&& VECTOR_MEM_VSX_P (V4SFmode)
+-	&& !TARGET_V4SF_ALTIVEC_REGS)
++    = ((VECTOR_UNIT_VSX_P (V4SFmode) && VECTOR_MEM_VSX_P (V4SFmode))
+        ? vsx_rc
+        : (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+ 	  ? ALTIVEC_REGS
+@@ -1712,7 +1757,7 @@ rs6000_init_hard_regno_mode_ok (void)
+   rs6000_vsx_reg_class = (float_p && TARGET_VSX) ? vsx_rc : NO_REGS;
+ 
+   /* Set up the reload helper functions.  */
+-  if (TARGET_RELOAD_FUNCTIONS && (TARGET_VSX || TARGET_ALTIVEC))
++  if (TARGET_VSX || TARGET_ALTIVEC)
+     {
+       if (TARGET_64BIT)
+ 	{
+@@ -1728,6 +1773,11 @@ rs6000_init_hard_regno_mode_ok (void)
+ 	  rs6000_vector_reload[V4SFmode][1]  = CODE_FOR_reload_v4sf_di_load;
+ 	  rs6000_vector_reload[V2DFmode][0]  = CODE_FOR_reload_v2df_di_store;
+ 	  rs6000_vector_reload[V2DFmode][1]  = CODE_FOR_reload_v2df_di_load;
++	  if (TARGET_ALLOW_TIMODE)
++	    {
++	      rs6000_vector_reload[TImode][0] = CODE_FOR_reload_ti_di_store;
++	      rs6000_vector_reload[TImode][1] = CODE_FOR_reload_ti_di_load;
++	    }
+ 	}
+       else
+ 	{
+@@ -1743,6 +1793,11 @@ rs6000_init_hard_regno_mode_ok (void)
+ 	  rs6000_vector_reload[V4SFmode][1]  = CODE_FOR_reload_v4sf_si_load;
+ 	  rs6000_vector_reload[V2DFmode][0]  = CODE_FOR_reload_v2df_si_store;
+ 	  rs6000_vector_reload[V2DFmode][1]  = CODE_FOR_reload_v2df_si_load;
++	  if (TARGET_ALLOW_TIMODE)
++	    {
++	      rs6000_vector_reload[TImode][0] = CODE_FOR_reload_ti_si_store;
++	      rs6000_vector_reload[TImode][1] = CODE_FOR_reload_ti_si_load;
++	    }
+ 	}
+     }
+ 
+@@ -2132,23 +2187,29 @@ rs6000_override_options (const char *def
+       const char *msg = NULL;
+       if (!TARGET_HARD_FLOAT || !TARGET_FPRS
+ 	  || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
+-	msg = "-mvsx requires hardware floating point";
++	{
++	  if (target_flags_explicit & MASK_VSX)
++	    msg = N_("-mvsx requires hardware floating point");
++	  else
++	    target_flags &= ~ MASK_VSX;
++	}
+       else if (TARGET_PAIRED_FLOAT)
+-	msg = "-mvsx and -mpaired are incompatible";
++	msg = N_("-mvsx and -mpaired are incompatible");
+       /* The hardware will allow VSX and little endian, but until we make sure
+ 	 things like vector select, etc. work don't allow VSX on little endian
+ 	 systems at this point.  */
+       else if (!BYTES_BIG_ENDIAN)
+-	msg = "-mvsx used with little endian code";
++	msg = N_("-mvsx used with little endian code");
+       else if (TARGET_AVOID_XFORM > 0)
+-	msg = "-mvsx needs indexed addressing";
++	msg = N_("-mvsx needs indexed addressing");
+ 
+       if (msg)
+ 	{
+ 	  warning (0, msg);
+-	  target_flags &= MASK_VSX;
++	  target_flags &= ~ MASK_VSX;
+ 	}
+-      else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC) == 0)
++      else if (TARGET_VSX && !TARGET_ALTIVEC
++	       && (target_flags_explicit & MASK_ALTIVEC) == 0)
+ 	target_flags |= MASK_ALTIVEC;
+     }
+ 
+@@ -2581,8 +2642,8 @@ rs6000_builtin_conversion (enum tree_cod
+ 	    return NULL_TREE;
+ 
+ 	  return TYPE_UNSIGNED (type)
+-	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDSP]
+-	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDSP];
++	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
++	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
+ 
+ 	case V4SImode:
+ 	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
+@@ -3785,15 +3846,28 @@ rs6000_expand_vector_init (rtx target, r
+ 	}
+     }
+ 
+-  if (mode == V2DFmode)
++  if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
+     {
+-      gcc_assert (TARGET_VSX);
++      rtx (*splat) (rtx, rtx);
++      rtx (*concat) (rtx, rtx, rtx);
++
++      if (mode == V2DFmode)
++	{
++	  splat = gen_vsx_splat_v2df;
++	  concat = gen_vsx_concat_v2df;
++	}
++      else
++	{
++	  splat = gen_vsx_splat_v2di;
++	  concat = gen_vsx_concat_v2di;
++	}
++
+       if (all_same)
+-	emit_insn (gen_vsx_splatv2df (target, XVECEXP (vals, 0, 0)));
++	emit_insn (splat (target, XVECEXP (vals, 0, 0)));
+       else
+-	emit_insn (gen_vsx_concat_v2df (target,
+-					copy_to_reg (XVECEXP (vals, 0, 0)),
+-					copy_to_reg (XVECEXP (vals, 0, 1))));
++	emit_insn (concat (target,
++			   copy_to_reg (XVECEXP (vals, 0, 0)),
++			   copy_to_reg (XVECEXP (vals, 0, 1))));
+       return;
+     }
+ 
+@@ -3856,10 +3930,12 @@ rs6000_expand_vector_set (rtx target, rt
+   int width = GET_MODE_SIZE (inner_mode);
+   int i;
+ 
+-  if (mode == V2DFmode)
++  if (mode == V2DFmode || mode == V2DImode)
+     {
++      rtx (*set_func) (rtx, rtx, rtx, rtx)
++	= ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
+       gcc_assert (TARGET_VSX);
+-      emit_insn (gen_vsx_set_v2df (target, val, target, GEN_INT (elt)));
++      emit_insn (set_func (target, val, target, GEN_INT (elt)));
+       return;
+     }
+ 
+@@ -3900,10 +3976,12 @@ rs6000_expand_vector_extract (rtx target
+   enum machine_mode inner_mode = GET_MODE_INNER (mode);
+   rtx mem, x;
+ 
+-  if (mode == V2DFmode)
++  if (mode == V2DFmode || mode == V2DImode)
+     {
++      rtx (*extract_func) (rtx, rtx, rtx)
++	= ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
+       gcc_assert (TARGET_VSX);
+-      emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
++      emit_insn (extract_func (target, vec, GEN_INT (elt)));
+       return;
+     }
+ 
+@@ -4323,9 +4401,7 @@ avoiding_indexed_address_p (enum machine
+ {
+   /* Avoid indexed addressing for modes that have non-indexed
+      load/store instruction forms.  */
+-  return (TARGET_AVOID_XFORM
+-	  && (!TARGET_ALTIVEC || !ALTIVEC_VECTOR_MODE (mode))
+-	  && (!TARGET_VSX || !VSX_VECTOR_MODE (mode)));
++  return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
+ }
+ 
+ inline bool
+@@ -4427,6 +4503,16 @@ rs6000_legitimize_address (rtx x, rtx ol
+ 	ret = rs6000_legitimize_tls_address (x, model);
+     }
+ 
++  else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
++    {
++      /* Make sure both operands are registers.  */
++      if (GET_CODE (x) == PLUS)
++	ret = gen_rtx_PLUS (Pmode,
++			    force_reg (Pmode, XEXP (x, 0)),
++			    force_reg (Pmode, XEXP (x, 1)));
++      else
++	ret = force_reg (Pmode, x);
++    }
+   else if (GET_CODE (x) == PLUS
+ 	   && GET_CODE (XEXP (x, 0)) == REG
+ 	   && GET_CODE (XEXP (x, 1)) == CONST_INT
+@@ -4436,8 +4522,6 @@ rs6000_legitimize_address (rtx x, rtx ol
+ 		 && (mode == DImode || mode == TImode)
+ 		 && (INTVAL (XEXP (x, 1)) & 3) != 0)
+ 		|| (TARGET_SPE && SPE_VECTOR_MODE (mode))
+-		|| (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
+-		|| (TARGET_VSX && VSX_VECTOR_MODE (mode))
+ 		|| (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
+ 					   || mode == DImode || mode == DDmode
+ 					   || mode == TDmode))))
+@@ -4467,15 +4551,6 @@ rs6000_legitimize_address (rtx x, rtx ol
+       ret = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ 			  force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
+     }
+-  else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
+-    {
+-      /* Make sure both operands are registers.  */
+-      if (GET_CODE (x) == PLUS)
+-	ret = gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
+-			    force_reg (Pmode, XEXP (x, 1)));
+-      else
+-	ret = force_reg (Pmode, x);
+-    }
+   else if ((TARGET_SPE && SPE_VECTOR_MODE (mode))
+ 	   || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
+ 				      || mode == DDmode || mode == TDmode
+@@ -5113,7 +5188,7 @@ rs6000_legitimate_address (enum machine_
+     ret = 1;
+   else if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
+     ret = 1;
+-  else if (mode != TImode
++  else if ((mode != TImode || !VECTOR_MEM_NONE_P (TImode))
+ 	   && mode != TFmode
+ 	   && mode != TDmode
+ 	   && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+@@ -5953,7 +6028,13 @@ rs6000_emit_move (rtx dest, rtx source, 
+ 
+     case TImode:
+       if (VECTOR_MEM_ALTIVEC_OR_VSX_P (TImode))
+-	break;
++	{
++	  if (CONSTANT_P (operands[1])
++	      && !easy_vector_constant (operands[1], mode))
++	    operands[1] = force_const_mem (mode, operands[1]);
++
++	  break;
++	}
+ 
+       rs6000_eliminate_indexed_memrefs (operands);
+ 
+@@ -7869,7 +7950,8 @@ def_builtin (int mask, const char *name,
+   if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
+     {
+       if (rs6000_builtin_decls[code])
+-	abort ();
++	fatal_error ("internal error: builtin function to %s already processed.",
++		     name);
+ 
+       rs6000_builtin_decls[code] =
+         add_builtin_function (name, type, code, BUILT_IN_MD,
+@@ -7934,6 +8016,34 @@ static const struct builtin_description 
+   { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
+   { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
+ 
++  { MASK_VSX, CODE_FOR_vector_vselv2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
++  { MASK_VSX, CODE_FOR_vector_vselv2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
++  { MASK_VSX, CODE_FOR_vector_vselv4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
++  { MASK_VSX, CODE_FOR_vector_vselv4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
++  { MASK_VSX, CODE_FOR_vector_vselv8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
++  { MASK_VSX, CODE_FOR_vector_vselv16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
++
++  { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
++  { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
++  { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
++  { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
++  { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
++  { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
++
++  { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
++  { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
++  { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
++  { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
++  { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
++
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
++  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
++  { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
++
+   { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
+   { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
+   { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
+@@ -8083,6 +8193,9 @@ static struct builtin_description bdesc_
+   { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
+   { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
+   { MASK_VSX, CODE_FOR_vsx_tdivv2df3, "__builtin_vsx_xvtdivdp", VSX_BUILTIN_XVTDIVDP },
++  { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
++  { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
++  { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
+ 
+   { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
+   { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
+@@ -8091,6 +8204,21 @@ static struct builtin_description bdesc_
+   { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
+   { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
+   { MASK_VSX, CODE_FOR_vsx_tdivv4sf3, "__builtin_vsx_xvtdivsp", VSX_BUILTIN_XVTDIVSP },
++  { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
++  { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
++  { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
++
++  { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
++  { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
++
++  { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
++  { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
++  { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
++  { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
++  { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
++  { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
++  { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
++  { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
+ 
+   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
+   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
+@@ -8508,6 +8636,47 @@ static struct builtin_description bdesc_
+   { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2, "__builtin_vsx_xvtsqrtsp", VSX_BUILTIN_XVTSQRTSP },
+   { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
+ 
++  { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
++  { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
++  { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
++  { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
++
++  { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
++  { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
++  { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
++  { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
++
++  { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
++  { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
++  { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
++  { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
++
++  { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
++  { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
++  { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
++  { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
++  { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
++  { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
++  { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
++  { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
++  { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
++
++  { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
++  { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
++  { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
++  { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
++  { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
++  { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
++  { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
++  { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
++  { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
++
++  { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
++  { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
++  { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
++  { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
++  { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
++
+   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
+   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
+   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
+@@ -8533,15 +8702,6 @@ static struct builtin_description bdesc_
+   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
+   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
+ 
+-  { MASK_VSX, CODE_FOR_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
+-  { MASK_VSX, CODE_FOR_unsigned_floatv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
+-  { MASK_VSX, CODE_FOR_fix_truncv2dfv2di2, "__builtin_vsx_xvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
+-  { MASK_VSX, CODE_FOR_fixuns_truncv2dfv2di2, "__builtin_vsx_xvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
+-  { MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXDSP },
+-  { MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
+-  { MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vsx_xvspsxws", VSX_BUILTIN_XVCVSPSXWS },
+-  { MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vsx_xvspuxws", VSX_BUILTIN_XVCVSPUXWS },
+-
+   /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
+      end with SPE_BUILTIN_EVSUBFUSIAAW.  */
+   { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
+@@ -9046,11 +9206,12 @@ rs6000_expand_ternop_builtin (enum insn_
+       || arg2 == error_mark_node)
+     return const0_rtx;
+ 
+-  if (icode == CODE_FOR_altivec_vsldoi_v4sf
+-      || icode == CODE_FOR_altivec_vsldoi_v4si
+-      || icode == CODE_FOR_altivec_vsldoi_v8hi
+-      || icode == CODE_FOR_altivec_vsldoi_v16qi)
++  switch (icode)
+     {
++    case CODE_FOR_altivec_vsldoi_v4sf:
++    case CODE_FOR_altivec_vsldoi_v4si:
++    case CODE_FOR_altivec_vsldoi_v8hi:
++    case CODE_FOR_altivec_vsldoi_v16qi:
+       /* Only allow 4-bit unsigned literals.  */
+       STRIP_NOPS (arg2);
+       if (TREE_CODE (arg2) != INTEGER_CST
+@@ -9059,6 +9220,40 @@ rs6000_expand_ternop_builtin (enum insn_
+ 	  error ("argument 3 must be a 4-bit unsigned literal");
+ 	  return const0_rtx;
+ 	}
++      break;
++
++    case CODE_FOR_vsx_xxpermdi_v2df:
++    case CODE_FOR_vsx_xxpermdi_v2di:
++    case CODE_FOR_vsx_xxsldwi_v16qi:
++    case CODE_FOR_vsx_xxsldwi_v8hi:
++    case CODE_FOR_vsx_xxsldwi_v4si:
++    case CODE_FOR_vsx_xxsldwi_v4sf:
++    case CODE_FOR_vsx_xxsldwi_v2di:
++    case CODE_FOR_vsx_xxsldwi_v2df:
++      /* Only allow 2-bit unsigned literals.  */
++      STRIP_NOPS (arg2);
++      if (TREE_CODE (arg2) != INTEGER_CST
++	  || TREE_INT_CST_LOW (arg2) & ~0x3)
++	{
++	  error ("argument 3 must be a 2-bit unsigned literal");
++	  return const0_rtx;
++	}
++      break;
++
++    case CODE_FOR_vsx_set_v2df:
++    case CODE_FOR_vsx_set_v2di:
++      /* Only allow 1-bit unsigned literals.  */
++      STRIP_NOPS (arg2);
++      if (TREE_CODE (arg2) != INTEGER_CST
++	  || TREE_INT_CST_LOW (arg2) & ~0x1)
++	{
++	  error ("argument 3 must be a 1-bit unsigned literal");
++	  return const0_rtx;
++	}
++      break;
++
++    default:
++      break;
+     }
+ 
+   if (target == 0
+@@ -9366,8 +9561,10 @@ altivec_expand_builtin (tree exp, rtx ta
+   enum machine_mode tmode, mode0;
+   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ 
+-  if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+-      && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++  if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
++       && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++      || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
++	  && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
+     {
+       *expandedp = true;
+       error ("unresolved overload for Altivec builtin %qF", fndecl);
+@@ -10156,6 +10353,7 @@ rs6000_init_builtins (void)
+   unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
+   unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
+   unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
++  unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
+ 
+   opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
+   opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
+@@ -10169,6 +10367,7 @@ rs6000_init_builtins (void)
+   bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
+   bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+   bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
++  bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
+   pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+ 
+   long_integer_type_internal_node = long_integer_type_node;
+@@ -10201,6 +10400,7 @@ rs6000_init_builtins (void)
+   bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
+   bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
+   bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
++  bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
+   pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
+ 
+   (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+@@ -10241,9 +10441,17 @@ rs6000_init_builtins (void)
+ 					    pixel_V8HI_type_node));
+ 
+   if (TARGET_VSX)
+-    (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+-					      get_identifier ("__vector double"),
+-					      V2DF_type_node));
++    {
++      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
++						get_identifier ("__vector double"),
++						V2DF_type_node));
++      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
++						get_identifier ("__vector long"),
++						V2DI_type_node));
++      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
++						get_identifier ("__vector __bool long"),
++						bool_V2DI_type_node));
++    }
+ 
+   if (TARGET_PAIRED_FLOAT)
+     paired_init_builtins ();
+@@ -10818,8 +11026,10 @@ altivec_init_builtins (void)
+     {
+       enum machine_mode mode1;
+       tree type;
+-      bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+-			   && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
++      bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
++			     && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++			    || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
++				&& dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
+ 
+       if (is_overloaded)
+ 	mode1 = VOIDmode;
+@@ -10982,592 +11192,302 @@ altivec_init_builtins (void)
+ 	       ALTIVEC_BUILTIN_VEC_EXT_V4SF);
+ }
+ 
+-static void
+-rs6000_common_init_builtins (void)
++/* Hash function for builtin functions with up to 3 arguments and a return
++   type.  */
++static unsigned
++builtin_hash_function (const void *hash_entry)
+ {
+-  const struct builtin_description *d;
+-  size_t i;
++  unsigned ret = 0;
++  int i;
++  const struct builtin_hash_struct *bh =
++    (const struct builtin_hash_struct *) hash_entry;
+ 
+-  tree v2sf_ftype_v2sf_v2sf_v2sf
+-    = build_function_type_list (V2SF_type_node,
+-                                V2SF_type_node, V2SF_type_node,
+-                                V2SF_type_node, NULL_TREE);
+-
+-  tree v4sf_ftype_v4sf_v4sf_v16qi
+-    = build_function_type_list (V4SF_type_node,
+-				V4SF_type_node, V4SF_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v4si_ftype_v4si_v4si_v16qi
+-    = build_function_type_list (V4SI_type_node,
+-				V4SI_type_node, V4SI_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v8hi_ftype_v8hi_v8hi_v16qi
+-    = build_function_type_list (V8HI_type_node,
+-				V8HI_type_node, V8HI_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v16qi_ftype_v16qi_v16qi_v16qi
+-    = build_function_type_list (V16QI_type_node,
+-				V16QI_type_node, V16QI_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v4si_ftype_int
+-    = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
+-  tree v8hi_ftype_int
+-    = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
+-  tree v16qi_ftype_int
+-    = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
+-  tree v8hi_ftype_v16qi
+-    = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4sf
+-    = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
++  for (i = 0; i < 4; i++)
++    ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
+ 
+-  tree v2si_ftype_v2si_v2si
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				opaque_V2SI_type_node,
+-				opaque_V2SI_type_node, NULL_TREE);
+-
+-  tree v2sf_ftype_v2sf_v2sf_spe
+-    = build_function_type_list (opaque_V2SF_type_node,
+-				opaque_V2SF_type_node,
+-				opaque_V2SF_type_node, NULL_TREE);
+-
+-  tree v2sf_ftype_v2sf_v2sf
+-    = build_function_type_list (V2SF_type_node,
+-                                V2SF_type_node,
+-                                V2SF_type_node, NULL_TREE);
+-
+-
+-  tree v2si_ftype_int_int
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				integer_type_node, integer_type_node,
+-				NULL_TREE);
++  return ret;
++}
+ 
+-  tree opaque_ftype_opaque
+-    = build_function_type_list (opaque_V4SI_type_node,
+-				opaque_V4SI_type_node, NULL_TREE);
++/* Compare builtin hash entries H1 and H2 for equivalence.  */
++static int
++builtin_hash_eq (const void *h1, const void *h2)
++{
++  const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
++  const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
+ 
+-  tree v2si_ftype_v2si
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				opaque_V2SI_type_node, NULL_TREE);
+-
+-  tree v2sf_ftype_v2sf_spe
+-    = build_function_type_list (opaque_V2SF_type_node,
+-				opaque_V2SF_type_node, NULL_TREE);
+-
+-  tree v2sf_ftype_v2sf
+-    = build_function_type_list (V2SF_type_node,
+-                                V2SF_type_node, NULL_TREE);
+-
+-  tree v2sf_ftype_v2si
+-    = build_function_type_list (opaque_V2SF_type_node,
+-				opaque_V2SI_type_node, NULL_TREE);
+-
+-  tree v2si_ftype_v2sf
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				opaque_V2SF_type_node, NULL_TREE);
+-
+-  tree v2si_ftype_v2si_char
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				opaque_V2SI_type_node,
+-				char_type_node, NULL_TREE);
+-
+-  tree v2si_ftype_int_char
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				integer_type_node, char_type_node, NULL_TREE);
+-
+-  tree v2si_ftype_char
+-    = build_function_type_list (opaque_V2SI_type_node,
+-				char_type_node, NULL_TREE);
++  return ((p1->mode[0] == p2->mode[0])
++	  && (p1->mode[1] == p2->mode[1])
++	  && (p1->mode[2] == p2->mode[2])
++	  && (p1->mode[3] == p2->mode[3]));
++}
+ 
+-  tree int_ftype_int_int
+-    = build_function_type_list (integer_type_node,
+-				integer_type_node, integer_type_node,
+-				NULL_TREE);
++/* Map selected modes to types for builtins.  */
++static tree builtin_mode_to_type[MAX_MACHINE_MODE];
+ 
+-  tree opaque_ftype_opaque_opaque
+-    = build_function_type_list (opaque_V4SI_type_node,
+-                                opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
+-  tree v4si_ftype_v4si_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V4SI_type_node, V4SI_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4si_int
+-    = build_function_type_list (V4SF_type_node,
+-				V4SI_type_node, integer_type_node, NULL_TREE);
+-  tree v4si_ftype_v4sf_int
+-    = build_function_type_list (V4SI_type_node,
+-				V4SF_type_node, integer_type_node, NULL_TREE);
+-  tree v4si_ftype_v4si_int
+-    = build_function_type_list (V4SI_type_node,
+-				V4SI_type_node, integer_type_node, NULL_TREE);
+-  tree v8hi_ftype_v8hi_int
+-    = build_function_type_list (V8HI_type_node,
+-				V8HI_type_node, integer_type_node, NULL_TREE);
+-  tree v16qi_ftype_v16qi_int
+-    = build_function_type_list (V16QI_type_node,
+-				V16QI_type_node, integer_type_node, NULL_TREE);
+-  tree v16qi_ftype_v16qi_v16qi_int
+-    = build_function_type_list (V16QI_type_node,
+-				V16QI_type_node, V16QI_type_node,
+-				integer_type_node, NULL_TREE);
+-  tree v8hi_ftype_v8hi_v8hi_int
+-    = build_function_type_list (V8HI_type_node,
+-				V8HI_type_node, V8HI_type_node,
+-				integer_type_node, NULL_TREE);
+-  tree v4si_ftype_v4si_v4si_int
+-    = build_function_type_list (V4SI_type_node,
+-				V4SI_type_node, V4SI_type_node,
+-				integer_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4sf_v4sf_int
+-    = build_function_type_list (V4SF_type_node,
+-				V4SF_type_node, V4SF_type_node,
+-				integer_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4sf_v4sf
+-    = build_function_type_list (V4SF_type_node,
+-				V4SF_type_node, V4SF_type_node, NULL_TREE);
+-  tree opaque_ftype_opaque_opaque_opaque
+-    = build_function_type_list (opaque_V4SI_type_node,
+-                                opaque_V4SI_type_node, opaque_V4SI_type_node,
+-                                opaque_V4SI_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4sf_v4sf_v4si
+-    = build_function_type_list (V4SF_type_node,
+-				V4SF_type_node, V4SF_type_node,
+-				V4SI_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4sf_v4sf_v4sf
+-    = build_function_type_list (V4SF_type_node,
+-				V4SF_type_node, V4SF_type_node,
+-				V4SF_type_node, NULL_TREE);
+-  tree v4si_ftype_v4si_v4si_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V4SI_type_node, V4SI_type_node,
+-				V4SI_type_node, NULL_TREE);
+-  tree v8hi_ftype_v8hi_v8hi
+-    = build_function_type_list (V8HI_type_node,
+-				V8HI_type_node, V8HI_type_node, NULL_TREE);
+-  tree v8hi_ftype_v8hi_v8hi_v8hi
+-    = build_function_type_list (V8HI_type_node,
+-				V8HI_type_node, V8HI_type_node,
+-				V8HI_type_node, NULL_TREE);
+-  tree v4si_ftype_v8hi_v8hi_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V8HI_type_node, V8HI_type_node,
+-				V4SI_type_node, NULL_TREE);
+-  tree v4si_ftype_v16qi_v16qi_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V16QI_type_node, V16QI_type_node,
+-				V4SI_type_node, NULL_TREE);
+-  tree v16qi_ftype_v16qi_v16qi
+-    = build_function_type_list (V16QI_type_node,
+-				V16QI_type_node, V16QI_type_node, NULL_TREE);
+-  tree v4si_ftype_v4sf_v4sf
+-    = build_function_type_list (V4SI_type_node,
+-				V4SF_type_node, V4SF_type_node, NULL_TREE);
+-  tree v8hi_ftype_v16qi_v16qi
+-    = build_function_type_list (V8HI_type_node,
+-				V16QI_type_node, V16QI_type_node, NULL_TREE);
+-  tree v4si_ftype_v8hi_v8hi
+-    = build_function_type_list (V4SI_type_node,
+-				V8HI_type_node, V8HI_type_node, NULL_TREE);
+-  tree v8hi_ftype_v4si_v4si
+-    = build_function_type_list (V8HI_type_node,
+-				V4SI_type_node, V4SI_type_node, NULL_TREE);
+-  tree v16qi_ftype_v8hi_v8hi
+-    = build_function_type_list (V16QI_type_node,
+-				V8HI_type_node, V8HI_type_node, NULL_TREE);
+-  tree v4si_ftype_v16qi_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V16QI_type_node, V4SI_type_node, NULL_TREE);
+-  tree v4si_ftype_v16qi_v16qi
+-    = build_function_type_list (V4SI_type_node,
+-				V16QI_type_node, V16QI_type_node, NULL_TREE);
+-  tree v4si_ftype_v8hi_v4si
+-    = build_function_type_list (V4SI_type_node,
+-				V8HI_type_node, V4SI_type_node, NULL_TREE);
+-  tree v4si_ftype_v8hi
+-    = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
+-  tree int_ftype_v4si_v4si
+-    = build_function_type_list (integer_type_node,
+-				V4SI_type_node, V4SI_type_node, NULL_TREE);
+-  tree int_ftype_v4sf_v4sf
+-    = build_function_type_list (integer_type_node,
+-				V4SF_type_node, V4SF_type_node, NULL_TREE);
+-  tree int_ftype_v16qi_v16qi
+-    = build_function_type_list (integer_type_node,
+-				V16QI_type_node, V16QI_type_node, NULL_TREE);
+-  tree int_ftype_v8hi_v8hi
+-    = build_function_type_list (integer_type_node,
+-				V8HI_type_node, V8HI_type_node, NULL_TREE);
+-  tree v2di_ftype_v2df
+-    = build_function_type_list (V2DI_type_node,
+-				V2DF_type_node, NULL_TREE);
+-  tree v2df_ftype_v2df
+-    = build_function_type_list (V2DF_type_node,
+-				V2DF_type_node, NULL_TREE);
+-  tree v2df_ftype_v2di
+-    = build_function_type_list (V2DF_type_node,
+-				V2DI_type_node, NULL_TREE);
+-  tree v2df_ftype_v2df_v2df
+-    = build_function_type_list (V2DF_type_node,
+-				V2DF_type_node, V2DF_type_node, NULL_TREE);
+-  tree v2df_ftype_v2df_v2df_v2df
+-    = build_function_type_list (V2DF_type_node,
+-				V2DF_type_node, V2DF_type_node,
+-				V2DF_type_node, NULL_TREE);
+-  tree v2di_ftype_v2di_v2di_v2di
+-    = build_function_type_list (V2DI_type_node,
+-				V2DI_type_node, V2DI_type_node,
+-				V2DI_type_node, NULL_TREE);
+-  tree v2df_ftype_v2df_v2df_v16qi
+-    = build_function_type_list (V2DF_type_node,
+-				V2DF_type_node, V2DF_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v2di_ftype_v2di_v2di_v16qi
+-    = build_function_type_list (V2DI_type_node,
+-				V2DI_type_node, V2DI_type_node,
+-				V16QI_type_node, NULL_TREE);
+-  tree v4sf_ftype_v4si
+-    = build_function_type_list (V4SF_type_node, V4SI_type_node, NULL_TREE);
+-  tree v4si_ftype_v4sf
+-    = build_function_type_list (V4SI_type_node, V4SF_type_node, NULL_TREE);
++/* Map types for builtin functions with an explicit return type and up to 3
++   arguments.  Functions with fewer than 3 arguments use VOIDmode as the type
++   of the argument.  */
++static tree
++builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
++		       enum machine_mode mode_arg1, enum machine_mode mode_arg2,
++		       const char *name)
++{
++  struct builtin_hash_struct h;
++  struct builtin_hash_struct *h2;
++  void **found;
++  int num_args = 3;
++  int i;
+ 
+-  /* Add the simple ternary operators.  */
++  /* Create builtin_hash_table.  */
++  if (builtin_hash_table == NULL)
++    builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
++					  builtin_hash_eq, NULL);
++
++  h.type = NULL_TREE;
++  h.mode[0] = mode_ret;
++  h.mode[1] = mode_arg0;
++  h.mode[2] = mode_arg1;
++  h.mode[3] = mode_arg2;
++
++  /* Figure out how many args are present.  */
++  while (num_args > 0 && h.mode[num_args] == VOIDmode)
++    num_args--;
++
++  if (num_args == 0)
++    fatal_error ("internal error: builtin function %s had no type", name);
++
++  if (!builtin_mode_to_type[h.mode[0]])
++    fatal_error ("internal error: builtin function %s had an unexpected "
++		 "return type %s", name, GET_MODE_NAME (h.mode[0]));
++
++  for (i = 0; i < num_args; i++)
++    if (!builtin_mode_to_type[h.mode[i+1]])
++      fatal_error ("internal error: builtin function %s, argument %d "
++		   "had unexpected argument type %s", name, i,
++		   GET_MODE_NAME (h.mode[i+1]));
++
++  found = htab_find_slot (builtin_hash_table, &h, 1);
++  if (*found == NULL)
++    {
++      h2 = GGC_NEW (struct builtin_hash_struct);
++      *h2 = h;
++      *found = (void *)h2;
++
++      switch (num_args)
++	{
++	case 1:
++	  h2->type = build_function_type_list (builtin_mode_to_type[mode_ret],
++					       builtin_mode_to_type[mode_arg0],
++					       NULL_TREE);
++	  break;
++
++	case 2:
++	  h2->type = build_function_type_list (builtin_mode_to_type[mode_ret],
++					       builtin_mode_to_type[mode_arg0],
++					       builtin_mode_to_type[mode_arg1],
++					       NULL_TREE);
++	  break;
++
++	case 3:
++	  h2->type = build_function_type_list (builtin_mode_to_type[mode_ret],
++					       builtin_mode_to_type[mode_arg0],
++					       builtin_mode_to_type[mode_arg1],
++					       builtin_mode_to_type[mode_arg2],
++					       NULL_TREE);
++	  break;
++
++	default:
++	  gcc_unreachable ();
++	}
++    }
++
++  return ((struct builtin_hash_struct *)(*found))->type;
++}
++
++static void
++rs6000_common_init_builtins (void)
++{
++  const struct builtin_description *d;
++  size_t i;
++
++  tree opaque_ftype_opaque = NULL_TREE;
++  tree opaque_ftype_opaque_opaque = NULL_TREE;
++  tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
++  tree v2si_ftype_qi = NULL_TREE;
++  tree v2si_ftype_v2si_qi = NULL_TREE;
++  tree v2si_ftype_int_qi = NULL_TREE;
++
++  /* Initialize the tables for the unary, binary, and ternary ops.  */
++  builtin_mode_to_type[QImode] = integer_type_node;
++  builtin_mode_to_type[HImode] = integer_type_node;
++  builtin_mode_to_type[SImode] = intSI_type_node;
++  builtin_mode_to_type[DImode] = intDI_type_node;
++  builtin_mode_to_type[SFmode] = float_type_node;
++  builtin_mode_to_type[DFmode] = double_type_node;
++  builtin_mode_to_type[V2SImode] = V2SI_type_node;
++  builtin_mode_to_type[V2SFmode] = V2SF_type_node;
++  builtin_mode_to_type[V2DImode] = V2DI_type_node;
++  builtin_mode_to_type[V2DFmode] = V2DF_type_node;
++  builtin_mode_to_type[V4HImode] = V4HI_type_node;
++  builtin_mode_to_type[V4SImode] = V4SI_type_node;
++  builtin_mode_to_type[V4SFmode] = V4SF_type_node;
++  builtin_mode_to_type[V8HImode] = V8HI_type_node;
++  builtin_mode_to_type[V16QImode] = V16QI_type_node;
++
++  if (!TARGET_PAIRED_FLOAT)
++    {
++      builtin_mode_to_type[V2SImode] = opaque_V2SI_type_node;
++      builtin_mode_to_type[V2SFmode] = opaque_V2SF_type_node;
++    }
++
++  /* Add the ternary operators.  */
+   d = bdesc_3arg;
+   for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
+     {
+-      enum machine_mode mode0, mode1, mode2, mode3;
+       tree type;
+-      bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+-			   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
++      int mask = d->mask;
+ 
+-      if (is_overloaded)
+-	{
+-          mode0 = VOIDmode;
+-          mode1 = VOIDmode;
+-          mode2 = VOIDmode;
+-          mode3 = VOIDmode;
++      if ((mask != 0 && (mask & target_flags) == 0)
++	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
++	continue;
++
++      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
++	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
++	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
++	{
++	  if (! (type = opaque_ftype_opaque_opaque_opaque))
++	    type = opaque_ftype_opaque_opaque_opaque
++	      = build_function_type_list (opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  NULL_TREE);
+ 	}
+       else
+ 	{
+-          if (d->name == 0 || d->icode == CODE_FOR_nothing)
++	  enum insn_code icode = d->icode;
++          if (d->name == 0 || icode == CODE_FOR_nothing)
+ 	    continue;
+ 
+-          mode0 = insn_data[d->icode].operand[0].mode;
+-          mode1 = insn_data[d->icode].operand[1].mode;
+-          mode2 = insn_data[d->icode].operand[2].mode;
+-          mode3 = insn_data[d->icode].operand[3].mode;
++	  type = builtin_function_type (insn_data[icode].operand[0].mode,
++					insn_data[icode].operand[1].mode,
++					insn_data[icode].operand[2].mode,
++					insn_data[icode].operand[3].mode,
++					d->name);
+ 	}
+ 
+-      /* When all four are of the same mode.  */
+-      if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
+-	{
+-	  switch (mode0)
+-	    {
+-	    case VOIDmode:
+-	      type = opaque_ftype_opaque_opaque_opaque;
+-	      break;
+-	    case V2DImode:
+-	      type = v2di_ftype_v2di_v2di_v2di;
+-	      break;
+-	    case V2DFmode:
+-	      type = v2df_ftype_v2df_v2df_v2df;
+-	      break;
+-	    case V4SImode:
+-	      type = v4si_ftype_v4si_v4si_v4si;
+-	      break;
+-	    case V4SFmode:
+-	      type = v4sf_ftype_v4sf_v4sf_v4sf;
+-	      break;
+-	    case V8HImode:
+-	      type = v8hi_ftype_v8hi_v8hi_v8hi;
+-	      break;
+-	    case V16QImode:
+-	      type = v16qi_ftype_v16qi_v16qi_v16qi;
+-	      break;
+-            case V2SFmode:
+-                type = v2sf_ftype_v2sf_v2sf_v2sf;
+-              break;
+-	    default:
+-	      gcc_unreachable ();
+-	    }
+-	}
+-      else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
+-	{
+-	  switch (mode0)
+-	    {
+-	    case V2DImode:
+-	      type = v2di_ftype_v2di_v2di_v16qi;
+-	      break;
+-	    case V2DFmode:
+-	      type = v2df_ftype_v2df_v2df_v16qi;
+-	      break;
+-	    case V4SImode:
+-	      type = v4si_ftype_v4si_v4si_v16qi;
+-	      break;
+-	    case V4SFmode:
+-	      type = v4sf_ftype_v4sf_v4sf_v16qi;
+-	      break;
+-	    case V8HImode:
+-	      type = v8hi_ftype_v8hi_v8hi_v16qi;
+-	      break;
+-	    case V16QImode:
+-	      type = v16qi_ftype_v16qi_v16qi_v16qi;
+-	      break;
+-	    default:
+-	      gcc_unreachable ();
+-	    }
+-	}
+-      else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
+-	       && mode3 == V4SImode)
+-	type = v4si_ftype_v16qi_v16qi_v4si;
+-      else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
+-	       && mode3 == V4SImode)
+-	type = v4si_ftype_v8hi_v8hi_v4si;
+-      else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
+-	       && mode3 == V4SImode)
+-	type = v4sf_ftype_v4sf_v4sf_v4si;
+-
+-      /* vchar, vchar, vchar, 4-bit literal.  */
+-      else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
+-	       && mode3 == QImode)
+-	type = v16qi_ftype_v16qi_v16qi_int;
+-
+-      /* vshort, vshort, vshort, 4-bit literal.  */
+-      else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
+-	       && mode3 == QImode)
+-	type = v8hi_ftype_v8hi_v8hi_int;
+-
+-      /* vint, vint, vint, 4-bit literal.  */
+-      else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
+-	       && mode3 == QImode)
+-	type = v4si_ftype_v4si_v4si_int;
+-
+-      /* vfloat, vfloat, vfloat, 4-bit literal.  */
+-      else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
+-	       && mode3 == QImode)
+-	type = v4sf_ftype_v4sf_v4sf_int;
+-
+-      else
+-	gcc_unreachable ();
+-
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ 
+-  /* Add the simple binary operators.  */
++  /* Add the binary operators.  */
+   d = (struct builtin_description *) bdesc_2arg;
+   for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+     {
+       enum machine_mode mode0, mode1, mode2;
+       tree type;
+-      bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+-			   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
++      int mask = d->mask;
+ 
+-      if (is_overloaded)
+-	{
+-	  mode0 = VOIDmode;
+-	  mode1 = VOIDmode;
+-	  mode2 = VOIDmode;
++      if ((mask != 0 && (mask & target_flags) == 0)
++	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
++	continue;
++
++      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
++	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
++	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
++	{
++	  if (! (type = opaque_ftype_opaque_opaque))
++	    type = opaque_ftype_opaque_opaque
++	      = build_function_type_list (opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  NULL_TREE);
+ 	}
+       else
+ 	{
+-          if (d->name == 0 || d->icode == CODE_FOR_nothing)
++	  enum insn_code icode = d->icode;
++          if (d->name == 0 || icode == CODE_FOR_nothing)
+ 	    continue;
+ 
+-          mode0 = insn_data[d->icode].operand[0].mode;
+-          mode1 = insn_data[d->icode].operand[1].mode;
+-          mode2 = insn_data[d->icode].operand[2].mode;
+-	}
++          mode0 = insn_data[icode].operand[0].mode;
++          mode1 = insn_data[icode].operand[1].mode;
++          mode2 = insn_data[icode].operand[2].mode;
+ 
+-      /* When all three operands are of the same mode.  */
+-      if (mode0 == mode1 && mode1 == mode2)
+-	{
+-	  switch (mode0)
++	  if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
+ 	    {
+-	    case VOIDmode:
+-	      type = opaque_ftype_opaque_opaque;
+-	      break;
+-	    case V2DFmode:
+-	      type = v2df_ftype_v2df_v2df;
+-	      break;
+-	    case V4SFmode:
+-	      type = v4sf_ftype_v4sf_v4sf;
+-	      break;
+-	    case V4SImode:
+-	      type = v4si_ftype_v4si_v4si;
+-	      break;
+-	    case V16QImode:
+-	      type = v16qi_ftype_v16qi_v16qi;
+-	      break;
+-	    case V8HImode:
+-	      type = v8hi_ftype_v8hi_v8hi;
+-	      break;
+-	    case V2SImode:
+-	      type = v2si_ftype_v2si_v2si;
+-	      break;
+-            case V2SFmode:
+-              if (TARGET_PAIRED_FLOAT)
+-                type = v2sf_ftype_v2sf_v2sf;
+-              else
+-                type = v2sf_ftype_v2sf_v2sf_spe;
+-	      break;
+-	    case SImode:
+-	      type = int_ftype_int_int;
+-	      break;
+-	    default:
+-	      gcc_unreachable ();
++	      if (! (type = v2si_ftype_v2si_qi))
++		type = v2si_ftype_v2si_qi
++		  = build_function_type_list (opaque_V2SI_type_node,
++					      opaque_V2SI_type_node,
++					      char_type_node,
++					      NULL_TREE);
+ 	    }
+-	}
+-
+-      /* A few other combos we really don't want to do manually.  */
+-
+-      /* vint, vfloat, vfloat.  */
+-      else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
+-	type = v4si_ftype_v4sf_v4sf;
+-
+-      /* vshort, vchar, vchar.  */
+-      else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
+-	type = v8hi_ftype_v16qi_v16qi;
+-
+-      /* vint, vshort, vshort.  */
+-      else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
+-	type = v4si_ftype_v8hi_v8hi;
+-
+-      /* vshort, vint, vint.  */
+-      else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
+-	type = v8hi_ftype_v4si_v4si;
+-
+-      /* vchar, vshort, vshort.  */
+-      else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
+-	type = v16qi_ftype_v8hi_v8hi;
+-
+-      /* vint, vchar, vint.  */
+-      else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
+-	type = v4si_ftype_v16qi_v4si;
+-
+-      /* vint, vchar, vchar.  */
+-      else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
+-	type = v4si_ftype_v16qi_v16qi;
+-
+-      /* vint, vshort, vint.  */
+-      else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
+-	type = v4si_ftype_v8hi_v4si;
+ 
+-      /* vint, vint, 5-bit literal.  */
+-      else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
+-	type = v4si_ftype_v4si_int;
+-
+-      /* vshort, vshort, 5-bit literal.  */
+-      else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
+-	type = v8hi_ftype_v8hi_int;
+-
+-      /* vchar, vchar, 5-bit literal.  */
+-      else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
+-	type = v16qi_ftype_v16qi_int;
+-
+-      /* vfloat, vint, 5-bit literal.  */
+-      else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
+-	type = v4sf_ftype_v4si_int;
+-
+-      /* vint, vfloat, 5-bit literal.  */
+-      else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
+-	type = v4si_ftype_v4sf_int;
+-
+-      else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
+-	type = v2si_ftype_int_int;
+-
+-      else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
+-	type = v2si_ftype_v2si_char;
+-
+-      else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
+-	type = v2si_ftype_int_char;
+-
+-      else
+-	{
+-	  /* int, x, x.  */
+-	  gcc_assert (mode0 == SImode);
+-	  switch (mode1)
++	  else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
++		   && mode2 == QImode)
+ 	    {
+-	    case V4SImode:
+-	      type = int_ftype_v4si_v4si;
+-	      break;
+-	    case V4SFmode:
+-	      type = int_ftype_v4sf_v4sf;
+-	      break;
+-	    case V16QImode:
+-	      type = int_ftype_v16qi_v16qi;
+-	      break;
+-	    case V8HImode:
+-	      type = int_ftype_v8hi_v8hi;
+-	      break;
+-	    default:
+-	      gcc_unreachable ();
++	      if (! (type = v2si_ftype_int_qi))
++		type = v2si_ftype_int_qi
++		  = build_function_type_list (opaque_V2SI_type_node,
++					      integer_type_node,
++					      char_type_node,
++					      NULL_TREE);
+ 	    }
++
++	  else
++	    type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
++					  d->name);
+ 	}
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+ 
+-  /* Add the simple unary operators.  */
++  /* Add the unary operators.  */
+   d = (struct builtin_description *) bdesc_1arg;
+   for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+     {
+       enum machine_mode mode0, mode1;
+       tree type;
+-      bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+-			   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
++      int mask = d->mask;
+ 
+-      if (is_overloaded)
+-        {
+-          mode0 = VOIDmode;
+-          mode1 = VOIDmode;
+-        }
++      if ((mask != 0 && (mask & target_flags) == 0)
++	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
++	continue;
++
++      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
++	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
++	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
++	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
++	{
++	  if (! (type = opaque_ftype_opaque))
++	    type = opaque_ftype_opaque
++	      = build_function_type_list (opaque_V4SI_type_node,
++					  opaque_V4SI_type_node,
++					  NULL_TREE);
++	}
+       else
+         {
+-          if (d->name == 0 || d->icode == CODE_FOR_nothing)
++	  enum insn_code icode = d->icode;
++          if (d->name == 0 || icode == CODE_FOR_nothing)
+ 	    continue;
+ 
+-          mode0 = insn_data[d->icode].operand[0].mode;
+-          mode1 = insn_data[d->icode].operand[1].mode;
+-        }
++          mode0 = insn_data[icode].operand[0].mode;
++          mode1 = insn_data[icode].operand[1].mode;
+ 
+-      if (mode0 == V4SImode && mode1 == QImode)
+-	type = v4si_ftype_int;
+-      else if (mode0 == V8HImode && mode1 == QImode)
+-	type = v8hi_ftype_int;
+-      else if (mode0 == V16QImode && mode1 == QImode)
+-	type = v16qi_ftype_int;
+-      else if (mode0 == VOIDmode && mode1 == VOIDmode)
+-	type = opaque_ftype_opaque;
+-      else if (mode0 == V2DFmode && mode1 == V2DFmode)
+-	type = v2df_ftype_v2df;
+-      else if (mode0 == V4SFmode && mode1 == V4SFmode)
+-	type = v4sf_ftype_v4sf;
+-      else if (mode0 == V8HImode && mode1 == V16QImode)
+-	type = v8hi_ftype_v16qi;
+-      else if (mode0 == V4SImode && mode1 == V8HImode)
+-	type = v4si_ftype_v8hi;
+-      else if (mode0 == V2SImode && mode1 == V2SImode)
+-	type = v2si_ftype_v2si;
+-      else if (mode0 == V2SFmode && mode1 == V2SFmode)
+-        {
+-          if (TARGET_PAIRED_FLOAT)
+-            type = v2sf_ftype_v2sf;
+-          else
+-            type = v2sf_ftype_v2sf_spe;
+-        }
+-      else if (mode0 == V2SFmode && mode1 == V2SImode)
+-	type = v2sf_ftype_v2si;
+-      else if (mode0 == V2SImode && mode1 == V2SFmode)
+-	type = v2si_ftype_v2sf;
+-      else if (mode0 == V2SImode && mode1 == QImode)
+-	type = v2si_ftype_char;
+-      else if (mode0 == V4SImode && mode1 == V4SFmode)
+-	type = v4si_ftype_v4sf;
+-      else if (mode0 == V4SFmode && mode1 == V4SImode)
+-	type = v4sf_ftype_v4si;
+-      else if (mode0 == V2DImode && mode1 == V2DFmode)
+-	type = v2di_ftype_v2df;
+-      else if (mode0 == V2DFmode && mode1 == V2DImode)
+-	type = v2df_ftype_v2di;
+-      else
+-	gcc_unreachable ();
++	  if (mode0 == V2SImode && mode1 == QImode)
++	    {
++	      if (! (type = v2si_ftype_qi))
++		type = v2si_ftype_qi
++		  = build_function_type_list (opaque_V2SI_type_node,
++					      char_type_node,
++					      NULL_TREE);
++	    }
++
++	  else
++	    type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
++					  d->name);
++	}
+ 
+       def_builtin (d->mask, d->name, type, d->code);
+     }
+@@ -12618,12 +12538,12 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 	}
+ 
+       if (GET_CODE (addr) == PLUS
+-	  && (!rs6000_legitimate_offset_address_p (TImode, addr, true)
++	  && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
+ 	      || and_op2 != NULL_RTX))
+ 	{
+ 	  addr_op1 = XEXP (addr, 0);
+ 	  addr_op2 = XEXP (addr, 1);
+-	  gcc_assert (legitimate_indirect_address_p (addr_op1, true));
++	  gcc_assert (legitimate_indirect_address_p (addr_op1, false));
+ 
+ 	  if (!REG_P (addr_op2)
+ 	      && (GET_CODE (addr_op2) != CONST_INT
+@@ -12642,8 +12562,8 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 	  addr = scratch_or_premodify;
+ 	  scratch_or_premodify = scratch;
+ 	}
+-      else if (!legitimate_indirect_address_p (addr, true)
+-	       && !rs6000_legitimate_offset_address_p (TImode, addr, true))
++      else if (!legitimate_indirect_address_p (addr, false)
++	       && !rs6000_legitimate_offset_address_p (TImode, addr, false))
+ 	{
+ 	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
+ 	  addr = scratch_or_premodify;
+@@ -12672,24 +12592,24 @@ rs6000_secondary_reload_inner (rtx reg, 
+       if (GET_CODE (addr) == PRE_MODIFY
+ 	  && (!VECTOR_MEM_VSX_P (mode)
+ 	      || and_op2 != NULL_RTX
+-	      || !legitimate_indexed_address_p (XEXP (addr, 1), true)))
++	      || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
+ 	{
+ 	  scratch_or_premodify = XEXP (addr, 0);
+ 	  gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
+-						     true));
++						     false));
+ 	  gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
+ 	  addr = XEXP (addr, 1);
+ 	}
+ 
+-      if (legitimate_indirect_address_p (addr, true)	/* reg */
+-	  || legitimate_indexed_address_p (addr, true)	/* reg+reg */
++      if (legitimate_indirect_address_p (addr, false)	/* reg */
++	  || legitimate_indexed_address_p (addr, false)	/* reg+reg */
+ 	  || GET_CODE (addr) == PRE_MODIFY		/* VSX pre-modify */
+ 	  || GET_CODE (addr) == AND			/* Altivec memory */
+ 	  || (rclass == FLOAT_REGS			/* legacy float mem */
+ 	      && GET_MODE_SIZE (mode) == 8
+ 	      && and_op2 == NULL_RTX
+ 	      && scratch_or_premodify == scratch
+-	      && rs6000_legitimate_offset_address_p (mode, addr, true)))
++	      && rs6000_legitimate_offset_address_p (mode, addr, false)))
+ 	;
+ 
+       else if (GET_CODE (addr) == PLUS)
+@@ -12709,7 +12629,7 @@ rs6000_secondary_reload_inner (rtx reg, 
+ 	}
+ 
+       else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
+-	       || GET_CODE (addr) == CONST_INT)
++	       || GET_CODE (addr) == CONST_INT || REG_P (addr))
+ 	{
+ 	  rs6000_emit_move (scratch_or_premodify, addr, Pmode);
+ 	  addr = scratch_or_premodify;
+@@ -12741,7 +12661,7 @@ rs6000_secondary_reload_inner (rtx reg, 
+      andi. instruction.  */
+   if (and_op2 != NULL_RTX)
+     {
+-      if (! legitimate_indirect_address_p (addr, true))
++      if (! legitimate_indirect_address_p (addr, false))
+ 	{
+ 	  emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
+ 	  addr = scratch;
+@@ -12776,6 +12696,26 @@ rs6000_secondary_reload_inner (rtx reg, 
+   return;
+ }
+ 
++/* Target hook to return the cover classes for Integrated Register Allocator.
++   Cover classes is a set of non-intersected register classes covering all hard
++   registers used for register allocation purpose.  Any move between two
++   registers of a cover class should be cheaper than load or store of the
++   registers.  The value is array of register classes with LIM_REG_CLASSES used
++   as the end marker.
++
++   We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
++   account for the Altivec and Floating registers being subsets of the VSX
++   register set under VSX, but distinct register sets on pre-VSX machines.  */
++
++static const enum reg_class *
++rs6000_ira_cover_classes (void)
++{
++  static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
++  static const enum reg_class cover_vsx[]     = IRA_COVER_CLASSES_VSX;
++
++  return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
++}
++
+ /* Allocate a 64-bit stack slot to be used for copying SDmode
+    values through if this function has any SDmode references.  */
+ 
+@@ -12849,13 +12789,15 @@ rs6000_preferred_reload_class (rtx x, en
+   enum machine_mode mode = GET_MODE (x);
+   enum reg_class ret;
+ 
+-  if (TARGET_VSX && VSX_VECTOR_MODE (mode) && x == CONST0_RTX (mode)
+-      && VSX_REG_CLASS_P (rclass))
++  if (TARGET_VSX
++      && (VSX_VECTOR_MODE (mode) || mode == TImode)
++      && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
+     ret = rclass;
+ 
+-  else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode)
+-	   && rclass == ALTIVEC_REGS && easy_vector_constant (x, mode))
+-    ret = rclass;
++  else if (TARGET_ALTIVEC && (ALTIVEC_VECTOR_MODE (mode) || mode == TImode)
++	   && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
++	   && easy_vector_constant (x, mode))
++    ret = ALTIVEC_REGS;
+ 
+   else if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
+     ret = NO_REGS;
+@@ -13074,8 +13016,10 @@ rs6000_cannot_change_mode_class (enum ma
+ 		       || (((to) == TDmode) + ((from) == TDmode)) == 1
+ 		       || (((to) == DImode) + ((from) == DImode)) == 1))
+ 		  || (TARGET_VSX
+-		      && (VSX_VECTOR_MODE (from) + VSX_VECTOR_MODE (to)) == 1)
++		      && (VSX_MOVE_MODE (from) + VSX_MOVE_MODE (to)) == 1
++		      && VSX_REG_CLASS_P (rclass))
+ 		  || (TARGET_ALTIVEC
++		      && rclass == ALTIVEC_REGS
+ 		      && (ALTIVEC_VECTOR_MODE (from)
+ 			  + ALTIVEC_VECTOR_MODE (to)) == 1)
+ 		  || (TARGET_SPE
+@@ -14953,7 +14897,7 @@ rs6000_emit_vector_cond_expr (rtx dest, 
+   if (!mask)
+     return 0;
+ 
+-  if ((TARGET_VSX && VSX_VECTOR_MOVE_MODE (dest_mode))
++  if ((TARGET_VSX && VSX_MOVE_MODE (dest_mode))
+       || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (dest_mode)))
+     {
+       rtx cond2 = gen_rtx_fmt_ee (NE, VOIDmode, mask, const0_rtx);
+@@ -22044,7 +21988,8 @@ rs6000_handle_altivec_attribute (tree *n
+   mode = TYPE_MODE (type);
+ 
+   /* Check for invalid AltiVec type qualifiers.  */
+-  if (type == long_unsigned_type_node || type == long_integer_type_node)
++  if ((type == long_unsigned_type_node || type == long_integer_type_node)
++      && !TARGET_VSX)
+     {
+     if (TARGET_64BIT)
+       error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
+@@ -22082,6 +22027,7 @@ rs6000_handle_altivec_attribute (tree *n
+ 	  break;
+ 	case SFmode: result = V4SF_type_node; break;
+ 	case DFmode: result = V2DF_type_node; break;
++	case DImode: result = V2DI_type_node; break;
+ 	  /* If the user says 'vector int bool', we may be handed the 'bool'
+ 	     attribute _before_ the 'vector' attribute, and so select the
+ 	     proper type in the 'b' case below.  */
+@@ -22093,6 +22039,7 @@ rs6000_handle_altivec_attribute (tree *n
+     case 'b':
+       switch (mode)
+ 	{
++	case DImode: case V2DImode: result = bool_V2DI_type_node; break;
+ 	case SImode: case V4SImode: result = bool_V4SI_type_node; break;
+ 	case HImode: case V8HImode: result = bool_V8HI_type_node; break;
+ 	case QImode: case V16QImode: result = bool_V16QI_type_node;
+@@ -22137,6 +22084,7 @@ rs6000_mangle_type (const_tree type)
+   if (type == bool_short_type_node) return "U6__bools";
+   if (type == pixel_type_node) return "u7__pixel";
+   if (type == bool_int_type_node) return "U6__booli";
++  if (type == bool_long_type_node) return "U6__booll";
+ 
+   /* Mangle IBM extended float long double as `g' (__float128) on
+      powerpc*-linux where long-double-64 previously was the default.  */
+@@ -23647,6 +23595,8 @@ int
+ rs6000_register_move_cost (enum machine_mode mode,
+ 			   enum reg_class from, enum reg_class to)
+ {
++  int ret;
++
+   /*  Moves from/to GENERAL_REGS.  */
+   if (reg_classes_intersect_p (to, GENERAL_REGS)
+       || reg_classes_intersect_p (from, GENERAL_REGS))
+@@ -23655,39 +23605,47 @@ rs6000_register_move_cost (enum machine_
+ 	from = to;
+ 
+       if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
+-	return (rs6000_memory_move_cost (mode, from, 0)
+-		+ rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
++	ret = (rs6000_memory_move_cost (mode, from, 0)
++	       + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
+ 
+       /* It's more expensive to move CR_REGS than CR0_REGS because of the
+ 	 shift.  */
+       else if (from == CR_REGS)
+-	return 4;
++	ret = 4;
+ 
+       /* Power6 has slower LR/CTR moves so make them more expensive than
+ 	 memory in order to bias spills to memory .*/
+       else if (rs6000_cpu == PROCESSOR_POWER6
+ 	       && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
+-        return 6 * hard_regno_nregs[0][mode];
++        ret = 6 * hard_regno_nregs[0][mode];
+ 
+       else
+ 	/* A move will cost one instruction per GPR moved.  */
+-	return 2 * hard_regno_nregs[0][mode];
++	ret = 2 * hard_regno_nregs[0][mode];
+     }
+ 
+   /* If we have VSX, we can easily move between FPR or Altivec registers.  */
+-  else if (TARGET_VSX
+-	   && ((from == VSX_REGS || from == FLOAT_REGS || from == ALTIVEC_REGS)
+-	       || (to == VSX_REGS || to == FLOAT_REGS || to == ALTIVEC_REGS)))
+-    return 2;
++  else if (VECTOR_UNIT_VSX_P (mode)
++	   && reg_classes_intersect_p (to, VSX_REGS)
++	   && reg_classes_intersect_p (from, VSX_REGS))
++    ret = 2 * hard_regno_nregs[32][mode];
+ 
+   /* Moving between two similar registers is just one instruction.  */
+   else if (reg_classes_intersect_p (to, from))
+-    return (mode == TFmode || mode == TDmode) ? 4 : 2;
++    ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
+ 
+   /* Everything else has to go through GENERAL_REGS.  */
+   else
+-    return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
+-	    + rs6000_register_move_cost (mode, from, GENERAL_REGS));
++    ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
++	   + rs6000_register_move_cost (mode, from, GENERAL_REGS));
++
++  if (TARGET_DEBUG_COST)
++    fprintf (stderr,
++	     "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
++	     ret, GET_MODE_NAME (mode), reg_class_names[from],
++	     reg_class_names[to]);
++
++  return ret;
+ }
+ 
+ /* A C expressions returning the cost of moving data of MODE from a register to
+@@ -23697,14 +23655,23 @@ int
+ rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
+ 			 int in ATTRIBUTE_UNUSED)
+ {
++  int ret;
++
+   if (reg_classes_intersect_p (rclass, GENERAL_REGS))
+-    return 4 * hard_regno_nregs[0][mode];
++    ret = 4 * hard_regno_nregs[0][mode];
+   else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
+-    return 4 * hard_regno_nregs[32][mode];
++    ret = 4 * hard_regno_nregs[32][mode];
+   else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
+-    return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
++    ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
+   else
+-    return 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
++    ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
++
++  if (TARGET_DEBUG_COST)
++    fprintf (stderr,
++	     "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
++	     ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
++
++  return ret;
+ }
+ 
+ /* Returns a code for a target-specific builtin that implements
+@@ -24424,4 +24391,24 @@ rs6000_final_prescan_insn (rtx insn, rtx
+     }
+ }
+ 
++/* Return true if the function has an indirect jump or a table jump.  The compiler
++   prefers the ctr register for such jumps, which interferes with using the decrement
++   ctr register and branch.  */
++
++bool
++rs6000_has_indirect_jump_p (void)
++{
++  gcc_assert (cfun && cfun->machine);
++  return cfun->machine->indirect_jump_p;
++}
++
++/* Remember when we've generated an indirect jump.  */
++
++void
++rs6000_set_indirect_jump (void)
++{
++  gcc_assert (cfun && cfun->machine);
++  cfun->machine->indirect_jump_p = true;
++}
++
+ #include "gt-rs6000.h"
+--- gcc/config/rs6000/vsx.md	(revision 146119)
++++ gcc/config/rs6000/vsx.md	(revision 146798)
+@@ -22,12 +22,22 @@
+ ;; Iterator for both scalar and vector floating point types supported by VSX
+ (define_mode_iterator VSX_B [DF V4SF V2DF])
+ 
++;; Iterator for the 2 64-bit vector types
++(define_mode_iterator VSX_D [V2DF V2DI])
++
++;; Iterator for the 2 32-bit vector types
++(define_mode_iterator VSX_W [V4SF V4SI])
++
+ ;; Iterator for vector floating point types supported by VSX
+ (define_mode_iterator VSX_F [V4SF V2DF])
+ 
+ ;; Iterator for logical types supported by VSX
+ (define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
+ 
++;; Iterator for memory move.  Handle TImode specially to allow
++;; it to use gprs as well as vsx registers.
++(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
++
+ ;; Iterator for types for load/store with update
+ (define_mode_iterator VSX_U [V16QI V8HI V4SI V2DI V4SF V2DF TI DF])
+ 
+@@ -49,9 +59,10 @@ (define_mode_attr VSs	[(V16QI "sp")
+ 			 (V2DF  "dp")
+ 			 (V2DI  "dp")
+ 			 (DF    "dp")
++			 (SF	"sp")
+ 			 (TI    "sp")])
+ 
+-;; Map into the register class used
++;; Map the register class used
+ (define_mode_attr VSr	[(V16QI "v")
+ 			 (V8HI  "v")
+ 			 (V4SI  "v")
+@@ -59,9 +70,10 @@ (define_mode_attr VSr	[(V16QI "v")
+ 			 (V2DI  "wd")
+ 			 (V2DF  "wd")
+ 			 (DF    "ws")
++			 (SF	"f")
+ 			 (TI    "wd")])
+ 
+-;; Map into the register class used for float<->int conversions
++;; Map the register class used for float<->int conversions
+ (define_mode_attr VSr2	[(V2DF  "wd")
+ 			 (V4SF  "wf")
+ 			 (DF    "!f#r")])
+@@ -70,6 +82,18 @@ (define_mode_attr VSr3	[(V2DF  "wa")
+ 			 (V4SF  "wa")
+ 			 (DF    "!f#r")])
+ 
++;; Map the register class for sp<->dp float conversions, destination
++(define_mode_attr VSr4	[(SF	"ws")
++			 (DF	"f")
++			 (V2DF  "wd")
++			 (V4SF	"v")])
++
++;; Map the register class for sp<->dp float conversions, destination
++(define_mode_attr VSr5	[(SF	"ws")
++			 (DF	"f")
++			 (V2DF  "v")
++			 (V4SF	"wd")])
++
+ ;; Same size integer type for floating point data
+ (define_mode_attr VSi [(V4SF  "v4si")
+ 		       (V2DF  "v2di")
+@@ -137,6 +161,32 @@ (define_mode_attr VSfptype_sqrt	[(V2DF "
+ 				 (V4SF "fp_sqrt_s")
+ 				 (DF   "fp_sqrt_d")])
+ 
++;; Iterator and modes for sp<->dp conversions
++(define_mode_iterator VSX_SPDP [SF DF V4SF V2DF])
++
++(define_mode_attr VS_spdp_res [(SF	"DF")
++			       (DF	"SF")
++			       (V4SF	"V2DF")
++			       (V2DF	"V4SF")])
++
++(define_mode_attr VS_spdp_insn [(SF	"xscvspdp")
++				(DF	"xscvdpsp")
++				(V4SF	"xvcvspdp")
++				(V2DF	"xvcvdpsp")])
++
++(define_mode_attr VS_spdp_type [(SF	"fp")
++				(DF	"fp")
++				(V4SF	"vecfloat")
++				(V2DF	"vecfloat")])
++
++;; Map the scalar mode for a vector type
++(define_mode_attr VS_scalar [(V2DF	"DF")
++			     (V2DI	"DI")
++			     (V4SF	"SF")
++			     (V4SI	"SI")
++			     (V8HI	"HI")
++			     (V16QI	"QI")])
++			     
+ ;; Appropriate type for load + update
+ (define_mode_attr VStype_load_update [(V16QI "vecload")
+ 				      (V8HI  "vecload")
+@@ -159,25 +209,33 @@ (define_mode_attr VStype_store_update [(
+ 
+ ;; Constants for creating unspecs
+ (define_constants
+-  [(UNSPEC_VSX_CONCAT_V2DF	500)
+-   (UNSPEC_VSX_XVCVDPSP		501)
+-   (UNSPEC_VSX_XVCVDPSXWS	502)
+-   (UNSPEC_VSX_XVCVDPUXWS	503)
+-   (UNSPEC_VSX_XVCVSPDP		504)
+-   (UNSPEC_VSX_XVCVSXWDP	505)
+-   (UNSPEC_VSX_XVCVUXWDP	506)
+-   (UNSPEC_VSX_XVMADD		507)
+-   (UNSPEC_VSX_XVMSUB		508)
+-   (UNSPEC_VSX_XVNMADD		509)
+-   (UNSPEC_VSX_XVNMSUB		510)
+-   (UNSPEC_VSX_XVRSQRTE		511)
+-   (UNSPEC_VSX_XVTDIV		512)
+-   (UNSPEC_VSX_XVTSQRT		513)])
++  [(UNSPEC_VSX_CONCAT		500)
++   (UNSPEC_VSX_CVDPSXWS		501)
++   (UNSPEC_VSX_CVDPUXWS		502)
++   (UNSPEC_VSX_CVSPDP		503)
++   (UNSPEC_VSX_CVSXWDP		504)
++   (UNSPEC_VSX_CVUXWDP		505)
++   (UNSPEC_VSX_CVSXDSP		506)
++   (UNSPEC_VSX_CVUXDSP		507)
++   (UNSPEC_VSX_CVSPSXDS		508)
++   (UNSPEC_VSX_CVSPUXDS		509)
++   (UNSPEC_VSX_MADD		510)
++   (UNSPEC_VSX_MSUB		511)
++   (UNSPEC_VSX_NMADD		512)
++   (UNSPEC_VSX_NMSUB		513)
++   (UNSPEC_VSX_RSQRTE		514)
++   (UNSPEC_VSX_TDIV		515)
++   (UNSPEC_VSX_TSQRT		516)
++   (UNSPEC_VSX_XXPERMDI		517)
++   (UNSPEC_VSX_SET		518)
++   (UNSPEC_VSX_ROUND_I		519)
++   (UNSPEC_VSX_ROUND_IC		520)
++   (UNSPEC_VSX_SLDWI		521)])
+ 
+ ;; VSX moves
+ (define_insn "*vsx_mov<mode>"
+-  [(set (match_operand:VSX_L 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?wa,?wa,*o,*r,*r,<VSr>,?wa,v,wZ,v")
+-	(match_operand:VSX_L 1 "input_operand" "<VSr>,Z,<VSr>,wa,Z,wa,r,o,r,j,j,W,v,wZ"))]
++  [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?wa,?wa,*o,*r,*r,<VSr>,?wa,v,wZ,v")
++	(match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,wa,Z,wa,r,o,r,j,j,W,v,wZ"))]
+   "VECTOR_MEM_VSX_P (<MODE>mode)
+    && (register_operand (operands[0], <MODE>mode) 
+        || register_operand (operands[1], <MODE>mode))"
+@@ -220,6 +278,49 @@ (define_insn "*vsx_mov<mode>"
+ }
+   [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")])
+ 
++;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for
++;; unions.  However for plain data movement, slightly favor the vector loads
++(define_insn "*vsx_movti"
++  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?o,?r,?r,wa,v,v,wZ")
++	(match_operand:TI 1 "input_operand" "wa,Z,wa,r,o,r,j,W,wZ,v"))]
++  "VECTOR_MEM_VSX_P (TImode)
++   && (register_operand (operands[0], TImode) 
++       || register_operand (operands[1], TImode))"
++{
++  switch (which_alternative)
++    {
++    case 0:
++      return "stxvd2%U0x %x1,%y0";
++
++    case 1:
++      return "lxvd2%U0x %x0,%y1";
++
++    case 2:
++      return "xxlor %x0,%x1,%x1";
++
++    case 3:
++    case 4:
++    case 5:
++      return "#";
++
++    case 6:
++      return "xxlxor %x0,%x0,%x0";
++
++    case 7:
++      return output_vec_const_move (operands);
++
++    case 8:
++      return "stvx %1,%y0";
++
++    case 9:
++      return "lvx %0,%y1";
++
++    default:
++      gcc_unreachable ();
++    }
++}
++  [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")])
++
+ ;; Load/store with update
+ ;; Define insns that do load or store with update.  Because VSX only has
+ ;; reg+reg addressing, pre-decrement or pre-inrement is unlikely to be
+@@ -297,7 +398,7 @@ (define_insn "vsx_tdiv<mode>3"
+   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
+ 		       (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")]
+-		      UNSPEC_VSX_XVTDIV))]
++		      UNSPEC_VSX_TDIV))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "x<VSv>tdiv<VSs> %x0,%x1,%x2"
+   [(set_attr "type" "<VStype_simple>")
+@@ -367,7 +468,7 @@ (define_insn "*vsx_sqrt<mode>2"
+ (define_insn "vsx_rsqrte<mode>2"
+   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
+-		      UNSPEC_VSX_XVRSQRTE))]
++		      UNSPEC_VSX_RSQRTE))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "x<VSv>rsqrte<VSs> %x0,%x1"
+   [(set_attr "type" "<VStype_simple>")
+@@ -376,7 +477,7 @@ (define_insn "vsx_rsqrte<mode>2"
+ (define_insn "vsx_tsqrt<mode>2"
+   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
+-		      UNSPEC_VSX_XVTSQRT))]
++		      UNSPEC_VSX_TSQRT))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "x<VSv>tsqrt<VSs> %x0,%x1"
+   [(set_attr "type" "<VStype_simple>")
+@@ -426,7 +527,7 @@ (define_insn "vsx_fmadd<mode>4_2"
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ 		       (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ 		       (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
+-		      UNSPEC_VSX_XVMADD))]
++		      UNSPEC_VSX_MADD))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "@
+    x<VSv>madda<VSs> %x0,%x1,%x2
+@@ -474,7 +575,7 @@ (define_insn "vsx_fmsub<mode>4_2"
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ 		       (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ 		       (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
+-		      UNSPEC_VSX_XVMSUB))]
++		      UNSPEC_VSX_MSUB))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "@
+    x<VSv>msuba<VSs> %x0,%x1,%x2
+@@ -552,7 +653,7 @@ (define_insn "vsx_fnmadd<mode>4_3"
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa")
+ 		       (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ 		       (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
+-		      UNSPEC_VSX_XVNMADD))]
++		      UNSPEC_VSX_NMADD))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "@
+    x<VSv>nmadda<VSs> %x0,%x1,%x2
+@@ -629,7 +730,7 @@ (define_insn "vsx_fnmsub<mode>4_3"
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ 		       (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ 		       (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
+-		      UNSPEC_VSX_XVNMSUB))]
++		      UNSPEC_VSX_NMSUB))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "@
+    x<VSv>nmsuba<VSs> %x0,%x1,%x2
+@@ -667,13 +768,13 @@ (define_insn "*vsx_ge<mode>"
+   [(set_attr "type" "<VStype_simple>")
+    (set_attr "fp_type" "<VSfptype_simple>")])
+ 
+-(define_insn "vsx_vsel<mode>"
+-  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
+-	(if_then_else:VSX_F (ne (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
++(define_insn "*vsx_vsel<mode>"
++  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa")
++	(if_then_else:VSX_L (ne (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa")
+ 				(const_int 0))
+-			    (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")
+-			    (match_operand:VSX_F 3 "vsx_register_operand" "<VSr>,wa")))]
+-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
++			    (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa")
++			    (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxsel %x0,%x3,%x2,%x1"
+   [(set_attr "type" "vecperm")])
+ 
+@@ -698,7 +799,7 @@ (define_insn "vsx_ftrunc<mode>2"
+   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+   	(fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
+   "VECTOR_UNIT_VSX_P (<MODE>mode)"
+-  "x<VSv>r<VSs>piz %x0,%x1"
++  "x<VSv>r<VSs>iz %x0,%x1"
+   [(set_attr "type" "<VStype_simple>")
+    (set_attr "fp_type" "<VSfptype_simple>")])
+ 
+@@ -735,6 +836,24 @@ (define_insn "vsx_fixuns_trunc<mode><VSi
+    (set_attr "fp_type" "<VSfptype_simple>")])
+ 
+ ;; Math rounding functions
++(define_insn "vsx_x<VSv>r<VSs>i"
++  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
++	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
++		      UNSPEC_VSX_ROUND_I))]
++  "VECTOR_UNIT_VSX_P (<MODE>mode)"
++  "x<VSv>r<VSs>i %x0,%x1"
++  [(set_attr "type" "<VStype_simple>")
++   (set_attr "fp_type" "<VSfptype_simple>")])
++
++(define_insn "vsx_x<VSv>r<VSs>ic"
++  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
++	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
++		      UNSPEC_VSX_ROUND_IC))]
++  "VECTOR_UNIT_VSX_P (<MODE>mode)"
++  "x<VSv>r<VSs>ic %x0,%x1"
++  [(set_attr "type" "<VStype_simple>")
++   (set_attr "fp_type" "<VSfptype_simple>")])
++
+ (define_insn "vsx_btrunc<mode>2"
+   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+ 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
+@@ -765,22 +884,26 @@ (define_insn "vsx_ceil<mode>2"
+ \f
+ ;; VSX convert to/from double vector
+ 
++;; Convert between single and double precision
++;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal
++;; scalar single precision instructions internally use the double format.
++;; Prefer the altivec registers, since we likely will need to do a vperm
++(define_insn "vsx_<VS_spdp_insn>"
++  [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?wa")
++	(unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,wa")]
++			      UNSPEC_VSX_CVSPDP))]
++  "VECTOR_UNIT_VSX_P (<MODE>mode)"
++  "<VS_spdp_insn> %x0,%x1"
++  [(set_attr "type" "<VS_spdp_type>")])
++
+ ;; Convert from 64-bit to 32-bit types
+ ;; Note, favor the Altivec registers since the usual use of these instructions
+ ;; is in vector converts and we need to use the Altivec vperm instruction.
+ 
+-(define_insn "vsx_xvcvdpsp"
+-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=v,?wa")
+-	(unspec:V4SF [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
+-		     UNSPEC_VSX_XVCVDPSP))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
+-  "xvcvdpsp %x0,%x1"
+-  [(set_attr "type" "vecfloat")])
+-
+ (define_insn "vsx_xvcvdpsxws"
+   [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
+ 	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
+-		     UNSPEC_VSX_XVCVDPSXWS))]
++		     UNSPEC_VSX_CVDPSXWS))]
+   "VECTOR_UNIT_VSX_P (V2DFmode)"
+   "xvcvdpsxws %x0,%x1"
+   [(set_attr "type" "vecfloat")])
+@@ -788,24 +911,32 @@ (define_insn "vsx_xvcvdpsxws"
+ (define_insn "vsx_xvcvdpuxws"
+   [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
+ 	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
+-		     UNSPEC_VSX_XVCVDPUXWS))]
++		     UNSPEC_VSX_CVDPUXWS))]
+   "VECTOR_UNIT_VSX_P (V2DFmode)"
+   "xvcvdpuxws %x0,%x1"
+   [(set_attr "type" "vecfloat")])
+ 
+-;; Convert from 32-bit to 64-bit types
+-(define_insn "vsx_xvcvspdp"
+-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
+-	(unspec:V2DF [(match_operand:V4SF 1 "vsx_register_operand" "wf,wa")]
+-		     UNSPEC_VSX_XVCVSPDP))]
++(define_insn "vsx_xvcvsxdsp"
++  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
++	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
++		     UNSPEC_VSX_CVSXDSP))]
++  "VECTOR_UNIT_VSX_P (V2DFmode)"
++  "xvcvsxdsp %x0,%x1"
++  [(set_attr "type" "vecfloat")])
++
++(define_insn "vsx_xvcvuxdsp"
++  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
++	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
++		     UNSPEC_VSX_CVUXDSP))]
+   "VECTOR_UNIT_VSX_P (V2DFmode)"
+-  "xvcvspdp %x0,%x1"
++  "xvcvuxwdp %x0,%x1"
+   [(set_attr "type" "vecfloat")])
+ 
++;; Convert from 32-bit to 64-bit types
+ (define_insn "vsx_xvcvsxwdp"
+   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
+ 	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
+-		     UNSPEC_VSX_XVCVSXWDP))]
++		     UNSPEC_VSX_CVSXWDP))]
+   "VECTOR_UNIT_VSX_P (V2DFmode)"
+   "xvcvsxwdp %x0,%x1"
+   [(set_attr "type" "vecfloat")])
+@@ -813,11 +944,26 @@ (define_insn "vsx_xvcvsxwdp"
+ (define_insn "vsx_xvcvuxwdp"
+   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
+ 	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
+-		     UNSPEC_VSX_XVCVUXWDP))]
++		     UNSPEC_VSX_CVUXWDP))]
+   "VECTOR_UNIT_VSX_P (V2DFmode)"
+   "xvcvuxwdp %x0,%x1"
+   [(set_attr "type" "vecfloat")])
+ 
++(define_insn "vsx_xvcvspsxds"
++  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
++	(unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
++		     UNSPEC_VSX_CVSPSXDS))]
++  "VECTOR_UNIT_VSX_P (V2DFmode)"
++  "xvcvspsxds %x0,%x1"
++  [(set_attr "type" "vecfloat")])
++
++(define_insn "vsx_xvcvspuxds"
++  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
++	(unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
++		     UNSPEC_VSX_CVSPUXDS))]
++  "VECTOR_UNIT_VSX_P (V2DFmode)"
++  "xvcvspuxds %x0,%x1"
++  [(set_attr "type" "vecfloat")])
+ \f
+ ;; Logical and permute operations
+ (define_insn "*vsx_and<mode>3"
+@@ -877,24 +1023,25 @@ (define_insn "*vsx_andc<mode>3"
+ \f
+ ;; Permute operations
+ 
+-(define_insn "vsx_concat_v2df"
+-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
+-	(unspec:V2DF
+-	 [(match_operand:DF 1 "vsx_register_operand" "ws,wa")
+-	  (match_operand:DF 2 "vsx_register_operand" "ws,wa")]
+-	 UNSPEC_VSX_CONCAT_V2DF))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
++;; Build a V2DF/V2DI vector from two scalars
++(define_insn "vsx_concat_<mode>"
++  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
++	(unspec:VSX_D
++	 [(match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,wa")
++	  (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")]
++	 UNSPEC_VSX_CONCAT))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxpermdi %x0,%x1,%x2,0"
+   [(set_attr "type" "vecperm")])
+ 
+-;; Set a double into one element
+-(define_insn "vsx_set_v2df"
+-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
+-	(vec_merge:V2DF
+-	 (match_operand:V2DF 1 "vsx_register_operand" "wd,wa")
+-	 (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws,f"))
+-	 (match_operand:QI 3 "u5bit_cint_operand" "i,i")))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
++;; Set the element of a V2DI/VD2F mode
++(define_insn "vsx_set_<mode>"
++  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
++	(unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
++		       (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")
++		       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
++		      UNSPEC_VSX_SET))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+ {
+   if (INTVAL (operands[3]) == 0)
+     return \"xxpermdi %x0,%x1,%x2,1\";
+@@ -906,12 +1053,12 @@ (define_insn "vsx_set_v2df"
+   [(set_attr "type" "vecperm")])
+ 
+ ;; Extract a DF element from V2DF
+-(define_insn "vsx_extract_v2df"
+-  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,f,?wa")
+-	(vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd,wd,wa")
++(define_insn "vsx_extract_<mode>"
++  [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,f,?wa")
++	(vec_select:<VS_scalar> (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa")
+ 		       (parallel
+ 			[(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+ {
+   gcc_assert (UINTVAL (operands[2]) <= 1);
+   operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
+@@ -919,17 +1066,30 @@ (define_insn "vsx_extract_v2df"
+ }
+   [(set_attr "type" "vecperm")])
+ 
+-;; General V2DF permute, extract_{high,low,even,odd}
+-(define_insn "vsx_xxpermdi"
+-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd")
+-	(vec_concat:V2DF
+-	 (vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd")
+-			(parallel
+-			 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))
+-	 (vec_select:DF (match_operand:V2DF 3 "vsx_register_operand" "wd")
+-			(parallel
+-			 [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
++;; General V2DF/V2DI permute
++(define_insn "vsx_xxpermdi_<mode>"
++  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
++	(unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
++		       (match_operand:VSX_D 2 "vsx_register_operand" "wd,wa")
++		       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
++		      UNSPEC_VSX_XXPERMDI))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
++  "xxpermdi %x0,%x1,%x2,%3"
++  [(set_attr "type" "vecperm")])
++
++;; Varient of xxpermdi that is emitted by the vec_interleave functions
++(define_insn "*vsx_xxpermdi2_<mode>"
++  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
++	(vec_concat:VSX_D
++	 (vec_select:<VS_scalar>
++	  (match_operand:VSX_D 1 "vsx_register_operand" "wd")
++	  (parallel
++	   [(match_operand:QI 2 "u5bit_cint_operand" "i")]))
++	 (vec_select:<VS_scalar>
++	  (match_operand:VSX_D 3 "vsx_register_operand" "wd")
++	  (parallel
++	   [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+ {
+   gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
+   operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
+@@ -939,11 +1099,11 @@ (define_insn "vsx_xxpermdi"
+   [(set_attr "type" "vecperm")])
+ 
+ ;; V2DF splat
+-(define_insn "vsx_splatv2df"
+-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
+-	(vec_duplicate:V2DF
+-	 (match_operand:DF 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
+-  "VECTOR_UNIT_VSX_P (V2DFmode)"
++(define_insn "vsx_splat_<mode>"
++  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
++	(vec_duplicate:VSX_D
++	 (match_operand:<VS_scalar> 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
++  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "@
+    xxpermdi %x0,%x1,%x1,0
+    xxpermdi %x0,%x1,%x1,0
+@@ -953,52 +1113,66 @@ (define_insn "vsx_splatv2df"
+    lxvdsx %x0,%y1"
+   [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
+ 
+-;; V4SF splat
+-(define_insn "*vsx_xxspltw"
+-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa")
+-	(vec_duplicate:V4SF
+-	 (vec_select:SF (match_operand:V4SF 1 "vsx_register_operand" "wf,wa")
+-			(parallel
+-			 [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
+-  "VECTOR_UNIT_VSX_P (V4SFmode)"
++;; V4SF/V4SI splat
++(define_insn "vsx_xxspltw_<mode>"
++  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
++	(vec_duplicate:VSX_W
++	 (vec_select:<VS_scalar>
++	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
++	  (parallel
++	   [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxspltw %x0,%x1,%2"
+   [(set_attr "type" "vecperm")])
+ 
+-;; V4SF interleave
+-(define_insn "vsx_xxmrghw"
+-  [(set (match_operand:V4SF 0 "register_operand" "=wf,?wa")
+-        (vec_merge:V4SF
+-	 (vec_select:V4SF (match_operand:V4SF 1 "vsx_register_operand" "wf,wa")
+-			  (parallel [(const_int 0)
+-				     (const_int 2)
+-				     (const_int 1)
+-				     (const_int 3)]))
+-	 (vec_select:V4SF (match_operand:V4SF 2 "vsx_register_operand" "wf,wa")
+-			  (parallel [(const_int 2)
+-				     (const_int 0)
+-				     (const_int 3)
+-				     (const_int 1)]))
++;; V4SF/V4SI interleave
++(define_insn "vsx_xxmrghw_<mode>"
++  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
++        (vec_merge:VSX_W
++	 (vec_select:VSX_W
++	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
++	  (parallel [(const_int 0)
++		     (const_int 2)
++		     (const_int 1)
++		     (const_int 3)]))
++	 (vec_select:VSX_W
++	  (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")
++	  (parallel [(const_int 2)
++		     (const_int 0)
++		     (const_int 3)
++		     (const_int 1)]))
+ 	 (const_int 5)))]
+-  "VECTOR_UNIT_VSX_P (V4SFmode)"
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxmrghw %x0,%x1,%x2"
+   [(set_attr "type" "vecperm")])
+ 
+-(define_insn "vsx_xxmrglw"
+-  [(set (match_operand:V4SF 0 "register_operand" "=wf,?wa")
+-        (vec_merge:V4SF
+-	 (vec_select:V4SF
+-	  (match_operand:V4SF 1 "register_operand" "wf,wa")
++(define_insn "vsx_xxmrglw_<mode>"
++  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
++        (vec_merge:VSX_W
++	 (vec_select:VSX_W
++	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
+ 	  (parallel [(const_int 2)
+ 		     (const_int 0)
+ 		     (const_int 3)
+ 		     (const_int 1)]))
+-	 (vec_select:V4SF
+-	  (match_operand:V4SF 2 "register_operand" "wf,?wa")
++	 (vec_select:VSX_W
++	  (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")
+ 	  (parallel [(const_int 0)
+ 		     (const_int 2)
+ 		     (const_int 1)
+ 		     (const_int 3)]))
+ 	 (const_int 5)))]
+-  "VECTOR_UNIT_VSX_P (V4SFmode)"
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
+   "xxmrglw %x0,%x1,%x2"
+   [(set_attr "type" "vecperm")])
++
++;; Shift left double by word immediate
++(define_insn "vsx_xxsldwi_<mode>"
++  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa")
++	(unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa")
++		       (match_operand:VSX_L 2 "vsx_register_operand" "wa")
++		       (match_operand:QI 3 "u5bit_cint_operand" "i")]
++		      UNSPEC_VSX_SLDWI))]
++  "VECTOR_MEM_VSX_P (<MODE>mode)"
++  "xxsldwi %x0,%x1,%x2,%3"
++  [(set_attr "type" "vecperm")])
+--- gcc/config/rs6000/rs6000.h	(revision 146119)
++++ gcc/config/rs6000/rs6000.h	(revision 146798)
+@@ -1033,14 +1033,6 @@ extern int rs6000_vector_align[];
+ 	 ((MODE) == V4SFmode		\
+ 	  || (MODE) == V2DFmode)	\
+ 
+-#define VSX_VECTOR_MOVE_MODE(MODE)	\
+-	 ((MODE) == V16QImode		\
+-	  || (MODE) == V8HImode		\
+-	  || (MODE) == V4SImode		\
+-	  || (MODE) == V2DImode		\
+-	  || (MODE) == V4SFmode		\
+-	  || (MODE) == V2DFmode)	\
+-
+ #define VSX_SCALAR_MODE(MODE)		\
+ 	((MODE) == DFmode)
+ 
+@@ -1049,12 +1041,9 @@ extern int rs6000_vector_align[];
+ 	 || VSX_SCALAR_MODE (MODE))
+ 
+ #define VSX_MOVE_MODE(MODE)		\
+-	(VSX_VECTOR_MOVE_MODE (MODE)	\
+-	 || VSX_SCALAR_MODE(MODE)	\
+-	 || (MODE) == V16QImode		\
+-	 || (MODE) == V8HImode		\
+-	 || (MODE) == V4SImode		\
+-	 || (MODE) == V2DImode		\
++	(VSX_VECTOR_MODE (MODE)		\
++	 || VSX_SCALAR_MODE (MODE)	\
++	 || ALTIVEC_VECTOR_MODE (MODE)	\
+ 	 || (MODE) == TImode)
+ 
+ #define ALTIVEC_VECTOR_MODE(MODE)	\
+@@ -1304,12 +1293,24 @@ enum reg_class
+    purpose.  Any move between two registers of a cover class should be
+    cheaper than load or store of the registers.  The macro value is
+    array of register classes with LIM_REG_CLASSES used as the end
+-   marker.  */
++   marker.
++
++   We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
++   account for the Altivec and Floating registers being subsets of the VSX
++   register set.  */
++
++#define IRA_COVER_CLASSES_PRE_VSX					     \
++{									     \
++  GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, /* VSX_REGS, */	     \
++  /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS,		     \
++  /* MQ_REGS, LINK_REGS, CTR_REGS, */					     \
++  CR_REGS, XER_REGS, LIM_REG_CLASSES					     \
++}
+ 
+-#define IRA_COVER_CLASSES						     \
++#define IRA_COVER_CLASSES_VSX						     \
+ {									     \
+-  GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS,			     \
+-  /*VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS,		     \
++  GENERAL_REGS, SPECIAL_REGS, /* FLOAT_REGS, ALTIVEC_REGS, */ VSX_REGS,	     \
++  /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS,		     \
+   /* MQ_REGS, LINK_REGS, CTR_REGS, */					     \
+   CR_REGS, XER_REGS, LIM_REG_CLASSES					     \
+ }
+@@ -3371,21 +3372,36 @@ enum rs6000_builtins
+   VSX_BUILTIN_XVTDIVSP,
+   VSX_BUILTIN_XVTSQRTDP,
+   VSX_BUILTIN_XVTSQRTSP,
+-  VSX_BUILTIN_XXLAND,
+-  VSX_BUILTIN_XXLANDC,
+-  VSX_BUILTIN_XXLNOR,
+-  VSX_BUILTIN_XXLOR,
+-  VSX_BUILTIN_XXLXOR,
+-  VSX_BUILTIN_XXMRGHD,
+-  VSX_BUILTIN_XXMRGHW,
+-  VSX_BUILTIN_XXMRGLD,
+-  VSX_BUILTIN_XXMRGLW,
+-  VSX_BUILTIN_XXPERMDI,
+-  VSX_BUILTIN_XXSEL,
+-  VSX_BUILTIN_XXSLDWI,
+-  VSX_BUILTIN_XXSPLTD,
+-  VSX_BUILTIN_XXSPLTW,
+-  VSX_BUILTIN_XXSWAPD,
++  VSX_BUILTIN_XXSEL_2DI,
++  VSX_BUILTIN_XXSEL_2DF,
++  VSX_BUILTIN_XXSEL_4SI,
++  VSX_BUILTIN_XXSEL_4SF,
++  VSX_BUILTIN_XXSEL_8HI,
++  VSX_BUILTIN_XXSEL_16QI,
++  VSX_BUILTIN_VPERM_2DI,
++  VSX_BUILTIN_VPERM_2DF,
++  VSX_BUILTIN_VPERM_4SI,
++  VSX_BUILTIN_VPERM_4SF,
++  VSX_BUILTIN_VPERM_8HI,
++  VSX_BUILTIN_VPERM_16QI,
++  VSX_BUILTIN_XXPERMDI_2DF,
++  VSX_BUILTIN_XXPERMDI_2DI,
++  VSX_BUILTIN_CONCAT_2DF,
++  VSX_BUILTIN_CONCAT_2DI,
++  VSX_BUILTIN_SET_2DF,
++  VSX_BUILTIN_SET_2DI,
++  VSX_BUILTIN_SPLAT_2DF,
++  VSX_BUILTIN_SPLAT_2DI,
++  VSX_BUILTIN_XXMRGHW_4SF,
++  VSX_BUILTIN_XXMRGHW_4SI,
++  VSX_BUILTIN_XXMRGLW_4SF,
++  VSX_BUILTIN_XXMRGLW_4SI,
++  VSX_BUILTIN_XXSLDWI_16QI,
++  VSX_BUILTIN_XXSLDWI_8HI,
++  VSX_BUILTIN_XXSLDWI_4SI,
++  VSX_BUILTIN_XXSLDWI_4SF,
++  VSX_BUILTIN_XXSLDWI_2DI,
++  VSX_BUILTIN_XXSLDWI_2DF,
+ 
+   /* VSX overloaded builtins, add the overloaded functions not present in
+      Altivec.  */
+@@ -3395,7 +3411,13 @@ enum rs6000_builtins
+   VSX_BUILTIN_VEC_NMADD,
+   VSX_BUITLIN_VEC_NMSUB,
+   VSX_BUILTIN_VEC_DIV,
+-  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_DIV,
++  VSX_BUILTIN_VEC_XXMRGHW,
++  VSX_BUILTIN_VEC_XXMRGLW,
++  VSX_BUILTIN_VEC_XXPERMDI,
++  VSX_BUILTIN_VEC_XXSLDWI,
++  VSX_BUILTIN_VEC_XXSPLTD,
++  VSX_BUILTIN_VEC_XXSPLTW,
++  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_XXSPLTW,
+ 
+   /* Combined VSX/Altivec builtins.  */
+   VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
+@@ -3425,13 +3447,16 @@ enum rs6000_builtin_type_index
+   RS6000_BTI_unsigned_V16QI,
+   RS6000_BTI_unsigned_V8HI,
+   RS6000_BTI_unsigned_V4SI,
++  RS6000_BTI_unsigned_V2DI,
+   RS6000_BTI_bool_char,          /* __bool char */
+   RS6000_BTI_bool_short,         /* __bool short */
+   RS6000_BTI_bool_int,           /* __bool int */
++  RS6000_BTI_bool_long,		 /* __bool long */
+   RS6000_BTI_pixel,              /* __pixel */
+   RS6000_BTI_bool_V16QI,         /* __vector __bool char */
+   RS6000_BTI_bool_V8HI,          /* __vector __bool short */
+   RS6000_BTI_bool_V4SI,          /* __vector __bool int */
++  RS6000_BTI_bool_V2DI,          /* __vector __bool long */
+   RS6000_BTI_pixel_V8HI,         /* __vector __pixel */
+   RS6000_BTI_long,	         /* long_integer_type_node */
+   RS6000_BTI_unsigned_long,      /* long_unsigned_type_node */
+@@ -3466,13 +3491,16 @@ enum rs6000_builtin_type_index
+ #define unsigned_V16QI_type_node      (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
+ #define unsigned_V8HI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
+ #define unsigned_V4SI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
++#define unsigned_V2DI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI])
+ #define bool_char_type_node           (rs6000_builtin_types[RS6000_BTI_bool_char])
+ #define bool_short_type_node          (rs6000_builtin_types[RS6000_BTI_bool_short])
+ #define bool_int_type_node            (rs6000_builtin_types[RS6000_BTI_bool_int])
++#define bool_long_type_node           (rs6000_builtin_types[RS6000_BTI_bool_long])
+ #define pixel_type_node               (rs6000_builtin_types[RS6000_BTI_pixel])
+ #define bool_V16QI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
+ #define bool_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
+ #define bool_V4SI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
++#define bool_V2DI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V2DI])
+ #define pixel_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
+ 
+ #define long_integer_type_internal_node  (rs6000_builtin_types[RS6000_BTI_long])
+--- gcc/config/rs6000/altivec.md	(revision 146119)
++++ gcc/config/rs6000/altivec.md	(revision 146798)
+@@ -166,12 +166,15 @@ (define_mode_iterator V [V4SI V8HI V16QI
+ ;; otherwise handled by altivec (v2df, v2di, ti)
+ (define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
+ 
++;; Like VM, except don't do TImode
++(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
++
+ (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
+ 
+ ;; Vector move instructions.
+ (define_insn "*altivec_mov<mode>"
+-  [(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
+-	(match_operand:V 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
++  [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
++	(match_operand:VM2 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
+   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
+    && (register_operand (operands[0], <MODE>mode) 
+        || register_operand (operands[1], <MODE>mode))"
+@@ -191,6 +194,31 @@ (define_insn "*altivec_mov<mode>"
+ }
+   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
+ 
++;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
++;; is for unions.  However for plain data movement, slightly favor the vector
++;; loads
++(define_insn "*altivec_movti"
++  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?o,?r,?r,v,v")
++	(match_operand:TI 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
++  "VECTOR_MEM_ALTIVEC_P (TImode)
++   && (register_operand (operands[0], TImode) 
++       || register_operand (operands[1], TImode))"
++{
++  switch (which_alternative)
++    {
++    case 0: return "stvx %1,%y0";
++    case 1: return "lvx %0,%y1";
++    case 2: return "vor %0,%1,%1";
++    case 3: return "#";
++    case 4: return "#";
++    case 5: return "#";
++    case 6: return "vxor %0,%0,%0";
++    case 7: return output_vec_const_move (operands);
++    default: gcc_unreachable ();
++    }
++}
++  [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
++
+ (define_split
+   [(set (match_operand:VM 0 "altivec_register_operand" "")
+ 	(match_operand:VM 1 "easy_vector_constant_add_self" ""))]
+@@ -434,13 +462,13 @@ (define_insn "*altivec_gev4sf"
+   "vcmpgefp %0,%1,%2"
+   [(set_attr "type" "veccmp")])
+ 
+-(define_insn "altivec_vsel<mode>"
++(define_insn "*altivec_vsel<mode>"
+   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
+ 	(if_then_else:VM (ne (match_operand:VM 1 "altivec_register_operand" "v")
+ 			     (const_int 0))
+ 			 (match_operand:VM 2 "altivec_register_operand" "v")
+ 			 (match_operand:VM 3 "altivec_register_operand" "v")))]
+-  "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
++  "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
+   "vsel %0,%3,%2,%1"
+   [(set_attr "type" "vecperm")])
+ 
+@@ -780,7 +808,7 @@ (define_insn "altivec_vmrghw"
+ 						    (const_int 3)
+ 						    (const_int 1)]))
+ 		      (const_int 5)))]
+-  "TARGET_ALTIVEC"
++  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
+   "vmrghw %0,%1,%2"
+   [(set_attr "type" "vecperm")])
+ 
+@@ -797,7 +825,7 @@ (define_insn "*altivec_vmrghsf"
+                                                     (const_int 3)
+                                                     (const_int 1)]))
+                       (const_int 5)))]
+-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
++  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
+   "vmrghw %0,%1,%2"
+   [(set_attr "type" "vecperm")])
+ 
+@@ -881,7 +909,7 @@ (define_insn "altivec_vmrglw"
+ 				     (const_int 1)
+ 				     (const_int 3)]))
+ 	 (const_int 5)))]
+-  "TARGET_ALTIVEC"
++  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
+   "vmrglw %0,%1,%2"
+   [(set_attr "type" "vecperm")])
+ 
+@@ -899,7 +927,7 @@ (define_insn "*altivec_vmrglsf"
+ 				     (const_int 1)
+ 				     (const_int 3)]))
+ 	 (const_int 5)))]
+-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
++  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
+   "vmrglw %0,%1,%2"
+   [(set_attr "type" "vecperm")])
+ 
+--- gcc/config/rs6000/rs6000.md	(revision 146119)
++++ gcc/config/rs6000/rs6000.md	(revision 146798)
+@@ -14667,7 +14667,11 @@ (define_insn "return"
+   [(set_attr "type" "jmpreg")])
+ 
+ (define_expand "indirect_jump"
+-  [(set (pc) (match_operand 0 "register_operand" ""))])
++  [(set (pc) (match_operand 0 "register_operand" ""))]
++  ""
++{
++  rs6000_set_indirect_jump ();
++})
+ 
+ (define_insn "*indirect_jump<mode>"
+   [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
+@@ -14682,14 +14686,14 @@ (define_expand "tablejump"
+   [(use (match_operand 0 "" ""))
+    (use (label_ref (match_operand 1 "" "")))]
+   ""
+-  "
+ {
++  rs6000_set_indirect_jump ();
+   if (TARGET_32BIT)
+     emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
+   else
+     emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
+   DONE;
+-}")
++})
+ 
+ (define_expand "tablejumpsi"
+   [(set (match_dup 3)
+@@ -14749,6 +14753,11 @@ (define_expand "doloop_end"
+   /* Only use this on innermost loops.  */
+   if (INTVAL (operands[3]) > 1)
+     FAIL;
++  /* Do not try to use decrement and count on code that has an indirect
++     jump or a table jump, because the ctr register is preferred over the
++     lr register.  */
++  if (rs6000_has_indirect_jump_p ())
++    FAIL;
+   if (TARGET_64BIT)
+     {
+       if (GET_MODE (operands[0]) != DImode)

diff --git a/gcc44-pr39543.patch b/gcc44-pr39543.patch
deleted file mode 100644
index e84c6b5..0000000
--- a/gcc44-pr39543.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-2009-04-10  Jakub Jelinek  <jakub@redhat.com>
-
-	PR rtl-optimization/39543
-	* fwprop.c (forward_propagate_asm): New function.
-	(forward_propagate_and_simplify): Propagate also into __asm, if it
-	doesn't increase the number of referenced registers.
-
-	* gcc.target/i386/pr39543-1.c: New test.
-	* gcc.target/i386/pr39543-2.c: New test.
-	* gcc.target/i386/pr39543-3.c: New test.
-
---- gcc/fwprop.c.jj	2009-03-30 12:45:45.000000000 +0200
-+++ gcc/fwprop.c	2009-04-10 16:19:36.000000000 +0200
-@@ -1,5 +1,5 @@
- /* RTL-based forward propagation pass for GNU compiler.
--   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-+   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-    Contributed by Paolo Bonzini and Steven Bosscher.
- 
- This file is part of GCC.
-@@ -852,6 +852,80 @@ forward_propagate_subreg (df_ref use, rt
-     return false;
- }
- 
-+/* Try to replace USE with SRC (defined in DEF_INSN) in __asm.  */
-+
-+static bool
-+forward_propagate_asm (df_ref use, rtx def_insn, rtx def_set, rtx reg)
-+{
-+  rtx use_insn = DF_REF_INSN (use), src, use_pat, asm_operands, new_rtx, *loc;
-+  int speed_p, i;
-+  df_ref *use_vec;
-+
-+  gcc_assert ((DF_REF_FLAGS (use) & DF_REF_IN_NOTE) == 0);
-+
-+  src = SET_SRC (def_set);
-+  use_pat = PATTERN (use_insn);
-+
-+  /* In __asm don't replace if src might need more registers than
-+     reg, as that could increase register pressure on the __asm.  */
-+  use_vec = DF_INSN_USES (def_insn);
-+  if (use_vec[0] && use_vec[1])
-+    return false;
-+
-+  speed_p = optimize_bb_for_speed_p (BLOCK_FOR_INSN (use_insn));
-+  asm_operands = NULL_RTX;
-+  switch (GET_CODE (use_pat))
-+    {
-+    case ASM_OPERANDS:
-+      asm_operands = use_pat;
-+      break;
-+    case SET:
-+      if (MEM_P (SET_DEST (use_pat)))
-+	{
-+	  loc = &SET_DEST (use_pat);
-+	  new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p);
-+	  if (new_rtx)
-+	    validate_unshare_change (use_insn, loc, new_rtx, true);
-+	}
-+      asm_operands = SET_SRC (use_pat);
-+      break;
-+    case PARALLEL:
-+      for (i = 0; i < XVECLEN (use_pat, 0); i++)
-+	if (GET_CODE (XVECEXP (use_pat, 0, i)) == SET)
-+	  {
-+	    if (MEM_P (SET_DEST (XVECEXP (use_pat, 0, i))))
-+	      {
-+		loc = &SET_DEST (XVECEXP (use_pat, 0, i));
-+		new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg,
-+					 src, speed_p);
-+		if (new_rtx)
-+		  validate_unshare_change (use_insn, loc, new_rtx, true);
-+	      }
-+	    asm_operands = SET_SRC (XVECEXP (use_pat, 0, i));
-+	  }
-+	else if (GET_CODE (XVECEXP (use_pat, 0, i)) == ASM_OPERANDS)
-+	  asm_operands = XVECEXP (use_pat, 0, i);
-+      break;
-+    default:
-+      gcc_unreachable ();
-+    }
-+
-+  gcc_assert (asm_operands && GET_CODE (asm_operands) == ASM_OPERANDS);
-+  for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (asm_operands); i++)
-+    {
-+      loc = &ASM_OPERANDS_INPUT (asm_operands, i);
-+      new_rtx = propagate_rtx (*loc, GET_MODE (*loc), reg, src, speed_p);
-+      if (new_rtx)
-+	validate_unshare_change (use_insn, loc, new_rtx, true);
-+    }
-+
-+  if (num_changes_pending () == 0 || !apply_change_group ())
-+    return false;
-+
-+  num_changes++;
-+  return true;
-+}
-+
- /* Try to replace USE with SRC (defined in DEF_INSN) and simplify the
-    result.  */
- 
-@@ -863,12 +937,16 @@ forward_propagate_and_simplify (df_ref u
-   rtx src, reg, new_rtx, *loc;
-   bool set_reg_equal;
-   enum machine_mode mode;
-+  int asm_use = -1;
-+
-+  if (INSN_CODE (use_insn) < 0)
-+    asm_use = asm_noperands (PATTERN (use_insn));
- 
--  if (!use_set)
-+  if (!use_set && asm_use < 0)
-     return false;
- 
-   /* Do not propagate into PC, CC0, etc.  */
--  if (GET_MODE (SET_DEST (use_set)) == VOIDmode)
-+  if (use_set && GET_MODE (SET_DEST (use_set)) == VOIDmode)
-     return false;
- 
-   /* If def and use are subreg, check if they match.  */
-@@ -900,7 +978,7 @@ forward_propagate_and_simplify (df_ref u
-   if (MEM_P (src) && MEM_READONLY_P (src))
-     {
-       rtx x = avoid_constant_pool_reference (src);
--      if (x != src)
-+      if (x != src && use_set)
- 	{
-           rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX);
- 	  rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set);
-@@ -911,6 +989,9 @@ forward_propagate_and_simplify (df_ref u
-       return false;
-     }
- 
-+  if (asm_use >= 0)
-+    return forward_propagate_asm (use, def_insn, def_set, reg);
-+
-   /* Else try simplifying.  */
- 
-   if (DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE)
---- gcc/testsuite/gcc.target/i386/pr39543-1.c.jj	2009-04-09 09:47:16.000000000 +0200
-+++ gcc/testsuite/gcc.target/i386/pr39543-1.c	2009-04-09 09:47:16.000000000 +0200
-@@ -0,0 +1,52 @@
-+/* PR rtl-optimization/39543 */
-+/* { dg-do compile } */
-+/* { dg-options "-O3 -fomit-frame-pointer" } */
-+
-+float __attribute__ ((aligned (16))) s0[128];
-+const float s1 = 0.707;
-+float s2[8] __attribute__ ((aligned (16)));
-+float s3[8] __attribute__ ((aligned (16)));
-+float s4[16] __attribute__ ((aligned (16)));
-+float s5[16] __attribute__ ((aligned (16)));
-+
-+void
-+foo (int k, float *x, float *y, const float *d, const float *z)
-+{
-+  float *a, *b, *c, *e;
-+
-+  a = x + 2 * k;
-+  b = a + 2 * k;
-+  c = b + 2 * k;
-+  e = y + 2 * k;
-+  __asm__ volatile (""
-+		    : "=m" (x[0]), "=m" (b[0]), "=m" (a[0]), "=m" (c[0])
-+		    : "m" (y[0]), "m" (y[k * 2]), "m" (x[0]), "m" (a[0])
-+		    : "memory");
-+  for (;;)
-+    {
-+      __asm__ volatile (""
-+			:
-+			: "m" (y[2]), "m" (d[2]), "m" (e[2]), "m" (z[2])
-+			: "memory");
-+      if (!--k)
-+	break;
-+    }
-+  __asm__ volatile (""
-+		    : "=m" (x[2]), "=m" (x[10]), "=m" (x[6]), "=m" (x[14])
-+		    : "m" (y[2]), "m" (y[6]), "m" (x[2]), "m" (x[6]),
-+		      "m" (y[18]), "m" (s1)
-+		    : "memory");
-+}
-+
-+void
-+bar (float *a)
-+{
-+  foo (4, a, a + 16, s2, s3);
-+  foo (8, a, a + 32, s4, s5);
-+}
-+
-+void
-+baz (void)
-+{
-+  bar (s0);
-+}
---- gcc/testsuite/gcc.target/i386/pr39543-2.c.jj	2009-04-09 09:47:16.000000000 +0200
-+++ gcc/testsuite/gcc.target/i386/pr39543-2.c	2009-04-09 09:47:16.000000000 +0200
-@@ -0,0 +1,51 @@
-+/* PR rtl-optimization/39543 */
-+/* { dg-do compile } */
-+/* { dg-options "-O3" } */
-+
-+float __attribute__ ((aligned (16))) s0[128];
-+const float s1 = 0.707;
-+float s2[8] __attribute__ ((aligned (16)));
-+float s3[8] __attribute__ ((aligned (16)));
-+float s4[16] __attribute__ ((aligned (16)));
-+float s5[16] __attribute__ ((aligned (16)));
-+
-+void
-+foo (int k, float *x, float *y, const float *d, const float *z)
-+{
-+  float *a, *b, *c, *e;
-+
-+  a = x + 2 * k;
-+  b = a + 2 * k;
-+  c = b + 2 * k;
-+  e = y + 2 * k;
-+  __asm__ volatile (""
-+		    : "=m" (x[0]), "=m" (b[0]), "=m" (a[0]), "=m" (c[0])
-+		    : "m" (y[0]), "m" (y[k * 2]), "m" (x[0]), "m" (a[0])
-+		    : "memory");
-+  for (;;)
-+    {
-+      __asm__ volatile (""
-+			:
-+			: "m" (y[2]), "m" (d[2]), "m" (e[2]), "m" (z[2])
-+			: "memory");
-+      if (!--k)
-+	break;
-+    }
-+  __asm__ volatile (""
-+		    : "=m" (x[2]), "=m" (x[10]), "=m" (x[6]), "=m" (x[14])
-+		    : "m" (y[2]), "m" (y[6]), "m" (x[2]), "m" (x[6]), "m" (s1)
-+		    : "memory");
-+}
-+
-+void
-+bar (float *a)
-+{
-+  foo (4, a, a + 16, s2, s3);
-+  foo (8, a, a + 32, s4, s5);
-+}
-+
-+void
-+baz (void)
-+{
-+  bar (s0);
-+}
---- gcc/testsuite/gcc.target/i386/pr39543-3.c.jj	2009-04-09 09:47:16.000000000 +0200
-+++ gcc/testsuite/gcc.target/i386/pr39543-3.c	2009-04-09 09:47:16.000000000 +0200
-@@ -0,0 +1,42 @@
-+/* PR rtl-optimization/39543 */
-+/* { dg-do compile } */
-+/* { dg-options "-O2" } */
-+
-+int s[128];
-+
-+void
-+f1 (void)
-+{
-+  int i;
-+  asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17"
-+		: "=r" (i)
-+		: "m" (s[0]), "m" (s[2]), "m" (s[4]), "m" (s[6]), "m" (s[8]),
-+		  "m" (s[10]), "m" (s[12]), "m" (s[14]), "m" (s[16]), "m" (s[18]),
-+		  "m" (s[20]), "m" (s[22]), "m" (s[24]), "m" (s[26]), "m" (s[28]),
-+		  "m" (s[30]), "m" (s[32]));
-+  asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17"
-+		: "=r" (i)
-+		: "m" (s[0]), "m" (s[2]), "m" (s[4]), "m" (s[6]), "m" (s[8]),
-+		  "m" (s[10]), "m" (s[12]), "m" (s[14]), "m" (s[16]), "m" (s[18]),
-+		  "m" (s[20]), "m" (s[22]), "m" (s[24]), "m" (s[26]), "m" (s[28]),
-+		  "m" (s[30]), "m" (s[32]));
-+}
-+
-+void
-+f2 (int *q)
-+{
-+  int i;
-+  int *p = q + 32;
-+  asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17"
-+		: "=r" (i)
-+		: "m" (p[0]), "m" (p[2]), "m" (p[4]), "m" (p[6]), "m" (p[8]),
-+		  "m" (p[10]), "m" (p[12]), "m" (p[14]), "m" (p[16]), "m" (p[18]),
-+		  "m" (p[20]), "m" (p[22]), "m" (p[24]), "m" (p[26]), "m" (p[28]),
-+		  "m" (p[30]), "m" (p[32]));
-+  asm volatile ("# %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17"
-+		: "=r" (i)
-+		: "m" (p[0]), "m" (p[2]), "m" (p[4]), "m" (p[6]), "m" (p[8]),
-+		  "m" (p[10]), "m" (p[12]), "m" (p[14]), "m" (p[16]), "m" (p[18]),
-+		  "m" (p[20]), "m" (p[22]), "m" (p[24]), "m" (p[26]), "m" (p[28]),
-+		  "m" (p[30]), "m" (p[32]));
-+}

diff --git a/gcc44-pr39763.patch b/gcc44-pr39763.patch
deleted file mode 100644
index 44f3bb4..0000000
--- a/gcc44-pr39763.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-2009-04-14  Jason Merrill  <jason@redhat.com>
-
-	PR c++/39763
-	* name-lookup.c (pushdecl_maybe_friend): Avoid all warnings
-	about shadowing by tentative parms.
-
-	* g++.dg/warn/Wshadow-4.C: Extend.
-
---- gcc/cp/name-lookup.c	(revision 146053)
-+++ gcc/cp/name-lookup.c	(revision 146054)
-@@ -1002,13 +1002,18 @@ pushdecl_maybe_friend (tree x, bool is_f
- 	      && TREE_PUBLIC (x))
- 	    TREE_PUBLIC (name) = 1;
- 
-+	  /* Don't complain about the parms we push and then pop
-+	     while tentatively parsing a function declarator.  */
-+	  if (TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE)
-+	    /* Ignore.  */;
-+
- 	  /* Warn if shadowing an argument at the top level of the body.  */
--	  if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
--	      /* Inline decls shadow nothing.  */
--	      && !DECL_FROM_INLINE (x)
--	      && TREE_CODE (oldlocal) == PARM_DECL
--	      /* Don't check the `this' parameter.  */
--	      && !DECL_ARTIFICIAL (oldlocal))
-+	  else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
-+		   /* Inline decls shadow nothing.  */
-+		   && !DECL_FROM_INLINE (x)
-+		   && TREE_CODE (oldlocal) == PARM_DECL
-+		   /* Don't check the `this' parameter.  */
-+		   && !DECL_ARTIFICIAL (oldlocal))
- 	    {
- 	      bool err = false;
- 
-@@ -1032,10 +1037,7 @@ pushdecl_maybe_friend (tree x, bool is_f
- 		    }
- 		}
- 
--	      if (warn_shadow && !err
--		  /* Don't complain about the parms we push and then pop
--		     while tentatively parsing a function declarator.  */
--		  && !(TREE_CODE (x) == PARM_DECL && DECL_CONTEXT (x) == NULL_TREE))
-+	      if (warn_shadow && !err)
- 		{
- 		  warning (OPT_Wshadow, "declaration of %q#D shadows a parameter", x);
- 		  warning (OPT_Wshadow, "%Jshadowed declaration is here", oldlocal);
---- gcc/testsuite/g++.dg/warn/Wshadow-4.C	(revision 146053)
-+++ gcc/testsuite/g++.dg/warn/Wshadow-4.C	(revision 146054)
-@@ -18,3 +18,15 @@ int foo(int infoo)		// { dg-warning "sha
-   };
-   return outfoo;
- }
-+
-+// PR c++/39763
-+int foo2(void)
-+{
-+    int infoo = 0;		// { dg-warning "shadowed declaration" }
-+    int outfoo( INetURLObject( infoo ).GetMainURL()); // { dg-bogus "shadows" }
-+    struct A
-+    {
-+      void f(int infoo) { }	// { dg-warning "shadows a previous local" }
-+    };
-+    return outfoo;
-+}
- 2009-04-13  Jason Merrill  <jason@redhat.com>
- 
- 	PR c++/39480

diff --git a/gcc44-pr39856.patch b/gcc44-pr39856.patch
new file mode 100644
index 0000000..5bc88fe
--- /dev/null
+++ b/gcc44-pr39856.patch
@@ -0,0 +1,43 @@
+2009-04-24  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR target/39856
+	* reg-stack.c (subst_stack_regs_pat): Remove gcc_assert for note
+	for clobber.
+
+--- gcc/reg-stack.c	(revision 146648)
++++ gcc/reg-stack.c	(working copy)
+@@ -1371,21 +1371,23 @@ subst_stack_regs_pat (rtx insn, stack re
+ 
+ 	    if (pat != PATTERN (insn))
+ 	      {
+-		/* The fix_truncdi_1 pattern wants to be able to allocate
+-		   its own scratch register.  It does this by clobbering
+-		   an fp reg so that it is assured of an empty reg-stack
+-		   register.  If the register is live, kill it now.
+-		   Remove the DEAD/UNUSED note so we don't try to kill it
+-		   later too.  */
++		/* The fix_truncdi_1 pattern wants to be able to
++		   allocate its own scratch register.  It does this by
++		   clobbering an fp reg so that it is assured of an
++		   empty reg-stack register.  If the register is live,
++		   kill it now.  Remove the DEAD/UNUSED note so we
++		   don't try to kill it later too.
++
++		   In reality the UNUSED note can be absent in some
++		   complicated cases when the register is reused for
++		   partially set variable.  */
+ 
+ 		if (note)
+ 		  emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
+ 		else
+-		  {
+-		    note = find_reg_note (insn, REG_UNUSED, *dest);
+-		    gcc_assert (note);
+-		  }
+-		remove_note (insn, note);
++		  note = find_reg_note (insn, REG_UNUSED, *dest);
++		if (note)
++		  remove_note (insn, note);
+ 		replace_reg (dest, FIRST_STACK_REG + 1);
+ 	      }
+ 	    else

diff --git a/gcc44-pr39942.patch b/gcc44-pr39942.patch
new file mode 100644
index 0000000..eb77eb6
--- /dev/null
+++ b/gcc44-pr39942.patch
@@ -0,0 +1,33 @@
+2009-05-05  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/39942
+	* config/i386/x86-64.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Don't emit second
+	.p2align 3 if MAX_SKIP is smaller than 7.
+	* config/i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise.
+
+--- gcc/config/i386/x86-64.h.jj	2009-05-05 08:33:20.000000000 +0200
++++ gcc/config/i386/x86-64.h	2009-05-05 16:37:13.000000000 +0200
+@@ -74,7 +74,9 @@ see the files COPYING3 and COPYING.RUNTI
+ 	fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP));	\
+ 	/* Make sure that we have at least 8 byte alignment if > 8 byte \
+ 	   alignment is preferred.  */					\
+-	if ((LOG) > 3 && (1 << (LOG)) > ((MAX_SKIP) + 1))		\
++	if ((LOG) > 3							\
++	    && (1 << (LOG)) > ((MAX_SKIP) + 1)				\
++	    && (MAX_SKIP) >= 7)						\
+ 	  fprintf ((FILE), "\t.p2align 3\n");				\
+       }									\
+     }									\
+--- gcc/config/i386/linux.h.jj	2009-05-05 08:33:20.000000000 +0200
++++ gcc/config/i386/linux.h	2009-05-05 16:37:13.000000000 +0200
+@@ -153,7 +153,9 @@ along with GCC; see the file COPYING3.  
+ 	fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP));	\
+ 	/* Make sure that we have at least 8 byte alignment if > 8 byte \
+ 	   alignment is preferred.  */					\
+-	if ((LOG) > 3 && (1 << (LOG)) > ((MAX_SKIP) + 1))		\
++	if ((LOG) > 3							\
++	    && (1 << (LOG)) > ((MAX_SKIP) + 1)				\
++	    && (MAX_SKIP) >= 7)						\
+ 	  fprintf ((FILE), "\t.p2align 3\n");				\
+       }									\
+     }									\

diff --git a/gcc44-rh330771.patch b/gcc44-rh330771.patch
index f52b919..f7c365d 100644
--- a/gcc44-rh330771.patch
+++ b/gcc44-rh330771.patch
@@ -3,20 +3,20 @@
 	* Makefile.am (libgcj_tools_la_LIBADD): Add.
 	* Makefile.in: Regenerated.
 
---- libjava/Makefile.am.jj	2007-03-17 09:20:30.000000000 +0100
-+++ libjava/Makefile.am	2007-10-16 15:45:14.000000000 +0200
-@@ -277,6 +277,8 @@ EXTRA_libgcj_la_SOURCES = java/lang/Obje
- 
- libgcj_tools_la_SOURCES = classpath/tools/tools.zip
- libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch -fno-indirect-classes  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+--- libjava/Makefile.am.jj	2009-05-06 08:14:50.000000000 +0200
++++ libjava/Makefile.am	2009-05-06 10:26:43.000000000 +0200
+@@ -314,6 +314,8 @@ libgcj_tools_la_SOURCES = classpath/tool
+ libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch \
+  -fno-bootstrap-classes -fno-indirect-classes \
+  -fsource-filename=$(here)/classpath/tools/all-classes.lst
 +## See jv_convert_LDADD.
 +libgcj_tools_la_LIBADD = -L$(here)/.libs libgcj.la
  libgcj_tools_la_LDFLAGS = -rpath $(toolexeclibdir) \
   -version-info `grep -v '^\#' $(srcdir)/libtool-version` \
   $(LIBGCJ_LD_SYMBOLIC_FUNCTIONS)
---- libjava/Makefile.in.jj	2007-07-04 21:11:11.000000000 +0200
-+++ libjava/Makefile.in	2007-10-16 15:56:07.000000000 +0200
-@@ -153,7 +153,6 @@ am__objects_1 = gnu/gcj/xlib/lib_gnu_awt
+--- libjava/Makefile.in.jj	2009-05-06 08:14:49.000000000 +0200
++++ libjava/Makefile.in	2009-05-06 10:27:18.000000000 +0200
+@@ -160,7 +160,6 @@ am__objects_1 = gnu/gcj/xlib/lib_gnu_awt
  am_lib_gnu_awt_xlib_la_OBJECTS = $(am__objects_1)
  lib_gnu_awt_xlib_la_OBJECTS = $(am_lib_gnu_awt_xlib_la_OBJECTS)
  @XLIB_AWT_TRUE@am_lib_gnu_awt_xlib_la_rpath = -rpath $(toolexeclibdir)
@@ -24,10 +24,10 @@
  am_libgcj_tools_la_OBJECTS = classpath/tools/libgcj_tools_la-tools.lo
  libgcj_tools_la_OBJECTS = $(am_libgcj_tools_la_OBJECTS)
  @INTERPRETER_TRUE@am__DEPENDENCIES_1 = gnu/classpath/jdwp.lo \
-@@ -941,6 +940,7 @@ libgcj_la_LINK = $(LIBLINK)
- EXTRA_libgcj_la_SOURCES = java/lang/Object.java
- libgcj_tools_la_SOURCES = classpath/tools/tools.zip
- libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS) -findirect-dispatch -fno-indirect-classes  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+@@ -1041,6 +1040,7 @@ libgcj_tools_la_GCJFLAGS = $(AM_GCJFLAGS
+  -fno-bootstrap-classes -fno-indirect-classes \
+  -fsource-filename=$(here)/classpath/tools/all-classes.lst
+ 
 +libgcj_tools_la_LIBADD = -L$(here)/.libs libgcj.la
  libgcj_tools_la_LDFLAGS = -rpath $(toolexeclibdir) \
   -version-info `grep -v '^\#' $(srcdir)/libtool-version` \

diff --git a/generate-cacerts.pl b/generate-cacerts.pl
deleted file mode 100644
index fcab0f1..0000000
--- a/generate-cacerts.pl
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/perl
-
-# Copyright (C) 2007 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# generate-cacerts.pl generates a gkeytool keystore named 'cacerts'
-# from OpenSSL's certificate bundle.
-
-# First extract each of OpenSSL's bundled certificates into its own
-# aliased filename.
-$file = "/etc/pki/tls/cert.pem";
-open(CERTS, $file);
-@certs = <CERTS>;
-close(CERTS);
-
-$pem_file_number = 0;
-$writing_cert = 0;
-foreach $cert (@certs)
-{
-	 if ($cert eq "-----BEGIN CERTIFICATE-----\n")
-	 {
-		  if ($writing_cert != 0)
-		  {
-				die "$file is malformed.";
-		  }
-		  $pem_file_number++;
-		  # Numbering each file guarantees that cert aliases will be
-		  # unique.
-		  $pem_file_name = "$pem_file_number$cert_alias.pem";
-		  $writing_cert = 1;
-		  open(PEM, ">$pem_file_name");
-		  print PEM $cert;
-	 }
-	 elsif ($cert eq "-----END CERTIFICATE-----\n")
-	 {
-		  $writing_cert = 0;
-		  print PEM $cert;
-		  close(PEM);
-	 }
-	 elsif ($cert =~ /Issuer: /)
-	 {
-		  # Generate an alias using the OU and CN attributes of the
-		  # Issuer field if both are present, otherwise use only the CN
-		  # attribute.  The Issuer field must have either the OU or the
-		  # CN attribute.
-		  $_ = $cert;
-		  if ($cert =~ /OU=/)
-		  {
-				s/Issuer:.*?OU=//;
-				# Remove other occurrences of OU=.
-				s/OU=.*CN=//;
-				# Remove CN= if there were not other occurrences of OU=.
-				s/CN=//;
-		  }
-		  elsif ($cert =~ /CN=/)
-		  {
-				s/Issuer:.*CN=//;
-		  }
-		  s/\W//g;
-		  tr/A-Z/a-z/;
-		  $cert_alias = $_
-	 }
-	 else
-	 {
-		  if ($writing_cert == 1)
-		  {
-				print PEM $cert;
-		  }
-	 }
-}
-
-# Check that the correct number of .pem files were produced.
-@pem_files = <*.pem>;
-if (@pem_files != $pem_file_number)
-{
-	 die "Number of .pem files produced does not match".
-		  " number of certs read from $file.";
-}
-
-# Now store each cert in the 'cacerts' file using gkeytool.
-$certs_written_count = 0;
-foreach $pem_file (@pem_files)
-{
-	 system "yes | gkeytool -import -alias `basename $pem_file .pem`".
-		  " -keystore cacerts -storepass '' -file $pem_file".
-		  " 2>&1 >/dev/null";
-	 unlink($pem_file);
-	 $certs_written_count++;
-}
-
-# Check that the correct number of certs were added to the keystore.
-if ($certs_written_count != $pem_file_number)
-{
-	 die "Number of certs added to keystore does not match".
-		  " number of certs read from $file.";
-}

diff --git a/import.log b/import.log
index c2040a3..cd3d10d 100644
--- a/import.log
+++ b/import.log
@@ -1 +1,2 @@
 gcc-4_4_0-0_3:HEAD:gcc-4.4.0-0.3.src.rpm:1232130841
+gcc-4_4_0-5:HEAD:gcc-4.4.0-5.src.rpm:1242291126

diff --git a/sources b/sources
index b14756b..5d45dc9 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
 2659f09c2e43ef8b7d4406321753f1b2  fastjar-0.97.tar.gz
-004cfd0a49b225032953517a827da968  gcc-4.4.0-20090414.tar.bz2
+271340a1883a595c5c8b4fe1007389fa  gcc-4.4.0-20090514.tar.bz2

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-29 12:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-29 12:24 [rpms/gcc] rhel-f41-base: 4.4.0-5 Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox