diff --git a/.cvsignore b/.cvsignore index a81b3c0..973d5b9 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,2 @@ fastjar-0.97.tar.gz -gcc-4.4.0-20090409.tar.bz2 +gcc-4.4.0-20090414.tar.bz2 diff --git a/gcc.spec b/gcc.spec index e86a14b..1ba2254 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,9 +1,9 @@ -%define DATE 20090409 -%define SVNREV 145816 +%define DATE 20090414 +%define SVNREV 146037 %define 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.33 +%define gcc_release 0.34 %define _unpackaged_files_terminate_build 0 %define multilib_64_archs sparc64 ppc64 s390x x86_64 %define include_gappletviewer 1 @@ -36,41 +36,13 @@ %ifarch x86_64 %define multilib_32_arch i586 %endif - -# java-1.5.0-gcj-compat related definitions - -# convert an absolute path to a relative path. each symbolic link is -# specified relative to the directory in which it is installed so that -# it will resolve properly within chrooted installations. -%define abs2rel %{__perl} -e 'use File::Spec; print File::Spec->abs2rel($ARGV[0], $ARGV[1])' - -# python install location -%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib().replace('%{_prefix}','',1)")} - -# Java version information and alternatives priority -%define javaver 1.5.0 -%define javabuildver 0 -%define javadirname java-%{javaver}-gcj-%{javaver}.%{javabuildver} -%define origin gcj -%define priority 1500 - -# installation directory names corresponding to JPackage specifications -%define sdklnk java-%{javaver}-%{origin} -%define jrelnk jre-%{javaver}-%{origin} -%define sdkdir java-%{javaver}-gcj-%{javaver}.%{javabuildver} -%define jredir %{sdkdir}/jre -%define sdkbindir %{_jvmdir}/%{sdklnk}/bin -%define jrebindir %{_jvmdir}/%{jrelnk}/bin -%define jvmjardir %{_jvmjardir}/java-%{javaver}-gcj-%{javaver}.%{javabuildver} - Summary: Various compilers (C, C++, Objective-C, Java, ...) Name: gcc Version: %{gcc_version} Release: %{gcc_release} -# libgcc, libgfortran, libmudflap and crtstuff have an exception which allows -# linking it into any kind of programs or shared libraries without -# restrictions. -License: GPLv3+ and GPLv2+ with exceptions +# libgcc, libgfortran, libmudflap, libgomp, libstdc++ and crtstuff have +# GCC Runtime Exception. +License: GPLv3+, GPLv3+ with exceptions and GPLv2+ with exceptions Group: Development/Languages # The source for this package was pulled from upstream's vcs. Use the # following commands to generate the tarball: @@ -82,7 +54,6 @@ Source2: README.libgcjwebplugin.so Source3: protoize.1 %define fastjar_ver 0.97 Source4: http://download.savannah.nongnu.org/releases/fastjar/fastjar-%{fastjar_ver}.tar.gz -Source5: generate-cacerts.pl URL: http://gcc.gnu.org BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) # Need binutils with -pie support >= 2.14.90.0.4-4 @@ -177,10 +148,8 @@ Patch21: gcc44-cloog-dl.patch Patch22: gcc44-raw-string.patch Patch24: gcc44-atom.patch Patch26: gcc44-power7.patch -Patch27: gcc44-power7-2.patch Patch28: gcc44-pr38757.patch Patch30: gcc44-pr39543.patch -Patch31: gcc44-libjava-i386.patch Patch1000: fastjar-0.97-segfault.patch @@ -387,165 +356,6 @@ Autoreq: true %description -n libgcj-src The Java(tm) runtime library sources for use in Eclipse. -%package -n java-%{javaver}-gcj -Summary: JPackage runtime compatibility layer for GCJ -Group: Development/Languages - -BuildRequires: gcc-java >= %{version} -BuildRequires: libgcj-src >= %{version} -# required for cacerts generation -BuildRequires: openssl -BuildRequires: python-devel -%if ! %{bootstrap_java} -# required for javadoc -BuildRequires: java-1.6.0-openjdk-devel -%endif -BuildRequires: unzip - -# required for tools and libgcj.jar -Requires: libgcj = %{version} -# required for directory structures -Requires: jpackage-utils >= 1.7.3 -# required for java.security symlink -Requires: %{_prefix}/%{_lib}/security/classpath.security -%if ! %{bootstrap_java} -# required for javadoc symlink -Requires: sinjdoc -%endif -# post requires alternatives to install tool alternatives -Requires(post): %{_sbindir}/alternatives -# post requires gij to retrieve gcc version -Requires(post): %{_bindir}/gij -# post rebuilds the gcj database -Requires(post): %{_bindir}/rebuild-gcj-db -# rebuild-gcj-db requires gcj-dbtool -Requires(post): %{_bindir}/gcj-dbtool -# rebuild-gcj-db requires findutils -Requires(post): findutils -# postun requires alternatives to uninstall tool alternatives -Requires(postun): %{_sbindir}/alternatives -# postun requires gij to retrieve gcc version -Requires(postun): %{_bindir}/gij -# postun rebuilds the gcj database -Requires(postun): %{_bindir}/rebuild-gcj-db -# rebuild-gcj-db requires gcj-dbtool -Requires(postun): %{_bindir}/gcj-dbtool -# rebuild-gcj-db requires findutils -Requires(postun): findutils - -# standard JPackage base provides -Provides: jre-%{javaver}-%{origin} = %{version}-%{release} -Provides: jre-%{origin} = %{version}-%{release} -Provides: jre-%{javaver} = %{version}-%{release} -Provides: java-%{javaver} = %{version}-%{release} -Provides: jre = %{javaver} -Provides: java-%{origin} = %{version}-%{release} -Provides: java = %{javaver} -# libgcj provides, translated to JPackage provides -Provides: jaas = %{version}-%{release} -Provides: jce = %{version}-%{release} -Provides: jdbc-stdext = %{version}-%{release} -Provides: jdbc-stdext = 3.0 -Provides: jndi = %{version}-%{release} -Provides: jndi-cos = %{version}-%{release} -Provides: jndi-dns = %{version}-%{release} -Provides: jndi-ldap = %{version}-%{release} -Provides: jndi-rmi = %{version}-%{release} -Provides: jsse = %{version}-%{release} -Provides: java-sasl = %{version}-%{release} -Provides: jaxp_parser_impl = %{version}-%{release} -# java-gcj-compat base provides -Provides: java-gcj-compat = 1.0.79 -Provides: java-1.4.2-gcj-compat > 1.4.2.0-40jpp.111 - -Obsoletes: java-1.4.2-gcj-compat <= 1.4.2.0-40jpp.111 -Obsoletes: gnu-crypto <= 2.1.0-2jpp.1 -Obsoletes: gnu-crypto-sasl-jdk1.4 <= 2.1.0-2jpp.1 -Obsoletes: jessie <= 1.0.1-7 - -%description -n java-%{javaver}-gcj -This package installs directory structures, shell scripts and symbolic -links to simulate a JPackage-compatible runtime environment with GCJ. - -%package -n java-%{javaver}-gcj-devel -Summary: JPackage development compatibility layer for GCJ -Group: Development/Tools - -# require libgcj-src for tools.jar symlink -Requires: libgcj-src = %{version} -# require base package -Requires: java-%{javaver}-gcj = %{version}-%{release} -# require ecj for ecj binary -Requires: ecj >= 3.2.1 -# require python for aot-compile -Requires: python -# require gcc-java for gjavah binary -Requires: gcc-java = %{version} -# post requires alternatives to install tool alternatives -Requires(post): %{_sbindir}/alternatives -# post requires gcj to retrieve gcj header file locations -Requires(post): %{_bindir}/gcj -# postun requires alternatives to uninstall tool alternatives -Requires(postun): %{_sbindir}/alternatives - -# standard JPackage devel provides -Provides: java-sdk-%{javaver}-%{origin} = %{version} -Provides: java-sdk-%{javaver} = %{version} -Provides: java-sdk-%{origin} = %{version} -Provides: java-sdk = %{javaver} -Provides: java-%{javaver}-devel = %{version} -Provides: java-devel-%{origin} = %{version} -Provides: java-devel = %{javaver} -# java-gcj-compat devel provides -Provides: java-gcj-compat-devel = 1.0.79 -Provides: java-1.4.2-gcj-compat-devel > 1.4.2.0-40jpp.111 - -Obsoletes: java-1.4.2-gcj-compat-devel <= 1.4.2.0-40jpp.111 - -%description -n java-%{javaver}-gcj-devel -This package installs directory structures, shell scripts and symbolic -links to simulate a JPackage-compatible development environment with -GCJ. - -%package -n java-%{javaver}-gcj-src -Summary: Source files for libgcj -Group: Development/Libraries - -Requires: java-%{javaver}-gcj = %{version}-%{release} -Requires: libgcj-src = %{version} -# post requires gij to retrieve gcc version -Requires(post): %{_bindir}/gij - -# java-gcj-compat src provides -Provides: java-1.4.2-gcj-compat-src > 1.4.2.0-40jpp.111 - -Obsoletes: java-1.4.2-gcj-compat-src <= 1.4.2.0-40jpp.111 - -%description -n java-%{javaver}-gcj-src -This package installs a src.zip symbolic link that points to a -specific version of the libgcj sources. - -%if ! %{bootstrap_java} -%package -n java-%{javaver}-gcj-javadoc -Summary: API documentation for libgcj -Group: Documentation - -# require base package -Requires: java-%{javaver}-gcj = %{version}-%{release} - -# standard JPackage javadoc provides -Provides: java-javadoc = %{version}-%{release} -Provides: java-%{javaver}-javadoc = %{version}-%{release} -# java-gcj-compat javadoc provides -Provides: java-1.4.2-gcj-compat-javadoc > 1.4.2.0-40jpp.111 - -Obsoletes: java-1.4.2-gcj-compat-javadoc <= 1.4.2.0-40jpp.111 -Obsoletes: gnu-crypto-javadoc <= 2.1.0-2jpp.1 - -%description -n java-%{javaver}-gcj-javadoc -This package installs Javadoc API documentation for libgcj. -%endif - %package -n cpp Summary: The C Preprocessor Group: Development/Languages @@ -626,10 +436,8 @@ which are required to compile with the GNAT. %patch22 -p0 -b .raw-string~ %patch24 -p0 -b .atom~ %patch26 -p0 -b .power7~ -%patch27 -p0 -b .power7-2~ %patch28 -p0 -b .pr38757~ #%patch30 -p0 -b .pr39543~ -%patch31 -p0 -b .libjava-i386~ # This testcase doesn't compile. rm libjava/testsuite/libjava.lang/PR35020* @@ -756,7 +564,6 @@ case "$OPT_FLAGS" in ../gcc/Makefile.in ;; esac - CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \ GCJFLAGS="$OPT_FLAGS" \ ../configure --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ @@ -772,11 +579,8 @@ CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="`echo $OPT_FLAGS | sed 's/ -Wall / /g'`" --disable-libgcj \ %else --enable-java-awt=gtk --disable-dssi --enable-plugin \ - --with-java-home=%{_prefix}/lib/jvm/%{javadirname}/jre \ - --enable-libgcj-multifile --enable-java-home --enable-aot-compile-rpm \ - --with-jvm-root-dir=\${prefix}/lib/jvm/%{javadirname} \ - --with-jvm-jar-dir=\${prefix}/lib/jvm-exports/%{javadirname} \ - --with-python-dir=%{python_sitelib} \ + --with-java-home=%{_prefix}/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre \ + --enable-libgcj-multifile \ %if !%{bootstrap_java} --enable-java-maintainer-mode \ %endif @@ -1305,126 +1109,6 @@ 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 - -# versionless symbolic links -pushd $RPM_BUILD_ROOT%{_jvmdir} - ln -s %{jredir} %{jrelnk} - ln -s %{sdkdir} %{sdklnk} -popd -pushd $RPM_BUILD_ROOT%{_jvmjardir} - ln -s %{sdkdir} %{jrelnk} - ln -s %{sdkdir} %{sdklnk} -popd - -# create relevant links in jre lib dir for backwards compatibility -pushd $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib -for jarname in jaas jce jdbc-stdext jndi jndi-cos jndi-dns \ - jndi-ldap jndi-rmi jsse sasl; do - ln -sf rt.jar $jarname.jar; -done -popd - -# security directory and provider list -install -dm 755 $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/security -pushd $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/security - RELATIVE=$(%{abs2rel} %{_prefix}/%{_lib}/security \ - %{_jvmdir}/%{jredir}/lib/security) - ln -sf $RELATIVE/classpath.security java.security -popd -# default security providers, provided by libgcj -install -dm 755 $RPM_BUILD_ROOT%{_sysconfdir}/java/security/security.d -for provider in \ - 1000-gnu.java.security.provider.Gnu \ - 1001-gnu.javax.crypto.jce.GnuCrypto \ - 1002-gnu.javax.crypto.jce.GnuSasl \ - 1003-gnu.javax.net.ssl.provider.Jessie \ - 1004-gnu.javax.security.auth.callback.GnuCallbacks -do - cat > $RPM_BUILD_ROOT%{_sysconfdir}/java/security/security.d/$provider << EOF -# This file's contents are ignored. Its name, of the form -# -, is used by post and postun scripts to -# rebuild the list of security providers in libgcj's -# classpath.security file. -EOF - -done -# cacerts -%{__perl} %{SOURCE5} -install -m 644 cacerts $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/security - -# classmap database directory -install -dm 755 $RPM_BUILD_ROOT%{_prefix}/%{_lib}/gcj - -# set up ecj link -RELATIVE=$(%{abs2rel} %{_prefix}/bin %{_jvmdir}/%{sdkdir}/bin) -ln -sf \ - $RELATIVE/ecj \ - $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir}/bin/javac - -# source zip -RELATIVE=$(%{abs2rel} %{_javadir} %{_jvmdir}/%{sdkdir}) -ln -s \ - $RELATIVE/src-%{version}.zip \ - $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir}/src.zip - -#use fastjar instead of gjar -RELATIVE=$(%{abs2rel} %{_prefix}/bin %{_jvmdir}/%{sdkdir}/bin) -ln -sf \ - $RELATIVE/fastjar \ - $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir}/bin/jar - -# use sinjdoc if not bootstrapping -%if ! %{bootstrap_java} -ln -sf \ - $RELATIVE/sinjdoc \ - $RPM_BUILD_ROOT%{_jvmdir}/%{sdkdir}/bin/javadoc -%endif - -# arch dir for x86_64 should be x86_64, with amd64 being a link (to keep the -# package backwards compatible) -%ifarch x86_64 -if [ -d $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/amd64 ]; then - - mv $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/amd64 \ - $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/x86_64 - - ln -s x86_64 $RPM_BUILD_ROOT%{_jvmdir}/%{jredir}/lib/amd64 -fi -%endif - -%if ! %{bootstrap_java} -# build and install API documentation -install -dm 755 $RPM_BUILD_ROOT%{_javadocdir}/java-%{javaver}-gcj -pushd $RPM_BUILD_ROOT%{_javadocdir} - ln -s java-%{javaver}-gcj java -popd -rm -rf docsbuild -mkdir docsbuild -pushd docsbuild - echo ==== CHECK ZIP ==== - unzip -tq $RPM_BUILD_ROOT/usr/share/java/src-%{version}.zip || : - echo ==== END CHECK ZIP ==== - if unzip -tq /usr/share/java/src-%{version}.zip - then - fastjar xvf /usr/share/java/src-%{version}.zip - rm -rf gnu - find ./ -name \*.java | xargs -n 1 dirname | sort | uniq \ - | sed -e "s/\.\///" | sed -e "s/\//\./" \ - | sed -e "s/\//\./" | sed -e "s/\//\./" \ - | sed -e "s/\//\./" | sed -e "s/\//\./" \ - | xargs %{_jvmdir}/java-openjdk/bin/javadoc -quiet \ - -d $RPM_BUILD_ROOT%{_javadocdir}/%{name} \ - -encoding UTF-8 -breakiterator \ - -linksource -splitindex -doctitle "GNU libgcj %{version}" \ - -windowtitle "GNU libgcj %{version} Documentation" - else - # Work around https://bugzilla.redhat.com/show_bug.cgi?id=404981 - touch $RPM_BUILD_ROOT%{_javadocdir}/%{name}/package-list - fi -popd -%endif - - %endif install -m644 %{SOURCE3} $RPM_BUILD_ROOT%{_mandir}/man1/protoize.1 @@ -1522,128 +1206,6 @@ fi %postun -n libgcj -p /sbin/ldconfig -%post -n java-%{javaver}-gcj -alternatives \ - --install %{_bindir}/java java %{jrebindir}/java %{priority} \ - --slave %{_jvmdir}/jre jre %{_jvmdir}/%{jrelnk} \ - --slave %{_jvmjardir}/jre jre_exports %{_jvmjardir}/%{jrelnk} \ - --slave %{_bindir}/keytool keytool %{jrebindir}/keytool \ - --slave %{_bindir}/rmiregistry rmiregistry %{jrebindir}/rmiregistry - -alternatives \ - --install %{_jvmdir}/jre-%{origin} \ - jre_%{origin} %{_jvmdir}/%{jrelnk} %{priority} \ - --slave %{_jvmjardir}/jre-%{origin} \ - jre_%{origin}_exports %{_jvmjardir}/%{jrelnk} - -alternatives \ - --install %{_jvmdir}/jre-%{javaver} \ - jre_%{javaver} %{_jvmdir}/%{jrelnk} %{priority} \ - --slave %{_jvmjardir}/jre-%{javaver} \ - jre_%{javaver}_exports %{_jvmjardir}/%{jrelnk} - -alternatives --install %{_javadir}/jaxp_parser_impl.jar \ - jaxp_parser_impl %{_javadir}/libgcj-%{version}.jar 20 - -{ - # Rebuild the list of security providers in classpath.security. - # This used to be a standalone script, rebuild-security-providers, - # provided by the Fedora version of jpackage-utils. Now it is - # inlined here and removed from Fedora's jpackage-utils for - # compatibility with jpackage.org's jpackage-utils. See: - # https://bugzilla.redhat.com/show_bug.cgi?id=260161 - suffix=security/classpath.security - secfiles="/usr/lib/$suffix /usr/lib64/$suffix" - - for secfile in $secfiles - do - # check if this classpath.security file exists - [ -f "$secfile" ] || continue - - sed -i '/^security\.provider\./d' "$secfile" - - count=0 - for provider in $(ls /etc/java/security/security.d) - do - count=$((count + 1)) - echo "security.provider.${count}=${provider#*-}" >> "$secfile" - done - done -} || : - -if [ -x %{_bindir}/rebuild-gcj-db ] -then - %{_bindir}/rebuild-gcj-db -fi - -%postun -n java-%{javaver}-gcj -if [ $1 -eq 0 ] -then - alternatives --remove java %{jrebindir}/java - alternatives --remove jre_%{origin} %{_jvmdir}/%{jrelnk} - alternatives --remove jre_%{javaver} %{_jvmdir}/%{jrelnk} - alternatives --remove jaxp_parser_impl \ - %{_javadir}/libgcj-%{version}.jar -fi - -{ - # Rebuild the list of security providers in classpath.security - suffix=security/classpath.security - secfiles="/usr/lib/$suffix /usr/lib64/$suffix" - - for secfile in $secfiles - do - # check if this classpath.security file exists - [ -f "$secfile" ] || continue - - sed -i '/^security\.provider\./d' "$secfile" - - count=0 - for provider in $(ls /etc/java/security/security.d) - do - count=$((count + 1)) - echo "security.provider.${count}=${provider#*-}" >> "$secfile" - done - done -} || : - -if [ -x %{_bindir}/rebuild-gcj-db ] -then - %{_bindir}/rebuild-gcj-db -fi - -%post -n java-%{javaver}-gcj-devel -alternatives \ - --install %{_bindir}/javac javac %{sdkbindir}/javac %{priority} \ - --slave %{_jvmdir}/java java_sdk %{_jvmdir}/%{sdklnk} \ - --slave %{_jvmjardir}/java java_sdk_exports %{_jvmjardir}/%{sdklnk} \ - --slave %{_bindir}/javadoc javadoc %{sdkbindir}/javadoc \ - --slave %{_bindir}/javah javah %{sdkbindir}/javah \ - --slave %{_bindir}/jar jar %{sdkbindir}/jar \ - --slave %{_bindir}/jarsigner jarsigner %{sdkbindir}/jarsigner \ - --slave %{_bindir}/appletviewer appletviewer %{sdkbindir}/appletviewer \ - --slave %{_bindir}/rmic rmic %{sdkbindir}/rmic - -alternatives \ - --install %{_jvmdir}/java-%{origin} \ - java_sdk_%{origin} %{_jvmdir}/%{sdklnk} %{priority} \ - --slave %{_jvmjardir}/java-%{origin} \ - java_sdk_%{origin}_exports %{_jvmjardir}/%{sdklnk} - -alternatives \ - --install %{_jvmdir}/java-%{javaver} \ - java_sdk_%{javaver} %{_jvmdir}/%{sdklnk} %{priority} \ - --slave %{_jvmjardir}/java-%{javaver} \ - java_sdk_%{javaver}_exports %{_jvmjardir}/%{sdklnk} - -%postun -n java-%{javaver}-gcj-devel -if [ $1 -eq 0 ] -then - alternatives --remove javac %{sdkbindir}/javac - alternatives --remove java_sdk_%{origin} %{_jvmdir}/%{sdklnk} - alternatives --remove java_sdk_%{javaver} %{_jvmdir}/%{sdklnk} -fi - %post -n libgfortran -p /sbin/ldconfig %postun -n libgfortran -p /sbin/ldconfig @@ -2093,137 +1655,6 @@ fi %dir %{_prefix}/share/java %{_prefix}/share/java/src*.zip %{_prefix}/share/java/libgcj-tools-%{version}.jar - -%files -n java-%{javaver}-gcj -%defattr(-,root,root,-) -%dir %{_jvmdir}/%{sdkdir} -%dir %{_jvmdir}/%{jredir} -%dir %{_jvmdir}/%{jredir}/bin -%dir %{_jvmdir}/%{jredir}/lib -%dir %{_jvmdir}/%{jredir}/lib/%{_arch} -%dir %{_jvmdir}/%{jredir}/lib/%{_arch}/client -%dir %{_jvmdir}/%{jredir}/lib/%{_arch}/server -%dir %{_jvmdir}/%{jredir}/lib/security -%dir %{jvmjardir} -%dir %{_prefix}/%{_lib}/gcj -%{_bindir}/rebuild-gcj-db -%{_jvmdir}/%{jredir}/bin/java -%{_jvmdir}/%{jredir}/bin/keytool -%{_jvmdir}/%{jredir}/bin/rmiregistry -%{_jvmdir}/%{jredir}/bin/orbd -%{_jvmdir}/%{jredir}/bin/rmid -%{_jvmdir}/%{jredir}/bin/tnameserv -%{_jvmdir}/%{jredir}/lib/security/cacerts -%{_jvmdir}/%{jredir}/lib/security/java.security -%{_jvmdir}/%{jredir}/lib/jaas.jar -%{_jvmdir}/%{jredir}/lib/jce.jar -%{_jvmdir}/%{jredir}/lib/jdbc-stdext.jar -%{_jvmdir}/%{jredir}/lib/jndi-cos.jar -%{_jvmdir}/%{jredir}/lib/jndi-dns.jar -%{_jvmdir}/%{jredir}/lib/jndi-ldap.jar -%{_jvmdir}/%{jredir}/lib/jndi-rmi.jar -%{_jvmdir}/%{jredir}/lib/jndi.jar -%{_jvmdir}/%{jredir}/lib/jsse.jar -%{_jvmdir}/%{jredir}/lib/sasl.jar -%ifarch x86_64 -%{_jvmdir}/%{jredir}/lib/amd64 -%endif -%{_jvmdir}/%{jrelnk} -%{jvmjardir}/jaas.jar -%{jvmjardir}/jaas-%{javaver}.jar -%{jvmjardir}/jaas-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jce.jar -%{jvmjardir}/jce-%{javaver}.jar -%{jvmjardir}/jce-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jdbc-stdext.jar -%{jvmjardir}/jdbc-stdext-%{javaver}.jar -%{jvmjardir}/jdbc-stdext-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jndi.jar -%{jvmjardir}/jndi-%{javaver}.jar -%{jvmjardir}/jndi-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jndi-cos.jar -%{jvmjardir}/jndi-cos-%{javaver}.jar -%{jvmjardir}/jndi-cos-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jndi-dns.jar -%{jvmjardir}/jndi-dns-%{javaver}.jar -%{jvmjardir}/jndi-dns-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jndi-ldap.jar -%{jvmjardir}/jndi-ldap-%{javaver}.jar -%{jvmjardir}/jndi-ldap-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jndi-rmi.jar -%{jvmjardir}/jndi-rmi-%{javaver}.jar -%{jvmjardir}/jndi-rmi-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/jsse.jar -%{jvmjardir}/jsse-%{javaver}.jar -%{jvmjardir}/jsse-%{javaver}.%{javabuildver}.jar -%{jvmjardir}/sasl.jar -%{jvmjardir}/sasl-%{javaver}.jar -%{jvmjardir}/sasl-%{javaver}.%{javabuildver}.jar -%{_jvmjardir}/%{jrelnk} -%{_jvmdir}/%{sdkdir}/jre/lib/rt.jar -%{_jvmdir}/%{jredir}/lib/%{_arch}/libjawt.so -%{_jvmdir}/%{jredir}/lib/%{_arch}/client/libjvm.so -%{_jvmdir}/%{jredir}/lib/%{_arch}/server/libjvm.so -# These must not be marked %config(noreplace). Their file names are -# used in post and postun. Their contents are ignored, so replacing -# them doesn't matter. .rpmnew files are harmful since they're -# interpreted by post and postun as classnames ending in rpmnew. -%{_sysconfdir}/java/security/security.d/1000-gnu.java.security.provider.Gnu -%{_sysconfdir}/java/security/security.d/1001-gnu.javax.crypto.jce.GnuCrypto -%{_sysconfdir}/java/security/security.d/1002-gnu.javax.crypto.jce.GnuSasl -%{_sysconfdir}/java/security/security.d/1003-gnu.javax.net.ssl.provider.Jessie -%{_sysconfdir}/java/security/security.d/1004-gnu.javax.security.auth.callback.GnuCallbacks - -%files -n java-%{javaver}-gcj-devel -%defattr(-,root,root,-) -%dir %{_jvmdir}/%{sdkdir}/bin -%dir %{_jvmdir}/%{sdkdir}/include -%dir %{_jvmdir}/%{sdkdir}/include/linux -%dir %{_jvmdir}/%{sdkdir}/lib -%{_bindir}/aot-compile -%{_bindir}/aot-compile-rpm -%{_prefix}/%{python_sitelib}/aotcompile.py* -%{_prefix}/%{python_sitelib}/classfile.py* -%{_jvmdir}/%{sdkdir}/bin/appletviewer -%{_jvmdir}/%{sdkdir}/bin/jar -%{_jvmdir}/%{sdkdir}/bin/jarsigner -%{_jvmdir}/%{sdkdir}/bin/java -%{_jvmdir}/%{sdkdir}/bin/javac -%{_jvmdir}/%{sdkdir}/bin/javadoc -%{_jvmdir}/%{sdkdir}/bin/javah -%{_jvmdir}/%{sdkdir}/bin/keytool -%{_jvmdir}/%{sdkdir}/bin/native2ascii -%{_jvmdir}/%{sdkdir}/bin/orbd -%{_jvmdir}/%{sdkdir}/bin/rmic -%{_jvmdir}/%{sdkdir}/bin/rmid -%{_jvmdir}/%{sdkdir}/bin/rmiregistry -%{_jvmdir}/%{sdkdir}/bin/serialver -%{_jvmdir}/%{sdkdir}/bin/tnameserv -%{_jvmdir}/%{sdklnk} -%{_jvmjardir}/%{sdklnk} -%{_jvmdir}/%{sdkdir}/include/jawt.h -%{_jvmdir}/%{sdkdir}/include/jni.h -%{_jvmdir}/%{sdkdir}/include/linux/jawt_md.h -%{_jvmdir}/%{sdkdir}/include/linux/jni_md.h -%{_jvmdir}/%{sdkdir}/lib/tools.jar - -%files -n java-%{javaver}-gcj-src -%defattr(-,root,root,-) -%{_jvmdir}/%{sdkdir}/src.zip - -%if ! %{bootstrap_java} -%files -n java-%{javaver}-gcj-javadoc -%defattr(-,root,root,-) -%doc %{_javadocdir}/java-%{javaver}-gcj -# A JPackage that "provides" this directory will, in its %post script, -# remove the existing directory and install a new symbolic link to its -# versioned directory. For Fedora we want clear file ownership so we -# make java-1.5.0-gcj-javadoc own this file. Installing the -# corresponding JPackage over java-1.5.0-gcj-javadoc will work but -# will invalidate this file. -%doc %{_javadocdir}/java -%endif - %endif %if %{build_ada} @@ -2317,8 +1748,13 @@ fi %doc rpm.doc/changelogs/libmudflap/ChangeLog* %changelog -* Fri Apr 10 2009 Deepak Bhole 4.4.0-0.33 -- create new java-1.5.0-gcj* packages to install JPackage compliant links +* Tue Apr 14 2009 Jakub Jelinek 4.4.0-0.34 +- update from gcc-4_4-branch + - GCC 4.4.0-rc1 + - license changes to GPLv3+ with GCC Runtime Exception for most of the + lib* files + - PRs c++/28301, c++/39480, c++/39742, c++/39750, c/39613, c/39614, c/39673, + libobjc/36610, target/39740, testsuite/35621, tree-optimization/39713 * Thu Apr 9 2009 Jakub Jelinek 4.4.0-0.32 - update from gcc-4_4-branch diff --git a/gcc44-power7-2.patch b/gcc44-power7-2.patch deleted file mode 100644 index 519f8b9..0000000 --- a/gcc44-power7-2.patch +++ /dev/null @@ -1,1369 +0,0 @@ -2009-03-13 Michael Meissner - - PR target/39457 - * config/rs6000/rs6000.opt (-mdisallow-float-in-lr-ctr): Add - temporary debug switch. - - * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Revert - behavior of disallowing - -2009-03-13 Michael Meissner - - * config/rs6000/vector.md (vec_extract_evenv2df): Delete, insn - causes problems in building spec 2006. - (vec_extract_oddv2df): Ditto. - (vec_pack_trunc_v2df): New expanders for VSX vectorized - conversions. - (vec_pack_sfix_trunc_v2df): Ditto. - (vec_pack_ufix_trunc_v2df): Ditto. - (vec_unpacks_hi_v4sf): Ditto. - (vec_unpacks_lo_v4sf): Ditto. - (vec_unpacks_float_hi_v4si): Ditto. - (vec_unpacks_float_lo_v4si): Ditto. - (vec_unpacku_float_hi_v4si): Ditto. - (vec_unpacku_float_lo_v4si): Ditto. - - * config/rs6000/rs6000-protos.h (rs6000_vector_secondary_reload): - Declaration for new target hook. - - * config/rs6000/rs6000.c (TARGET_SECONDARY_RELOAD): Add new target - hook for eventually fixing up the memory references for Altivec - and VSX reloads to be reg+reg instead of reg+offset. Right now, - this is a stub function that prints debug information if - -mdebug=addr and then calls default_secondary_reload. - (rs6000_secondary_reload): Ditto. - (rs6000_vector_secondary_reload): Ditto. - (rs6000_builtin_conversion): Add support for V2DI/V2DF - conversions. - (rs6000_legitimate_offset_address_p): Test for the vector unit - doing the memory references. - (rs6000_legimize_reload_address): Ditto. - (rs6000_legitimize_address): Print extra \n if -mdebug=addr. - (rs6000_legitimize_reload_address): Ditto. - (rs6000_legitimate_address): Ditto. - (rs6000_mode_dependent_address): Ditto. - (bdesc_2arg): Add VSX builtins. - (bdesc_abs): Ditto. - (bdesc_1arg): Ditto. - (altivec_init_builtins): Ditto. - (rs6000_secondary_memory_needed_rtx): Add debug support if - -mdebug=addr. - (rs6000_preferred_reload_class): Ditto. - (rs6000_secondary_memory_needed): Ditto. - (rs6000_secondary_reload_class): Ditto. - (rs6000_cannot_change_mode_class): Ditto. - - * config/rs6000/vsx.md (UNSPEC_VSX_*): Add unspecs for VSX - conversions. - (vsx_nabs): Add generator function. - (vsx_float2): Ditto. - (vsx_floatuns2): Ditto. - (vsx_xxmrghw): Ditto. - (vsx_xxmrglw): Ditto. - (vsx_xvcvdpsp): New VSX vector conversion insn. - (vsx_xvcvdpsxws): Ditto. - (vsx_xvcvdpuxws): Ditto. - (vsx_xvcvspdp): Ditto. - (vsx_xvcvsxwdp): Ditto. - (vsx_xvcvuxwdp): Ditto. - (vsx_reload_*): New insns for reload support. - - * config/rs6000/rs6000.h: Fix a comment. - - * config/rs6000/altivec.md (altivec_reload_*): New insns for - reload support. - - * config/rs6000/rs6000.md (ptrsize): New mode attribute for the - pointer size. - -2009-03-10 Michael Meissner - - * config/rs6000/vsx.md (vsx_concat_v2df): Add explicit 'f' - register class for scalar data, correct uses of the xxpermdi - instruction. - (vsx_set_v2df): Ditto. - (vsx_extract_v2df): Ditto. - (vsx_xxpermdi): Ditto. - (vsx_splatv2df): Ditto. - (vsx_xxmrghw): Use wf instead of v constraints. - (vsx_xxmrglw): Ditto. -testsuite/ -2009-03-13 Michael Meissner - - PR target/39457 - * gcc.target/powerpc/pr39457.c: New test for PR39457. - -2009-03-13 Michael Meissner - - * gcc.target/powerpc/vsx-builtin-1.c: New test for builtins. - * gcc.target/powerpc/vsx-builtin-2.c: Ditto. - ---- gcc/config/rs6000/vector.md (revision 144758) -+++ gcc/config/rs6000/vector.md (revision 144843) -@@ -496,23 +496,122 @@ (define_expand "vec_interleave_lowv2df" - "VECTOR_UNIT_VSX_P (V2DFmode)" - "") - --;; For 2 element vectors, even/odd is the same as high/low --(define_expand "vec_extract_evenv2df" -- [(set (match_operand:V2DF 0 "vfloat_operand" "") -- (vec_concat:V2DF -- (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") -- (parallel [(const_int 0)])) -- (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") -- (parallel [(const_int 0)]))))] -- "VECTOR_UNIT_VSX_P (V2DFmode)" -- "") -+ -+;; Convert double word types to single word types -+(define_expand "vec_pack_trunc_v2df" -+ [(match_operand:V4SF 0 "vsx_register_operand" "") -+ (match_operand:V2DF 1 "vsx_register_operand" "") -+ (match_operand:V2DF 2 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -+{ -+ rtx r1 = gen_reg_rtx (V4SFmode); -+ rtx r2 = gen_reg_rtx (V4SFmode); - --(define_expand "vec_extract_oddv2df" -- [(set (match_operand:V2DF 0 "vfloat_operand" "") -- (vec_concat:V2DF -- (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") -- (parallel [(const_int 1)])) -- (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") -- (parallel [(const_int 1)]))))] -- "VECTOR_UNIT_VSX_P (V2DFmode)" -- "") -+ emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); -+ emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); -+ emit_insn (gen_vec_extract_evenv4sf (operands[0], r1, r2)); -+ DONE; -+}) -+ -+(define_expand "vec_pack_sfix_trunc_v2df" -+ [(match_operand:V4SI 0 "vsx_register_operand" "") -+ (match_operand:V2DF 1 "vsx_register_operand" "") -+ (match_operand:V2DF 2 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -+{ -+ rtx r1 = gen_reg_rtx (V4SImode); -+ rtx r2 = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); -+ emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); -+ emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); -+ DONE; -+}) -+ -+(define_expand "vec_pack_ufix_trunc_v2df" -+ [(match_operand:V4SI 0 "vsx_register_operand" "") -+ (match_operand:V2DF 1 "vsx_register_operand" "") -+ (match_operand:V2DF 2 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -+{ -+ rtx r1 = gen_reg_rtx (V4SImode); -+ rtx r2 = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); -+ emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); -+ emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); -+ DONE; -+}) -+ -+;; Convert single word types to double word -+(define_expand "vec_unpacks_hi_v4sf" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SF 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" -+{ -+ rtx reg = gen_reg_rtx (V4SFmode); -+ -+ emit_insn (gen_vec_interleave_highv4sf (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); -+ DONE; -+}) -+ -+(define_expand "vec_unpacks_lo_v4sf" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SF 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" -+{ -+ rtx reg = gen_reg_rtx (V4SFmode); -+ -+ emit_insn (gen_vec_interleave_lowv4sf (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); -+ DONE; -+}) -+ -+(define_expand "vec_unpacks_float_hi_v4si" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SI 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -+{ -+ rtx reg = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); -+ DONE; -+}) -+ -+(define_expand "vec_unpacks_float_lo_v4si" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SI 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -+{ -+ rtx reg = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); -+ DONE; -+}) -+ -+(define_expand "vec_unpacku_float_hi_v4si" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SI 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -+{ -+ rtx reg = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); -+ DONE; -+}) -+ -+(define_expand "vec_unpacku_float_lo_v4si" -+ [(match_operand:V2DF 0 "vsx_register_operand" "") -+ (match_operand:V4SI 1 "vsx_register_operand" "")] -+ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -+{ -+ rtx reg = gen_reg_rtx (V4SImode); -+ -+ emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); -+ emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); -+ DONE; -+}) ---- gcc/config/rs6000/rs6000-protos.h (revision 144758) -+++ gcc/config/rs6000/rs6000-protos.h (revision 144843) -@@ -72,6 +72,7 @@ extern bool rs6000_secondary_memory_need - extern bool rs6000_cannot_change_mode_class (enum machine_mode, - enum machine_mode, - enum reg_class); -+extern void rs6000_vector_secondary_reload (rtx, rtx, rtx, bool); - extern int paired_emit_vector_cond_expr (rtx, rtx, rtx, - rtx, rtx, rtx); - extern void paired_expand_vector_move (rtx operands[]); ---- gcc/config/rs6000/rs6000.opt (revision 144845) -+++ gcc/config/rs6000/rs6000.opt (revision 144857) -@@ -139,6 +139,9 @@ mvsx-scalar-memory - Target Report Var(TARGET_VSX_SCALAR_MEMORY) - If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default) - -+mdisallow-float-in-lr-ctr -+Target Undocumented Var(TARGET_DISALLOW_FLOAT_IN_LR_CTR) Init(-1) -+ - mupdate - Target Report Var(TARGET_UPDATE) Init(1) - Generate load/store with update instructions ---- gcc/config/rs6000/rs6000.c (revision 144758) -+++ gcc/config/rs6000/rs6000.c (revision 144843) -@@ -1004,6 +1004,10 @@ static rtx rs6000_emit_vector_compare (e - enum machine_mode); - static tree rs6000_stack_protect_fail (void); - -+static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class, -+ enum machine_mode, -+ struct secondary_reload_info *); -+ - const int INSN_NOT_AVAILABLE = -1; - static enum machine_mode rs6000_eh_return_filter_mode (void); - -@@ -1333,6 +1337,9 @@ static const char alt_reg_names[][8] = - #undef TARGET_INSTANTIATE_DECLS - #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls - -+#undef TARGET_SECONDARY_RELOAD -+#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload -+ - struct gcc_target targetm = TARGET_INITIALIZER; - - /* Return number of consecutive hard regs needed starting at reg REGNO -@@ -1448,10 +1448,16 @@ rs6000_hard_regno_mode_ok (int regno, en - if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) - return 1; - -- /* Don't allow anything but word sized integers (aka pointers) in CTR/LR. You -- really don't want to spill your floating point values to those -- registers. Also do it for the old MQ register in the power. */ -- if (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO) -+ /* Don't allow anything but word sized integers (aka pointers) in CTR/LR. -+ You really don't want to spill your floating point values to those -+ registers. Also do it for the old MQ register in the power. -+ -+ While this is desirable in theory, disabling float to go in LR/CTR does -+ cause some regressions, so until they are taken care of, revert to the old -+ behavior by default for most power systems, but enable it for power7. */ -+ if ((TARGET_DISALLOW_FLOAT_IN_LR_CTR > 0 -+ || (TARGET_DISALLOW_FLOAT_IN_LR_CTR < 0 && TARGET_VSX)) -+ && (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO)) - return (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_SIZE (mode) <= UNITS_PER_WORD); - -@@ -2447,6 +2454,14 @@ rs6000_builtin_conversion (enum tree_cod - case FIX_TRUNC_EXPR: - switch (TYPE_MODE (type)) - { -+ case V2DImode: -+ if (!VECTOR_UNIT_VSX_P (V2DFmode)) -+ return NULL_TREE; -+ -+ return TYPE_UNSIGNED (type) -+ ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS] -+ : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS]; -+ - case V4SImode: - if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) - return NULL_TREE; -@@ -2462,6 +2477,14 @@ rs6000_builtin_conversion (enum tree_cod - case FLOAT_EXPR: - switch (TYPE_MODE (type)) - { -+ case V2DImode: -+ if (!VECTOR_UNIT_VSX_P (V2DFmode)) -+ return NULL_TREE; -+ -+ return TYPE_UNSIGNED (type) -+ ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDSP] -+ : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDSP]; -+ - case V4SImode: - if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) - return NULL_TREE; -@@ -2469,6 +2492,7 @@ rs6000_builtin_conversion (enum tree_cod - return TYPE_UNSIGNED (type) - ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF] - : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF]; -+ - default: - return NULL_TREE; - } -@@ -4101,7 +4125,7 @@ rs6000_legitimate_offset_address_p (enum - case V2DImode: - /* AltiVec/VSX vector modes. Only reg+reg addressing is valid and - constant offset zero should not occur due to canonicalization. */ -- if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)) -+ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) - return false; - break; - -@@ -4441,6 +4465,7 @@ rs6000_legitimize_address (rtx x, rtx ol - } - else - fprintf (stderr, "NULL returned\n"); -+ fprintf (stderr, "\n"); - } - - return ret; -@@ -4776,8 +4801,7 @@ rs6000_legitimize_reload_address (rtx x, - && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode) - && GET_CODE (XEXP (x, 1)) == CONST_INT - && (INTVAL (XEXP (x, 1)) & 3) != 0 -- && !ALTIVEC_VECTOR_MODE (mode) -- && !VSX_VECTOR_MODE (mode) -+ && VECTOR_MEM_NONE_P (mode) - && GET_MODE_SIZE (mode) >= UNITS_PER_WORD - && TARGET_POWERPC64) - { -@@ -4798,8 +4822,7 @@ rs6000_legitimize_reload_address (rtx x, - && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode - || mode == DImode)) -- && !ALTIVEC_VECTOR_MODE (mode) -- && !VSX_VECTOR_MODE (mode)) -+ && VECTOR_MEM_NONE_P (mode)) - { - HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; -@@ -4843,6 +4866,7 @@ rs6000_legitimize_reload_address (rtx x, - /* Don't do this for TFmode or TDmode, since the result isn't - offsettable. The same goes for DImode without 64-bit gprs and - DFmode and DDmode without fprs. */ -+ && VECTOR_MEM_NONE_P (mode) - && mode != TFmode - && mode != TDmode - && (mode != DImode || TARGET_POWERPC64) -@@ -4918,6 +4942,8 @@ rs6000_legitimize_reload_address (rtx x, - fprintf (stderr, "New address:\n"); - debug_rtx (ret); - } -+ -+ fprintf (stderr, "\n"); - } - - return ret; -@@ -5035,6 +5061,7 @@ rs6000_legitimate_address (enum machine_ - GET_MODE_NAME (mode), - reg_ok_strict); - debug_rtx (orig_x); -+ fprintf (stderr, "\n"); - } - - return ret; -@@ -5082,9 +5109,10 @@ rs6000_mode_dependent_address (rtx addr) - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, -- "\nrs6000_mode_dependent_address: ret = %d\n", -- (int)ret); -+ "\nrs6000_mode_dependent_address: ret = %s\n", -+ ret ? "true" : "false"); - debug_rtx (addr); -+ fprintf (stderr, "\n"); - } - - return ret; -@@ -7917,6 +7945,20 @@ static struct builtin_description bdesc_ - { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS }, - { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR }, - -+ { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP }, -+ { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP }, -+ { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP }, -+ { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP }, -+ { 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_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP }, -+ { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP }, -+ { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP }, -+ { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP }, -+ { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP }, -+ { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP }, -+ - { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, - { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, - { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM }, -@@ -8288,7 +8330,11 @@ static const struct builtin_description - { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI }, - { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI }, - { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI }, -- { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI } -+ { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }, -+ { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP }, -+ { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP }, -+ { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP }, -+ { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP }, - }; - - /* Simple unary operations: VECb = foo (unsigned literal) or VECb = -@@ -8314,6 +8360,11 @@ static struct builtin_description bdesc_ - { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX }, - { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH }, - -+ { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP }, -+ { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP }, -+ { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP }, -+ { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP }, -+ - { 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 }, -@@ -8339,6 +8390,15 @@ 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 }, -@@ -10484,6 +10544,8 @@ altivec_init_builtins (void) - = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); - tree v4sf_ftype_v4sf - = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); -+ tree v2df_ftype_v2df -+ = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE); - tree void_ftype_pcvoid_int_int - = build_function_type_list (void_type_node, - pcvoid_type_node, integer_type_node, -@@ -10641,6 +10703,9 @@ altivec_init_builtins (void) - case V4SFmode: - type = v4sf_ftype_v4sf; - break; -+ case V2DFmode: -+ type = v2df_ftype_v2df; -+ break; - default: - gcc_unreachable (); - } -@@ -10960,6 +11025,18 @@ rs6000_common_init_builtins (void) - 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, -@@ -11136,6 +11213,9 @@ rs6000_common_init_builtins (void) - case VOIDmode: - type = opaque_ftype_opaque_opaque; - break; -+ case V2DFmode: -+ type = v2df_ftype_v2df_v2df; -+ break; - case V4SFmode: - type = v4sf_ftype_v4sf_v4sf; - break; -@@ -11285,6 +11365,8 @@ rs6000_common_init_builtins (void) - 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) -@@ -11310,6 +11392,10 @@ rs6000_common_init_builtins (void) - 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 (); - -@@ -12092,8 +12178,10 @@ rtx - rs6000_secondary_memory_needed_rtx (enum machine_mode mode) - { - static bool eliminated = false; -+ rtx ret; -+ - if (mode != SDmode) -- return assign_stack_local (mode, GET_MODE_SIZE (mode), 0); -+ ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); - else - { - rtx mem = cfun->machine->sdmode_stack_slot; -@@ -12105,8 +12193,21 @@ rs6000_secondary_memory_needed_rtx (enum - cfun->machine->sdmode_stack_slot = mem; - eliminated = true; - } -- return mem; -+ ret = mem; -+ } -+ -+ if (TARGET_DEBUG_ADDR) -+ { -+ fprintf (stderr, "rs6000_secondary_memory_needed_rtx, mode %s, rtx:\n", -+ GET_MODE_NAME (mode)); -+ if (!ret) -+ fprintf (stderr, "\tNULL_RTX\n"); -+ else -+ debug_rtx (ret); -+ fprintf (stderr, "\n"); - } -+ -+ return ret; - } - - static tree -@@ -12140,6 +12241,54 @@ rs6000_check_sdmode (tree *tp, int *walk - return NULL_TREE; - } - -+/* Inform reload about cases where moving X with a mode MODE to a register in -+ RCLASS requires an extra scratch or immediate register. Return the class -+ needed for the immediate register. */ -+ -+static enum reg_class -+rs6000_secondary_reload (bool in_p, -+ rtx x, -+ enum reg_class rclass, -+ enum machine_mode mode, -+ secondary_reload_info *sri) -+{ -+ if (TARGET_DEBUG_ADDR) -+ { -+ fprintf (stderr, -+ "rs6000_secondary_reload, in_p = %s, rclass = %s, mode = %s\n", -+ in_p ? "true" : "false", reg_class_names[rclass], -+ GET_MODE_NAME (mode)); -+ debug_rtx (x); -+ fprintf (stderr, "\n"); -+ } -+ -+ return default_secondary_reload (in_p, x, rclass, mode, sri); -+} -+ -+/* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset -+ to SP+reg addressing. */ -+ -+void -+rs6000_vector_secondary_reload (rtx op0, rtx op1, rtx op2, bool to_mem_p) -+{ -+ rtx memref = to_mem_p ? op0 : op1; -+ gcc_assert (MEM_P (memref)); -+ -+ if (TARGET_DEBUG_ADDR) -+ { -+ fprintf (stderr, "rs6000_vector_secondary_reload, to_mem_p = %s\n", -+ to_mem_p ? "true" : "false"); -+ fprintf (stderr, "op0:\n"); -+ debug_rtx (op0); -+ fprintf (stderr, "op1:\n"); -+ debug_rtx (op1); -+ fprintf (stderr, "op2:\n"); -+ debug_rtx (op2); -+ fprintf (stderr, "\n"); -+ } -+ -+ gcc_unreachable (); -+} - - /* Allocate a 64-bit stack slot to be used for copying SDmode - values through if this function has any SDmode references. */ -@@ -12212,32 +12361,44 @@ enum reg_class - rs6000_preferred_reload_class (rtx x, enum reg_class rclass) - { - 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)) -- return rclass; -+ ret = rclass; - -- if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode) && rclass == ALTIVEC_REGS -- && easy_vector_constant (x, mode)) -- return rclass; -+ else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode) -+ && rclass == ALTIVEC_REGS && easy_vector_constant (x, mode)) -+ ret = rclass; - -- if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) -- return NO_REGS; -+ else if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) -+ ret = NO_REGS; - -- if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) -- return GENERAL_REGS; -+ else if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) -+ ret = GENERAL_REGS; - - /* For VSX, prefer the traditional registers. */ -- if (rclass == VSX_REGS) -+ else if (rclass == VSX_REGS) - { - if (mode == DFmode) -- return FLOAT_REGS; -+ ret = FLOAT_REGS; - - if (ALTIVEC_VECTOR_MODE (mode)) -- return ALTIVEC_REGS; -+ ret = ALTIVEC_REGS; -+ } -+ else -+ ret = rclass; -+ -+ if (TARGET_DEBUG_ADDR) -+ { -+ fprintf (stderr, -+ "rs6000_preferred_reload_class, return %s, rclass = %s, x:\n", -+ reg_class_names[ret], reg_class_names[rclass]); -+ debug_rtx (x); -+ fprintf (stderr, "\n"); - } - -- return rclass; -+ return ret; - } - - /* If we are copying between FP or AltiVec registers and anything else, we need -@@ -12251,31 +12412,46 @@ rs6000_secondary_memory_needed (enum reg - enum reg_class class2, - enum machine_mode mode) - { -+ bool ret; -+ bool vsx1; -+ bool vsx2; -+ - if (class1 == class2) -- return false; -+ ret = false; - -- if (TARGET_VSX && VSX_MOVE_MODE (mode) && VSX_REG_CLASS_P (class1) -- && VSX_REG_CLASS_P (class2)) -- return false; -+ else if (TARGET_VSX && VECTOR_MEM_VSX_P (mode) -+ && ((vsx1 = VSX_REG_CLASS_P (class1)) -+ || (vsx2 = VSX_REG_CLASS_P (class2)))) -+ ret = (vsx1 != vsx2); -+ -+ else if (class1 == FLOAT_REGS -+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 -+ || ((mode != DFmode) -+ && (mode != DDmode) -+ && (mode != DImode)))) -+ ret = true; -+ -+ else if (class2 == FLOAT_REGS -+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 -+ || ((mode != DFmode) -+ && (mode != DDmode) -+ && (mode != DImode)))) -+ ret = true; - -- if (class1 == FLOAT_REGS -- && (!TARGET_MFPGPR || !TARGET_POWERPC64 -- || ((mode != DFmode) -- && (mode != DDmode) -- && (mode != DImode)))) -- return true; -+ else if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) -+ ret = true; - -- if (class2 == FLOAT_REGS -- && (!TARGET_MFPGPR || !TARGET_POWERPC64 -- || ((mode != DFmode) -- && (mode != DDmode) -- && (mode != DImode)))) -- return true; -+ else -+ ret = false; - -- if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) -- return true; -+ if (TARGET_DEBUG_ADDR) -+ fprintf (stderr, -+ "rs6000_secondary_memory_needed, return: %s, class1 = %s, " -+ "class2 = %s, mode = %s\n", -+ ret ? "true" : "false", reg_class_names[class1], -+ reg_class_names[class2], GET_MODE_NAME (mode)); - -- return false; -+ return ret; - } - - /* Return the register class of a scratch register needed to copy IN into -@@ -12287,6 +12463,7 @@ rs6000_secondary_reload_class (enum reg_ - enum machine_mode mode, - rtx in) - { -+ enum reg_class ret = NO_REGS; - int regno; - - if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN -@@ -12307,58 +12484,75 @@ rs6000_secondary_reload_class (enum reg_ - || GET_CODE (in) == HIGH - || GET_CODE (in) == LABEL_REF - || GET_CODE (in) == CONST)) -- return BASE_REGS; -+ ret = BASE_REGS; - } - -- if (GET_CODE (in) == REG) -+ if (ret == NO_REGS) - { -- regno = REGNO (in); -- if (regno >= FIRST_PSEUDO_REGISTER) -+ if (GET_CODE (in) == REG) -+ { -+ regno = REGNO (in); -+ if (regno >= FIRST_PSEUDO_REGISTER) -+ { -+ regno = true_regnum (in); -+ if (regno >= FIRST_PSEUDO_REGISTER) -+ regno = -1; -+ } -+ } -+ else if (GET_CODE (in) == SUBREG) - { - regno = true_regnum (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - } -- } -- else if (GET_CODE (in) == SUBREG) -- { -- regno = true_regnum (in); -- if (regno >= FIRST_PSEUDO_REGISTER) -+ else - regno = -1; -- } -- else -- regno = -1; - -- /* We can place anything into GENERAL_REGS and can put GENERAL_REGS -- into anything. */ -- if (rclass == GENERAL_REGS || rclass == BASE_REGS -- || (regno >= 0 && INT_REGNO_P (regno))) -- return NO_REGS; -- -- /* Constants, memory, and FP registers can go into FP registers. */ -- if ((regno == -1 || FP_REGNO_P (regno)) -- && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) -- return (mode != SDmode) ? NO_REGS : GENERAL_REGS; -- -- /* Memory, and FP/altivec registers can go into fp/altivec registers under -- VSX. */ -- if (TARGET_VSX -- && (regno == -1 || VSX_REGNO_P (regno)) -- && VSX_REG_CLASS_P (rclass)) -- return NO_REGS; -+ /* We can place anything into GENERAL_REGS and can put GENERAL_REGS -+ into anything. */ -+ if (rclass == GENERAL_REGS || rclass == BASE_REGS -+ || (regno >= 0 && INT_REGNO_P (regno))) -+ ret = NO_REGS; -+ -+ /* Constants, memory, and FP registers can go into FP registers. */ -+ else if ((regno == -1 || FP_REGNO_P (regno)) -+ && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) -+ ret = (mode != SDmode) ? NO_REGS : GENERAL_REGS; -+ -+ /* Memory, and FP/altivec registers can go into fp/altivec registers under -+ VSX. */ -+ else if (TARGET_VSX -+ && (regno == -1 || VSX_REGNO_P (regno)) -+ && VSX_REG_CLASS_P (rclass)) -+ ret = NO_REGS; -+ -+ /* Memory, and AltiVec registers can go into AltiVec registers. */ -+ else if ((regno == -1 || ALTIVEC_REGNO_P (regno)) -+ && rclass == ALTIVEC_REGS) -+ ret = NO_REGS; -+ -+ /* We can copy among the CR registers. */ -+ else if ((rclass == CR_REGS || rclass == CR0_REGS) -+ && regno >= 0 && CR_REGNO_P (regno)) -+ ret = NO_REGS; -+ -+ /* Otherwise, we need GENERAL_REGS. */ -+ else -+ ret = GENERAL_REGS; -+ } - -- /* Memory, and AltiVec registers can go into AltiVec registers. */ -- if ((regno == -1 || ALTIVEC_REGNO_P (regno)) -- && rclass == ALTIVEC_REGS) -- return NO_REGS; -- -- /* We can copy among the CR registers. */ -- if ((rclass == CR_REGS || rclass == CR0_REGS) -- && regno >= 0 && CR_REGNO_P (regno)) -- return NO_REGS; -+ if (TARGET_DEBUG_ADDR) -+ { -+ fprintf (stderr, -+ "rs6000_secondary_reload_class, return %s, rclass = %s, " -+ "mode = %s, input rtx:\n", -+ reg_class_names[ret], reg_class_names[rclass], -+ GET_MODE_NAME (mode)); -+ debug_rtx (in); -+ fprintf (stderr, "\n"); -+ } - -- /* Otherwise, we need GENERAL_REGS. */ -- return GENERAL_REGS; -+ return ret; - } - - /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */ -@@ -12368,19 +12562,29 @@ rs6000_cannot_change_mode_class (enum ma - enum machine_mode to, - enum reg_class rclass) - { -- return (GET_MODE_SIZE (from) != GET_MODE_SIZE (to) -- ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8 -- || TARGET_IEEEQUAD) -- && reg_classes_intersect_p (FLOAT_REGS, rclass)) -- : (((TARGET_E500_DOUBLE -- && ((((to) == DFmode) + ((from) == DFmode)) == 1 -- || (((to) == TFmode) + ((from) == TFmode)) == 1 -- || (((to) == DDmode) + ((from) == DDmode)) == 1 -- || (((to) == TDmode) + ((from) == TDmode)) == 1 -- || (((to) == DImode) + ((from) == DImode)) == 1)) -- || (TARGET_SPE -- && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1)) -- && reg_classes_intersect_p (GENERAL_REGS, rclass))); -+ bool ret = (GET_MODE_SIZE (from) != GET_MODE_SIZE (to) -+ ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8 -+ || TARGET_IEEEQUAD) -+ && reg_classes_intersect_p (FLOAT_REGS, rclass)) -+ : (((TARGET_E500_DOUBLE -+ && ((((to) == DFmode) + ((from) == DFmode)) == 1 -+ || (((to) == TFmode) + ((from) == TFmode)) == 1 -+ || (((to) == DDmode) + ((from) == DDmode)) == 1 -+ || (((to) == TDmode) + ((from) == TDmode)) == 1 -+ || (((to) == DImode) + ((from) == DImode)) == 1)) -+ || (TARGET_SPE -+ && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1)) -+ && reg_classes_intersect_p (GENERAL_REGS, rclass))); -+ -+ if (TARGET_DEBUG_ADDR) -+ fprintf (stderr, -+ "rs6000_cannot_change_mode_class, return %s, from = %s, " -+ "to = %s, rclass = %s\n", -+ ret ? "true" : "false", -+ GET_MODE_NAME (from), GET_MODE_NAME (to), -+ reg_class_names[rclass]); -+ -+ return ret; - } - - /* Given a comparison operation, return the bit number in CCR to test. We ---- gcc/config/rs6000/vsx.md (revision 144758) -+++ gcc/config/rs6000/vsx.md (revision 144843) -@@ -68,7 +68,13 @@ (define_mode_attr VSbit [(SI "32") - (DI "64")]) - - (define_constants -- [(UNSPEC_VSX_CONCAT_V2DF 500)]) -+ [(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)]) - - ;; VSX moves - (define_insn "*vsx_mov" -@@ -245,7 +251,7 @@ (define_insn "*vsx_abs2" - "xvabs %x0,%x1" - [(set_attr "type" "vecfloat")]) - --(define_insn "*vsx_nabs2" -+(define_insn "vsx_nabs2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") - (neg:VSX_F - (abs:VSX_F -@@ -417,14 +423,14 @@ (define_insn "*vsx_ftrunc2" - "xvrpiz %x0,%x1" - [(set_attr "type" "vecperm")]) - --(define_insn "*vsx_float2" -+(define_insn "vsx_float2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") - (float:VSX_F (match_operand: 1 "vsx_register_operand" "")))] - "VECTOR_UNIT_VSX_P (mode)" - "xvcvsx %x0,%x1" - [(set_attr "type" "vecfloat")]) - --(define_insn "*vsx_floatuns2" -+(define_insn "vsx_floatuns2" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") - (unsigned_float:VSX_F (match_operand: 1 "vsx_register_operand" "")))] - "VECTOR_UNIT_VSX_P (mode)" -@@ -446,6 +452,62 @@ (define_insn "*vsx_fixuns_trunc3" - (define_insn "vsx_concat_v2df" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") - (unspec:V2DF -- [(match_operand:DF 1 "vsx_register_operand" "f,wa") -- (match_operand:DF 2 "vsx_register_operand" "f,wa")] -+ [(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)" - "xxpermdi %x0,%x1,%x2,0" -@@ -762,32 +824,37 @@ (define_insn "vsx_concat_v2df" - - ;; Set a double into one element - (define_insn "vsx_set_v2df" -- [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd") -+ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") - (vec_merge:V2DF -- (match_operand:V2DF 1 "vsx_register_operand" "wd") -- (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws")) -- (match_operand:QI 3 "u5bit_cint_operand" "i")))] -+ (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)" - { -- operands[3] = GEN_INT (INTVAL (operands[3]) & 1); -- return \"xxpermdi %x0,%x1,%x2,%3\"; -+ if (INTVAL (operands[3]) == 0) -+ return \"xxpermdi %x0,%x1,%x2,1\"; -+ else if (INTVAL (operands[3]) == 1) -+ return \"xxpermdi %x0,%x2,%x1,0\"; -+ else -+ gcc_unreachable (); - } - [(set_attr "type" "vecperm")]) - - ;; Extract a DF element from V2DF - (define_insn "vsx_extract_v2df" -- [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -- (vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd") -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,f,?wa") -+ (vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd,wd,wa") - (parallel -- [(match_operand:QI 2 "u5bit_cint_operand" "i")])))] -+ [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - { -- operands[3] = GEN_INT (INTVAL (operands[2]) & 1); -+ gcc_assert (UINTVAL (operands[2]) <= 1); -+ operands[3] = GEN_INT (INTVAL (operands[2]) << 1); - return \"xxpermdi %x0,%x1,%x1,%3\"; - } - [(set_attr "type" "vecperm")]) - --;; General V2DF permute -+;; General V2DF permute, extract_{high,low,even,odd} - (define_insn "vsx_xxpermdi" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd") - (vec_concat:V2DF -@@ -799,6 +866,7 @@ (define_insn "vsx_xxpermdi" - [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - { -+ gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1)); - operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1) - | (INTVAL (operands[4]) & 1)); - return \"xxpermdi %x0,%x1,%x3,%5\"; -@@ -807,14 +875,15 @@ (define_insn "vsx_xxpermdi" - - ;; V2DF splat - (define_insn "vsx_splatv2df" -- [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd") -+ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,wd") - (vec_duplicate:V2DF -- (match_operand:DF 1 "input_operand" "ws,Z")))] -+ (match_operand:DF 1 "input_operand" "ws,f,Z")))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "@ - xxpermdi %x0,%x1,%x1,0 -+ xxpermdi %x0,%x1,%x1,0 - lxvdsx %x0,%y1" -- [(set_attr "type" "vecperm,vecload")]) -+ [(set_attr "type" "vecperm,vecperm,vecload")]) - - ;; V4SF splat - (define_insn "*vsx_xxspltw" -@@ -828,14 +897,14 @@ (define_insn "*vsx_xxspltw" - [(set_attr "type" "vecperm")]) - - ;; V4SF interleave --(define_insn "*vsx_xxmrghw" -- [(set (match_operand:V4SF 0 "register_operand" "=v") -- (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v") -+(define_insn "vsx_xxmrghw" -+ [(set (match_operand:V4SF 0 "register_operand" "=wf") -+ (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf") - (parallel [(const_int 0) - (const_int 2) - (const_int 1) - (const_int 3)])) -- (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v") -+ (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf") - (parallel [(const_int 2) - (const_int 0) - (const_int 3) -@@ -845,15 +914,15 @@ (define_insn "*vsx_xxmrghw" - "xxmrghw %x0,%x1,%x2" - [(set_attr "type" "vecperm")]) - --(define_insn "*vsx_xxmrglw" -- [(set (match_operand:V4SF 0 "register_operand" "=v") -+(define_insn "vsx_xxmrglw" -+ [(set (match_operand:V4SF 0 "register_operand" "=wf") - (vec_merge:V4SF -- (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v") -+ (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "wf") - (parallel [(const_int 2) - (const_int 0) - (const_int 3) - (const_int 1)])) -- (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v") -+ (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "wf") - (parallel [(const_int 0) - (const_int 2) - (const_int 1) -@@ -862,3 +931,26 @@ (define_insn "*vsx_xxmrglw" - "VECTOR_UNIT_VSX_P (V4SFmode)" - "xxmrglw %x0,%x1,%x2" - [(set_attr "type" "vecperm")]) -+ -+ -+;; Reload patterns for VSX loads/stores. We need a scratch register to convert -+;; the stack temporary address from reg+offset to reg+reg addressing. -+(define_expand "vsx_reload___to_mem" -+ [(parallel [(match_operand:VSX_L 0 "memory_operand" "") -+ (match_operand:VSX_L 1 "register_operand" "=wa") -+ (match_operand:P 2 "register_operand" "=&b")])] -+ "VECTOR_MEM_VSX_P (mode)" -+{ -+ rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], true); -+ DONE; -+}) -+ -+(define_expand "vsx_reload___to_reg" -+ [(parallel [(match_operand:VSX_L 0 "register_operand" "=wa") -+ (match_operand:VSX_L 1 "memory_operand" "") -+ (match_operand:P 2 "register_operand" "=&b")])] -+ "VECTOR_MEM_VSX_P (mode)" -+{ -+ rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], false); -+ DONE; -+}) ---- gcc/config/rs6000/rs6000.h (revision 144758) -+++ gcc/config/rs6000/rs6000.h (revision 144843) -@@ -3388,7 +3388,7 @@ enum rs6000_builtins - VSX_BUILTIN_XXSPLTW, - VSX_BUILTIN_XXSWAPD, - -- /* Combine VSX/Altivec builtins. */ -+ /* Combined VSX/Altivec builtins. */ - VECTOR_BUILTIN_FLOAT_V4SI_V4SF, - VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF, - VECTOR_BUILTIN_FIX_V4SF_V4SI, ---- gcc/config/rs6000/altivec.md (revision 144758) -+++ gcc/config/rs6000/altivec.md (revision 144843) -@@ -2685,3 +2685,27 @@ (define_expand "vec_unpacku_float_lo_v8h - emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); - DONE; - }") -+ -+ -+;; Reload patterns for Altivec loads/stores. We need a scratch register to -+;; convert the stack temporary address from reg+offset to reg+reg addressing. -+ -+(define_expand "altivec_reload___to_mem" -+ [(parallel [(match_operand:V 0 "memory_operand" "") -+ (match_operand:V 1 "register_operand" "=v") -+ (match_operand:P 2 "register_operand" "=&b")])] -+ "VECTOR_MEM_ALTIVEC_P (mode)" -+{ -+ rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], true); -+ DONE; -+}) -+ -+(define_expand "altivec_reload___to_reg" -+ [(parallel [(match_operand:V 0 "register_operand" "=v") -+ (match_operand:V 1 "memory_operand" "") -+ (match_operand:P 2 "register_operand" "=&b")])] -+ "VECTOR_MEM_ALTIVEC_P (mode)" -+{ -+ rs6000_vector_secondary_reload (operands[0], operands[1], operands[2], false); -+ DONE; -+}) ---- gcc/config/rs6000/rs6000.md (revision 144758) -+++ gcc/config/rs6000/rs6000.md (revision 144843) -@@ -222,6 +222,10 @@ (define_mode_attr dbits [(QI "56") (HI " - ;; ISEL/ISEL64 target selection - (define_mode_attr sel [(SI "") (DI "64")]) - -+;; Suffix for reload patterns -+(define_mode_attr ptrsize [(SI "32bit") -+ (DI "64bit")]) -+ - - ;; Start with fixed-point load and store insns. Here we put only the more - ;; complex forms. Basic data transfer is done later. ---- gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c (revision 144843) -@@ -0,0 +1,29 @@ -+/* { dg-do compile { target { powerpc*-*-* } } } */ -+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ -+/* { dg-require-effective-target powerpc_vsx_ok } */ -+/* { dg-options "-O2 -mcpu=power7" } */ -+/* { dg-final { scan-assembler "xvaddsp" } } */ -+/* { dg-final { scan-assembler "xvsubsp" } } */ -+/* { dg-final { scan-assembler "xvmulsp" } } */ -+/* { dg-final { scan-assembler "xvdivsp" } } */ -+/* { dg-final { scan-assembler "xvmaxsp" } } */ -+/* { dg-final { scan-assembler "xvminsp" } } */ -+/* { dg-final { scan-assembler "xvsqrtsp" } } */ -+/* { dg-final { scan-assembler "xvabssp" } } */ -+/* { dg-final { scan-assembler "xvnabssp" } } */ -+ -+void use_builtins (__vector float *p, __vector float *q, __vector float *r) -+{ -+ __vector float tmp1 = *q; -+ __vector float tmp2 = *r; -+ -+ *p++ = __builtin_vsx_xvaddsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvsubsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvmulsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvdivsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvmaxsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvminsp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvabssp (tmp1); -+ *p++ = __builtin_vsx_xvnabssp (tmp1); -+ *p = __builtin_vsx_xvsqrtsp (tmp1); -+} ---- gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c (revision 144843) -@@ -0,0 +1,29 @@ -+/* { dg-do compile { target { powerpc*-*-* } } } */ -+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ -+/* { dg-require-effective-target powerpc_vsx_ok } */ -+/* { dg-options "-O2 -mcpu=power7" } */ -+/* { dg-final { scan-assembler "xvadddp" } } */ -+/* { dg-final { scan-assembler "xvsubdp" } } */ -+/* { dg-final { scan-assembler "xvmuldp" } } */ -+/* { dg-final { scan-assembler "xvdivdp" } } */ -+/* { dg-final { scan-assembler "xvmaxdp" } } */ -+/* { dg-final { scan-assembler "xvmindp" } } */ -+/* { dg-final { scan-assembler "xvsqrtdp" } } */ -+/* { dg-final { scan-assembler "xvabsdp" } } */ -+/* { dg-final { scan-assembler "xvnabsdp" } } */ -+ -+void use_builtins (__vector double *p, __vector double *q, __vector double *r) -+{ -+ __vector double tmp1 = *q; -+ __vector double tmp2 = *r; -+ -+ *p++ = __builtin_vsx_xvadddp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvsubdp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvmuldp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvdivdp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvmaxdp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvmindp (tmp1, tmp2); -+ *p++ = __builtin_vsx_xvabsdp (tmp1); -+ *p++ = __builtin_vsx_xvnabsdp (tmp1); -+ *p = __builtin_vsx_xvsqrtdp (tmp1); -+} ---- gcc/testsuite/gcc.target/powerpc/pr39457.c (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/pr39457.c (revision 144857) -@@ -0,0 +1,56 @@ -+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ -+/* { dg-options "-m64 -O2 -mminimal-toc" } */ -+ -+/* PR 39457 -- fix breakage because the compiler ran out of registers and -+ wanted to stash a floating point value to the LR/CTR register. */ -+ -+/* -O2 -m64 -mminimal-toc */ -+typedef struct { void *s; } S; -+typedef void (*T1) (void); -+typedef void (*T2) (void *, void *, int, void *); -+char *fn1 (const char *, ...); -+void *fn2 (void); -+int fn3 (char *, int); -+int fn4 (const void *); -+int fn5 (const void *); -+long fn6 (void) __attribute__ ((__const__)); -+int fn7 (void *, void *, void *); -+void *fn8 (void *, long); -+void *fn9 (void *, long, const char *, ...); -+void *fn10 (void *); -+long fn11 (void) __attribute__ ((__const__)); -+long fn12 (void *, const char *, T1, T2, void *); -+void *fn13 (void *); -+long fn14 (void) __attribute__ ((__const__)); -+extern void *v1; -+extern char *v2; -+extern int v3; -+ -+void -+foo (void *x, char *z) -+{ -+ void *i1, *i2; -+ int y; -+ if (v1) -+ return; -+ v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0); -+ y = 520 - (520 - fn4 (x)) / 2; -+ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0, -+ "y", 16.0, "wid", 80.0, "hi", 500.0, 0); -+ fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2", -+ 500.0, "f", fn3 ("fff", 0x0D0DFA00), 0); -+ fn13 (((S *) fn8 (v1, fn6 ()))->s); -+ fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ())); -+ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", -+ fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi", -+ 500.0, 0); -+ v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2", -+ 500.0, "f", fn3 ("gc", 0x0D0DFA00), 0); -+ fn1 (z, 0); -+ i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x", -+ 800 - fn5 (x) / 2, "y", y - fn4 (x), 0); -+ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/"); -+ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0); -+ i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x", -+ 800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0); -+} diff --git a/gcc44-power7.patch b/gcc44-power7.patch index 42f8088..3345ed3 100644 --- a/gcc44-power7.patch +++ b/gcc44-power7.patch @@ -1,3 +1,247 @@ +2009-04-08 Michael Meissner + + * doc/invoke.texi (-mvsx-vector-memory): Make debug switches + undoucmented. + (-mvsx-vector-float): Ditto. + (-mvsx-vector-double): Ditto. + (-mvsx-scalar-double): Ditto. + (-mvsx-scalar-memory): Ditto. + + * config/rs6000/vector.md (VEC_R): New iterator for reload + patterns. + (mov): Don't call rs6000_emit_move. + (reload___*): New insns for + secondary_reload support. + (vec_reload_and_plus_): New insns in case reload needs + to move a VSX/Altivec (and (plus reg reg) -16) type address to a + base register. + + * config/rs6000/rs6000-protos.h (rs6000_secondary_reload_inner): + Rename from rs6000_vector_secondary_reload. + + * config/rs6000/rs6000.opt (-mvsx-vector-memory): Make debug + switches undoucmented. + (-mvsx-vector-float): Ditto. + (-mvsx-vector-double): Ditto. + (-mvsx-scalar-double): Ditto. + (-mvsx-scalar-memory): Ditto. + (-mvsx-v4sf-altivec-regs): New undocumented debug switch to + control whether V4SF types prefer the Altivec registers or all of + the VSX registers. + (-mreload-functions): New undocumented debug switch to + enable/disable the secondary reload support. + + * config/rs6000/rs6000.c (rs6000_regno_regclass): New global to + map register number to regclass. + (rs6000_vector_reload): New array to hold the secondary reload + insn codes for the vector types. + (rs6000_init_hard_regno_mode_ok): Fill in rs6000_regno_regclass + and rs6000_vector_reload. + (rs6000_mode_dependent_address): Using AND in addresses is mode + dependent. + (rs6000_emit_move): Add debug information if -mdebug=addr. + (rs6000_reload_register_type): Classify register classes for + secondary reload. + (rs6000_secondary_reload): For the vector types, add reload + support to support reg+reg addressing for gprs, and reg+offset + addressing for vector registers. + (rs6000_secondary_reload_inner): Rename from + rs6000_vector_secondary_reload. Fixup gpr addressing to just reg + or reg+offset, and vector addressing to just reg or reg+reg. + (rs6000_preferred_reload_class): Make sure all cases set the + return value. If VSX/Altivec address with AND -16, prefer using + an Altivec register. + (rs6000_secondary_memory_needed): Handle things like SFmode that + can go in floating registers, but not altivec registers under + -mvsx. + + * config/rs6000/vsx.md (VSX_U): New iterator for load/store with + update. + (VSi, VSI): Reorder fields. + (VSd): Add support for load/store with update rewrite. + (VSv): Ditto. + (VStype_load_update): New mode attribute for load/store with + update. + (VStype_store_update): Ditto. + (vsx_mov): Use * instead of store/load attributes for + multi-instruction gpr loads/stores. + (vsx_reload**): Delete unused reload patterns. + + * config/rs6000/rs6000.h (REGNO_REG_CLASS): Change from a bunch of + if statements to using a lookup table. + (rs6000_regno_regclass): Lookup table for REGNO_REG_CLASS. + + * config/rs6000/altivec.md (altivec_reload*): Delete unused reload + patterns. + + * config/rs6000/rs6000.md (tptrsize, mptrsize): New mode + attributes for -m32/-m64 support. + +2009-03-27 Jakub Jelinek + + PR target/39558 + * macro.c (cpp_get_token): If macro_to_expand returns NULL + and used some tokens, add CPP_PADDING before next token. + + * gcc.target/powerpc/altivec-29.c: New test. + +2009-03-27 Michael Meissner + + * config/rs6000/constraints.md ("wZ" constraint): New constraint + for using Altivec loads/stores under VSX for vector realignment. + + * config/rs6000/predicates.md + (altivec_indexed_or_indirect_operand): New predicate to recognize + Altivec load/stores with an explicit AND -16. + + * config/rs6000/power7.md: Whitespace change. + + * config/rs6000/rs6000.opt (-mpower7-adjust-cost): New debug + switch. + + * config/rs6000/rs6000-c.c (altivec_categorize_keyword): If -mvsx + and -mno-altivec, recognize the 'vector' keyword, but do not + recognize 'bool' or 'pixel'. Recognize vector double under VSX. + (init_vector_keywords): Ditto. + (rs6000_macro_to_expand): Ditto. + (altivec_overloaded_builtins): Add VSX overloaded builtins. + (altivec_resolve_overloaded_builtin): Ditto. + + * config/rs6000/rs6000.c (rs6000_debug_cost): New global for + -mdebug=cost. + (rs6000_debug_address_cost): New function for printing costs if + -mdebug=cost. + (rs6000_debug_rtx_costs): Ditto. + (rs6000_debug_adjust_cost): Ditto. + (rs6000_override_options): Add -mdebug=cost support. + (rs6000_legitimize_reload_address): Allow Altivec loads and stores + with an explicit AND -16, in VSX for vector realignment. + (rs6000_legitimize_reload_address): Ditto. + (rs6000_legitimate_address): Ditto. + (print_operand): Ditto. + (bdesc_3arg): Add VSX builtins. + (bdesc_2arg): Ditto. + (bdesc_1arg): Ditto. + (bdesc_abs): Ditto. + (vsx_expand_builtin): Stub function for expanding VSX builtins. + (rs6000_expand_builtin): Call vsx_expand_builtin. + + * config/rs6000/vsx.md (most DF insns): Merge DF insns in with + V2DF and V4SF insns, rather than duplicating much of the code. + (all insns): Go through all insns, and alternatives to address the + full VSX register set, as a non-preferred option. + (vsx_mod): Add support for using Altivec load/store with + explicit AND -16. Use xxlor to copy registers, not copy sign. + (multiply/add insns): Add an expander and unspec so the insn can + be used directly even if -mno-fused-madd. + (vsx_tdiv3): New insn for use as a builtin function. + (vsx_tsqrt2): Ditto. + (vsx_rsqrte2): Ditto. + + * config/rs6000/rs6000.h (rs6000_debug_cost): New for + -mdebug=cost. + (TARGET_DEBUG_COST): Ditto. + (VSX_BUILTIN_*): Merge the two forms of multiply/add instructions + into a single insn. Start to add overloaded VSX builtins. + + * config/rs6000/altivec.md (build_vector_mask_for_load): Delete + VSX code. + + * config/rs6000/rs6000.md (btruncsf2): Delete extra space. + (movdf_hardfloat32): Use xxlor instead of xscpsgndp to copy data. + (movdf_hardfloat64_mfpgpr): Ditto. + (movdf_hardfloat64): Ditto. + +2009-03-13 Michael Meissner + + PR target/39457 + * config/rs6000/rs6000.opt (-mdisallow-float-in-lr-ctr): Add + temporary debug switch. + + * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Revert + behavior of disallowing + +2009-03-13 Michael Meissner + + * config/rs6000/vector.md (vec_extract_evenv2df): Delete, insn + causes problems in building spec 2006. + (vec_extract_oddv2df): Ditto. + (vec_pack_trunc_v2df): New expanders for VSX vectorized + conversions. + (vec_pack_sfix_trunc_v2df): Ditto. + (vec_pack_ufix_trunc_v2df): Ditto. + (vec_unpacks_hi_v4sf): Ditto. + (vec_unpacks_lo_v4sf): Ditto. + (vec_unpacks_float_hi_v4si): Ditto. + (vec_unpacks_float_lo_v4si): Ditto. + (vec_unpacku_float_hi_v4si): Ditto. + (vec_unpacku_float_lo_v4si): Ditto. + + * config/rs6000/rs6000-protos.h (rs6000_vector_secondary_reload): + Declaration for new target hook. + + * config/rs6000/rs6000.c (TARGET_SECONDARY_RELOAD): Add new target + hook for eventually fixing up the memory references for Altivec + and VSX reloads to be reg+reg instead of reg+offset. Right now, + this is a stub function that prints debug information if + -mdebug=addr and then calls default_secondary_reload. + (rs6000_secondary_reload): Ditto. + (rs6000_vector_secondary_reload): Ditto. + (rs6000_builtin_conversion): Add support for V2DI/V2DF + conversions. + (rs6000_legitimate_offset_address_p): Test for the vector unit + doing the memory references. + (rs6000_legimize_reload_address): Ditto. + (rs6000_legitimize_address): Print extra \n if -mdebug=addr. + (rs6000_legitimize_reload_address): Ditto. + (rs6000_legitimate_address): Ditto. + (rs6000_mode_dependent_address): Ditto. + (bdesc_2arg): Add VSX builtins. + (bdesc_abs): Ditto. + (bdesc_1arg): Ditto. + (altivec_init_builtins): Ditto. + (rs6000_secondary_memory_needed_rtx): Add debug support if + -mdebug=addr. + (rs6000_preferred_reload_class): Ditto. + (rs6000_secondary_memory_needed): Ditto. + (rs6000_secondary_reload_class): Ditto. + (rs6000_cannot_change_mode_class): Ditto. + + * config/rs6000/vsx.md (UNSPEC_VSX_*): Add unspecs for VSX + conversions. + (vsx_nabs): Add generator function. + (vsx_float2): Ditto. + (vsx_floatuns2): Ditto. + (vsx_xxmrghw): Ditto. + (vsx_xxmrglw): Ditto. + (vsx_xvcvdpsp): New VSX vector conversion insn. + (vsx_xvcvdpsxws): Ditto. + (vsx_xvcvdpuxws): Ditto. + (vsx_xvcvspdp): Ditto. + (vsx_xvcvsxwdp): Ditto. + (vsx_xvcvuxwdp): Ditto. + (vsx_reload_*): New insns for reload support. + + * config/rs6000/rs6000.h: Fix a comment. + + * config/rs6000/altivec.md (altivec_reload_*): New insns for + reload support. + + * config/rs6000/rs6000.md (ptrsize): New mode attribute for the + pointer size. + +2009-03-10 Michael Meissner + + * config/rs6000/vsx.md (vsx_concat_v2df): Add explicit 'f' + register class for scalar data, correct uses of the xxpermdi + instruction. + (vsx_set_v2df): Ditto. + (vsx_extract_v2df): Ditto. + (vsx_xxpermdi): Ditto. + (vsx_splatv2df): Ditto. + (vsx_xxmrghw): Use wf instead of v constraints. + (vsx_xxmrglw): Ditto. + 2009-03-09 Michael Meissner * config/rs6000/vsx.md (vsx_store_update64): Use correct @@ -868,7 +1112,27 @@ (popcntwsi2): Add popcntw support. (popcntddi2): Add popcntd support. -testsuite/ +2009-03-27 Jakub Jelinek + + PR target/39558 + * gcc.target/powerpc/altivec-29.c: New test. + +2009-03-27 Michael Meissner + + * gcc.target/powerpc/vsx-builtin-1.c: Add more VSX builtins. + Prevent the optimizer from combining the various multiplies. + * gcc.target/powerpc/vsx-builtin-2.c: Ditto. + +2009-03-13 Michael Meissner + + PR target/39457 + * gcc.target/powerpc/pr39457.c: New test for PR39457. + +2009-03-13 Michael Meissner + + * gcc.target/powerpc/vsx-builtin-1.c: New test for builtins. + * gcc.target/powerpc/vsx-builtin-2.c: Ditto. + 2009-03-01 Michael Meissner * gcc.target/powerpc/vsx-vector-1.c: Fix typos. @@ -899,9 +1163,9 @@ testsuite/ * gcc.target/powerpc/popcount-2.c: New file for power7 support. * gcc.target/powerpc/popcount-3.c: Ditto. ---- gcc/doc/invoke.texi (.../trunk) (revision 144557) -+++ gcc/doc/invoke.texi (.../branches/ibm/power7-meissner) (revision 144730) -@@ -712,7 +712,8 @@ See RS/6000 and PowerPC Options. +--- gcc/doc/invoke.texi (.../trunk) (revision 145777) ++++ gcc/doc/invoke.texi (.../branches/ibm/power7-meissner) (revision 146027) +@@ -715,7 +715,8 @@ See RS/6000 and PowerPC Options. -maltivec -mno-altivec @gol -mpowerpc-gpopt -mno-powerpc-gpopt @gol -mpowerpc-gfxopt -mno-powerpc-gfxopt @gol @@ -911,18 +1175,16 @@ testsuite/ -mcmpb -mno-cmpb -mmfpgpr -mno-mfpgpr -mhard-dfp -mno-hard-dfp @gol -mnew-mnemonics -mold-mnemonics @gol -mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol -@@ -726,7 +727,9 @@ See RS/6000 and PowerPC Options. +@@ -729,7 +730,7 @@ See RS/6000 and PowerPC Options. -mstrict-align -mno-strict-align -mrelocatable @gol -mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol -mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol --mdynamic-no-pic -maltivec -mswdiv @gol -+-mdynamic-no-pic -maltivec -mswdiv -mvsx -mvsx-vector-memory @gol -+-mvsx-vector-float -mvsx-vector-double @gol -+-mvsx-scalar-double -mvsx-scalar-memory @gol ++-mdynamic-no-pic -maltivec -mswdiv @gol -mprioritize-restricted-insns=@var{priority} @gol -msched-costly-dep=@var{dependence_type} @gol -minsert-sched-nops=@var{scheme} @gol -@@ -13512,6 +13515,8 @@ These @samp{-m} options are defined for +@@ -13614,6 +13615,8 @@ These @samp{-m} options are defined for @itemx -mno-mfcrf @itemx -mpopcntb @itemx -mno-popcntb @@ -931,7 +1193,7 @@ testsuite/ @itemx -mfprnd @itemx -mno-fprnd @itemx -mcmpb -@@ -13536,6 +13541,8 @@ These @samp{-m} options are defined for +@@ -13638,6 +13641,8 @@ These @samp{-m} options are defined for @opindex mno-mfcrf @opindex mpopcntb @opindex mno-popcntb @@ -940,7 +1202,7 @@ testsuite/ @opindex mfprnd @opindex mno-fprnd @opindex mcmpb -@@ -13585,6 +13592,9 @@ The @option{-mpopcntb} option allows GCC +@@ -13687,6 +13692,9 @@ The @option{-mpopcntb} option allows GCC double precision FP reciprocal estimate instruction implemented on the POWER5 processor and other processors that support the PowerPC V2.02 architecture. @@ -950,7 +1212,7 @@ testsuite/ The @option{-mfprnd} option allows GCC to generate the FP round to integer instructions implemented on the POWER5+ processor and other processors that support the PowerPC V2.03 architecture. -@@ -13663,9 +13673,9 @@ The @option{-mcpu} options automatically +@@ -13765,9 +13773,9 @@ The @option{-mcpu} options automatically following options: @gccoptlist{-maltivec -mfprnd -mhard-float -mmfcrf -mmultiple @gol @@ -962,7 +1224,7 @@ testsuite/ The particular options set for any particular CPU will vary between compiler versions, depending on what setting seems to produce optimal -@@ -13766,6 +13776,44 @@ instructions. +@@ -13868,6 +13876,14 @@ instructions. This option has been deprecated. Use @option{-mspe} and @option{-mno-spe} instead. @@ -973,43 +1235,13 @@ testsuite/ +Generate code that uses (does not use) vector/scalar (VSX) +instructions, and also enable the use of built-in functions that allow +more direct access to the VSX instruction set. -+ -+@item -mvsx-vector-memory -+@itemx -mno-vsx-vector-memory -+If @option{-mvsx}, use VSX memory reference instructions for vectors -+instead of the Altivec instructions This option is a temporary switch -+to tune the compiler, and may not be supported in future versions. -+ -+@item -mvsx-vector-float -+@itemx -mno-vsx-vector-float -+If @option{-mvsx}, use VSX arithmetic instructions for float vectors. -+This option is a temporary switch to tune the compiler, and may not be -+supported in future versions. -+ -+@item -mvsx-vector-double -+@itemx -mno-vsx-vector-double -+If @option{-mvsx}, use VSX arithmetic instructions for double -+vectors. This option is a temporary switch to tune the -+compiler, and may not be supported in future versions. -+ -+@item -mvsx-scalar-double -+@itemx -mno-vsx-scalar-double -+If @option{-mvsx}, use VSX arithmetic instructions for scalar double. -+This option is a temporary switch to tune the compiler, and may not be -+supported in future versions. -+ -+@item -mvsx-scalar-memory -+@itemx -mno-vsx-scalar-memory -+If @option{-mvsx}, use VSX memory reference instructions for scalar -+double. This option is a temporary switch to tune the compiler, and -+may not be supported in future versions. + @item -mfloat-gprs=@var{yes/single/double/no} @itemx -mfloat-gprs @opindex mfloat-gprs ---- gcc/doc/md.texi (.../trunk) (revision 144557) -+++ gcc/doc/md.texi (.../branches/ibm/power7-meissner) (revision 144730) -@@ -1905,7 +1905,19 @@ Address base register +--- gcc/doc/md.texi (.../trunk) (revision 145777) ++++ gcc/doc/md.texi (.../branches/ibm/power7-meissner) (revision 146027) +@@ -1913,7 +1913,19 @@ Address base register Floating point register @item v @@ -1030,7 +1262,7 @@ testsuite/ @item h @samp{MQ}, @samp{CTR}, or @samp{LINK} register -@@ -1991,6 +2003,9 @@ AND masks that can be performed by two r +@@ -1999,6 +2011,9 @@ AND masks that can be performed by two r @item W Vector constant that does not require memory @@ -1040,8 +1272,8 @@ testsuite/ @end table @item Intel 386---@file{config/i386/constraints.md} ---- gcc/reload.c (.../trunk) (revision 144557) -+++ gcc/reload.c (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/reload.c (.../trunk) (revision 145777) ++++ gcc/reload.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -6255,8 +6255,14 @@ subst_reloads (rtx insn) *r->where = reloadreg; } @@ -1059,8 +1291,144 @@ testsuite/ } } +--- gcc/configure (.../trunk) (revision 145777) ++++ gcc/configure (.../branches/ibm/power7-meissner) (revision 146027) +@@ -23075,7 +23075,7 @@ if test "${gcc_cv_as_powerpc_mfpgpr+set} + else + gcc_cv_as_powerpc_mfpgpr=no + if test $in_tree_gas = yes; then +- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` + then gcc_cv_as_powerpc_mfpgpr=yes + fi + elif test x$gcc_cv_as != x; then +@@ -23171,7 +23171,7 @@ if test "${gcc_cv_as_powerpc_cmpb+set}" + else + gcc_cv_as_powerpc_cmpb=no + if test $in_tree_gas = yes; then +- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` + then gcc_cv_as_powerpc_cmpb=yes + fi + elif test x$gcc_cv_as != x; then +@@ -23217,7 +23217,7 @@ if test "${gcc_cv_as_powerpc_dfp+set}" = + else + gcc_cv_as_powerpc_dfp=no + if test $in_tree_gas = yes; then +- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` + then gcc_cv_as_powerpc_dfp=yes + fi + elif test x$gcc_cv_as != x; then +@@ -23263,7 +23263,7 @@ if test "${gcc_cv_as_powerpc_vsx+set}" = + else + gcc_cv_as_powerpc_vsx=no + if test $in_tree_gas = yes; then +- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` + then gcc_cv_as_powerpc_vsx=yes + fi + elif test x$gcc_cv_as != x; then +@@ -23293,6 +23293,52 @@ _ACEOF + + fi + ++ case $target in ++ *-*-aix*) conftest_s=' .machine "pwr7" ++ .csect .text[PR] ++ popcntd 3,3';; ++ *) conftest_s=' .machine power7 ++ .text ++ popcntd 3,3';; ++ esac ++ ++ echo "$as_me:$LINENO: checking assembler for popcntd support" >&5 ++echo $ECHO_N "checking assembler for popcntd support... $ECHO_C" >&6 ++if test "${gcc_cv_as_powerpc_popcntd+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ gcc_cv_as_powerpc_popcntd=no ++ if test $in_tree_gas = yes; then ++ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` ++ then gcc_cv_as_powerpc_popcntd=yes ++fi ++ elif test x$gcc_cv_as != x; then ++ echo "$conftest_s" > conftest.s ++ if { ac_try='$gcc_cv_as -a32 -o conftest.o conftest.s >&5' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } ++ then ++ gcc_cv_as_powerpc_popcntd=yes ++ else ++ echo "configure: failed program was" >&5 ++ cat conftest.s >&5 ++ fi ++ rm -f conftest.o conftest.s ++ fi ++fi ++echo "$as_me:$LINENO: result: $gcc_cv_as_powerpc_popcntd" >&5 ++echo "${ECHO_T}$gcc_cv_as_powerpc_popcntd" >&6 ++if test $gcc_cv_as_powerpc_popcntd = yes; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define HAVE_AS_POPCNTD 1 ++_ACEOF ++ ++fi ++ + echo "$as_me:$LINENO: checking assembler for .gnu_attribute support" >&5 + echo $ECHO_N "checking assembler for .gnu_attribute support... $ECHO_C" >&6 + if test "${gcc_cv_as_powerpc_gnu_attribute+set}" = set; then +--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c (.../trunk) (revision 0) ++++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-2.c (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,42 @@ ++/* { dg-do compile { target { powerpc*-*-* } } } */ ++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ ++/* { dg-require-effective-target powerpc_vsx_ok } */ ++/* { dg-options "-O2 -mcpu=power7" } */ ++/* { dg-final { scan-assembler "xvaddsp" } } */ ++/* { dg-final { scan-assembler "xvsubsp" } } */ ++/* { dg-final { scan-assembler "xvmulsp" } } */ ++/* { dg-final { scan-assembler "xvmadd" } } */ ++/* { dg-final { scan-assembler "xvmsub" } } */ ++/* { dg-final { scan-assembler "xvnmadd" } } */ ++/* { dg-final { scan-assembler "xvnmsub" } } */ ++/* { dg-final { scan-assembler "xvdivsp" } } */ ++/* { dg-final { scan-assembler "xvmaxsp" } } */ ++/* { dg-final { scan-assembler "xvminsp" } } */ ++/* { dg-final { scan-assembler "xvsqrtsp" } } */ ++/* { dg-final { scan-assembler "xvabssp" } } */ ++/* { dg-final { scan-assembler "xvnabssp" } } */ ++/* { dg-final { scan-assembler "xvresp" } } */ ++/* { dg-final { scan-assembler "xvrsqrtesp" } } */ ++/* { dg-final { scan-assembler "xvtsqrtsp" } } */ ++/* { dg-final { scan-assembler "xvtdivsp" } } */ ++ ++void use_builtins (__vector float *p, __vector float *q, __vector float *r, __vector float *s) ++{ ++ p[0] = __builtin_vsx_xvaddsp (q[0], r[0]); ++ p[1] = __builtin_vsx_xvsubsp (q[1], r[1]); ++ p[2] = __builtin_vsx_xvmulsp (q[2], r[2]); ++ p[3] = __builtin_vsx_xvdivsp (q[3], r[3]); ++ p[4] = __builtin_vsx_xvmaxsp (q[4], r[4]); ++ p[5] = __builtin_vsx_xvminsp (q[5], r[5]); ++ p[6] = __builtin_vsx_xvabssp (q[6]); ++ p[7] = __builtin_vsx_xvnabssp (q[7]); ++ p[8] = __builtin_vsx_xvsqrtsp (q[8]); ++ p[9] = __builtin_vsx_xvmaddsp (q[9], r[9], s[9]); ++ p[10] = __builtin_vsx_xvmsubsp (q[10], r[10], s[10]); ++ p[11] = __builtin_vsx_xvnmaddsp (q[11], r[11], s[11]); ++ p[12] = __builtin_vsx_xvnmsubsp (q[12], r[12], s[12]); ++ p[13] = __builtin_vsx_xvresp (q[13]); ++ p[14] = __builtin_vsx_xvrsqrtesp (q[14]); ++ p[15] = __builtin_vsx_xvtsqrtsp (q[15]); ++ p[16] = __builtin_vsx_xvtdivsp (q[16], r[16]); ++} --- gcc/testsuite/gcc.target/powerpc/popcount-3.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/popcount-3.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/popcount-3.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,9 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1072,7 +1440,7 @@ testsuite/ + return __builtin_popcountl(x); +} --- gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-1.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,74 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1149,7 +1517,7 @@ testsuite/ + a[i] = b[i] / c[i]; +} --- gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-2.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,74 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1225,8 +1593,67 @@ testsuite/ + for (i = 0; i < SIZE; i++) + a[i] = b[i] / c[i]; +} +--- gcc/testsuite/gcc.target/powerpc/pr39457.c (.../trunk) (revision 0) ++++ gcc/testsuite/gcc.target/powerpc/pr39457.c (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,56 @@ ++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ ++/* { dg-options "-m64 -O2 -mminimal-toc" } */ ++ ++/* PR 39457 -- fix breakage because the compiler ran out of registers and ++ wanted to stash a floating point value to the LR/CTR register. */ ++ ++/* -O2 -m64 -mminimal-toc */ ++typedef struct { void *s; } S; ++typedef void (*T1) (void); ++typedef void (*T2) (void *, void *, int, void *); ++char *fn1 (const char *, ...); ++void *fn2 (void); ++int fn3 (char *, int); ++int fn4 (const void *); ++int fn5 (const void *); ++long fn6 (void) __attribute__ ((__const__)); ++int fn7 (void *, void *, void *); ++void *fn8 (void *, long); ++void *fn9 (void *, long, const char *, ...); ++void *fn10 (void *); ++long fn11 (void) __attribute__ ((__const__)); ++long fn12 (void *, const char *, T1, T2, void *); ++void *fn13 (void *); ++long fn14 (void) __attribute__ ((__const__)); ++extern void *v1; ++extern char *v2; ++extern int v3; ++ ++void ++foo (void *x, char *z) ++{ ++ void *i1, *i2; ++ int y; ++ if (v1) ++ return; ++ v1 = fn9 (fn10 (fn2 ()), fn6 (), "x", 0., "y", 0., 0); ++ y = 520 - (520 - fn4 (x)) / 2; ++ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", fn8 (v1, fn14 ()), "x", 18.0, ++ "y", 16.0, "wid", 80.0, "hi", 500.0, 0); ++ fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 80.0, "y2", ++ 500.0, "f", fn3 ("fff", 0x0D0DFA00), 0); ++ fn13 (((S *) fn8 (v1, fn6 ()))->s); ++ fn12 (fn8 (v1, fn11 ()), "ev", (T1) fn7, 0, fn8 (v1, fn6 ())); ++ fn9 (fn8 (v1, fn6 ()), fn6 (), "wig", ++ fn8 (v1, fn14 ()), "x", 111.0, "y", 14.0, "wid", 774.0, "hi", ++ 500.0, 0); ++ v1 = fn9 (fn10 (v1), fn6 (), "x1", 0., "y1", 0., "x2", 774.0, "y2", ++ 500.0, "f", fn3 ("gc", 0x0D0DFA00), 0); ++ fn1 (z, 0); ++ i1 = fn9 (fn8 (v1, fn6 ()), fn6 (), "pixbuf", x, "x", ++ 800 - fn5 (x) / 2, "y", y - fn4 (x), 0); ++ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, "/ok/"); ++ fn12 (fn8 (i1, fn11 ()), "ev", (T1) fn7, 0, 0); ++ i2 = fn9 (fn8 (v1, fn6 ()), fn6 (), "txt", "OK", "fnt", v2, "x", ++ 800, "y", y - fn4 (x) + 15, "ar", 0, "f", v3, 0); ++} --- gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-3.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,48 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1276,8 +1703,53 @@ testsuite/ +{ + a = b / c; +} +--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c (.../trunk) (revision 0) ++++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-1.c (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,42 @@ ++/* { dg-do compile { target { powerpc*-*-* } } } */ ++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ ++/* { dg-require-effective-target powerpc_vsx_ok } */ ++/* { dg-options "-O2 -mcpu=power7" } */ ++/* { dg-final { scan-assembler "xvadddp" } } */ ++/* { dg-final { scan-assembler "xvsubdp" } } */ ++/* { dg-final { scan-assembler "xvmuldp" } } */ ++/* { dg-final { scan-assembler "xvmadd" } } */ ++/* { dg-final { scan-assembler "xvmsub" } } */ ++/* { dg-final { scan-assembler "xvnmadd" } } */ ++/* { dg-final { scan-assembler "xvnmsub" } } */ ++/* { dg-final { scan-assembler "xvdivdp" } } */ ++/* { dg-final { scan-assembler "xvmaxdp" } } */ ++/* { dg-final { scan-assembler "xvmindp" } } */ ++/* { dg-final { scan-assembler "xvsqrtdp" } } */ ++/* { dg-final { scan-assembler "xvrsqrtedp" } } */ ++/* { dg-final { scan-assembler "xvtsqrtdp" } } */ ++/* { dg-final { scan-assembler "xvabsdp" } } */ ++/* { dg-final { scan-assembler "xvnabsdp" } } */ ++/* { dg-final { scan-assembler "xvredp" } } */ ++/* { dg-final { scan-assembler "xvtdivdp" } } */ ++ ++void use_builtins (__vector double *p, __vector double *q, __vector double *r, __vector double *s) ++{ ++ p[0] = __builtin_vsx_xvadddp (q[0], r[0]); ++ p[1] = __builtin_vsx_xvsubdp (q[1], r[1]); ++ p[2] = __builtin_vsx_xvmuldp (q[2], r[2]); ++ p[3] = __builtin_vsx_xvdivdp (q[3], r[3]); ++ p[4] = __builtin_vsx_xvmaxdp (q[4], r[4]); ++ p[5] = __builtin_vsx_xvmindp (q[5], r[5]); ++ p[6] = __builtin_vsx_xvabsdp (q[6]); ++ p[7] = __builtin_vsx_xvnabsdp (q[7]); ++ p[8] = __builtin_vsx_xvsqrtdp (q[8]); ++ p[9] = __builtin_vsx_xvmadddp (q[9], r[9], s[9]); ++ p[10] = __builtin_vsx_xvmsubdp (q[10], r[10], s[10]); ++ p[11] = __builtin_vsx_xvnmadddp (q[11], r[11], s[11]); ++ p[12] = __builtin_vsx_xvnmsubdp (q[12], r[12], s[12]); ++ p[13] = __builtin_vsx_xvredp (q[13]); ++ p[14] = __builtin_vsx_xvrsqrtedp (q[14]); ++ p[15] = __builtin_vsx_xvtsqrtdp (q[15]); ++ p[16] = __builtin_vsx_xvtdivdp (q[16], r[16]); ++} --- gcc/testsuite/gcc.target/powerpc/popcount-2.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/popcount-2.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/popcount-2.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,9 @@ +/* { dg-do compile { target { ilp32 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1289,7 +1761,7 @@ testsuite/ + return __builtin_popcount(x); +} --- gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c (.../trunk) (revision 0) -+++ gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c (.../branches/ibm/power7-meissner) (revision 144730) ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-4.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -0,0 +1,48 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ @@ -1339,8 +1811,8 @@ testsuite/ +{ + a = b / c; +} ---- gcc/testsuite/gcc.dg/vmx/vmx.exp (.../trunk) (revision 144557) -+++ gcc/testsuite/gcc.dg/vmx/vmx.exp (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/testsuite/gcc.dg/vmx/vmx.exp (.../trunk) (revision 145777) ++++ gcc/testsuite/gcc.dg/vmx/vmx.exp (.../branches/ibm/power7-meissner) (revision 146027) @@ -31,7 +31,7 @@ if {![istarget powerpc*-*-*] # nothing but extensions. global DEFAULT_VMXCFLAGS @@ -1350,8 +1822,8 @@ testsuite/ } # If the target system supports AltiVec instructions, the default action ---- gcc/testsuite/lib/target-supports.exp (.../trunk) (revision 144557) -+++ gcc/testsuite/lib/target-supports.exp (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/testsuite/lib/target-supports.exp (.../trunk) (revision 145777) ++++ gcc/testsuite/lib/target-supports.exp (.../branches/ibm/power7-meissner) (revision 146027) @@ -873,6 +873,32 @@ proc check_sse2_hw_available { } { }] } @@ -1436,9 +1908,9 @@ testsuite/ # Return 1 if this is a PowerPC target supporting -mcpu=cell. proc check_effective_target_powerpc_ppu_ok { } { ---- gcc/config.in (.../trunk) (revision 144557) -+++ gcc/config.in (.../branches/ibm/power7-meissner) (revision 144730) -@@ -334,12 +334,18 @@ +--- gcc/config.in (.../trunk) (revision 145777) ++++ gcc/config.in (.../branches/ibm/power7-meissner) (revision 146027) +@@ -327,12 +327,18 @@ #endif @@ -1458,18 +1930,9 @@ testsuite/ /* Define if your assembler supports .register. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_REGISTER_PSEUDO_OP ---- gcc/configure.ac (.../trunk) (revision 144557) -+++ gcc/configure.ac (.../branches/ibm/power7-meissner) (revision 144730) -@@ -2,7 +2,7 @@ - # Process this file with autoconf to generate a configuration script. - - # Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, --# 2007, 2008 Free Software Foundation, Inc. -+# 2007, 2008, 2009 Free Software Foundation, Inc. - - #This file is part of GCC. - -@@ -3080,7 +3080,7 @@ foo: nop +--- gcc/configure.ac (.../trunk) (revision 145777) ++++ gcc/configure.ac (.../branches/ibm/power7-meissner) (revision 146027) +@@ -3054,7 +3054,7 @@ foo: nop esac gcc_GAS_CHECK_FEATURE([move fp gpr support], @@ -1478,7 +1941,7 @@ testsuite/ [$conftest_s],, [AC_DEFINE(HAVE_AS_MFPGPR, 1, [Define if your assembler supports mffgpr and mftgpr.])]) -@@ -3114,7 +3114,7 @@ LCF0: +@@ -3088,7 +3088,7 @@ LCF0: esac gcc_GAS_CHECK_FEATURE([compare bytes support], @@ -1487,7 +1950,7 @@ testsuite/ [$conftest_s],, [AC_DEFINE(HAVE_AS_CMPB, 1, [Define if your assembler supports cmpb.])]) -@@ -3129,7 +3129,7 @@ LCF0: +@@ -3103,7 +3103,7 @@ LCF0: esac gcc_GAS_CHECK_FEATURE([decimal float support], @@ -1496,7 +1959,7 @@ testsuite/ [$conftest_s],, [AC_DEFINE(HAVE_AS_DFP, 1, [Define if your assembler supports DFP instructions.])]) -@@ -3144,11 +3144,26 @@ LCF0: +@@ -3118,11 +3118,26 @@ LCF0: esac gcc_GAS_CHECK_FEATURE([vector-scalar support], @@ -1524,99 +1987,8 @@ testsuite/ gcc_GAS_CHECK_FEATURE([.gnu_attribute support], gcc_cv_as_powerpc_gnu_attribute, [2,18,0],, [.gnu_attribute 4,1],, ---- gcc/configure (.../trunk) (revision 144557) -+++ gcc/configure (.../branches/ibm/power7-meissner) (revision 144730) -@@ -23225,7 +23225,7 @@ if test "${gcc_cv_as_powerpc_mfpgpr+set} - else - gcc_cv_as_powerpc_mfpgpr=no - if test $in_tree_gas = yes; then -- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` -+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` - then gcc_cv_as_powerpc_mfpgpr=yes - fi - elif test x$gcc_cv_as != x; then -@@ -23321,7 +23321,7 @@ if test "${gcc_cv_as_powerpc_cmpb+set}" - else - gcc_cv_as_powerpc_cmpb=no - if test $in_tree_gas = yes; then -- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` -+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` - then gcc_cv_as_powerpc_cmpb=yes - fi - elif test x$gcc_cv_as != x; then -@@ -23367,7 +23367,7 @@ if test "${gcc_cv_as_powerpc_dfp+set}" = - else - gcc_cv_as_powerpc_dfp=no - if test $in_tree_gas = yes; then -- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` -+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` - then gcc_cv_as_powerpc_dfp=yes - fi - elif test x$gcc_cv_as != x; then -@@ -23413,7 +23413,7 @@ if test "${gcc_cv_as_powerpc_vsx+set}" = - else - gcc_cv_as_powerpc_vsx=no - if test $in_tree_gas = yes; then -- if test $gcc_cv_gas_vers -ge `expr \( \( 9 \* 1000 \) + 99 \) \* 1000 + 0` -+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` - then gcc_cv_as_powerpc_vsx=yes - fi - elif test x$gcc_cv_as != x; then -@@ -23443,6 +23443,52 @@ _ACEOF - - fi - -+ case $target in -+ *-*-aix*) conftest_s=' .machine "pwr7" -+ .csect .text[PR] -+ popcntd 3,3';; -+ *) conftest_s=' .machine power7 -+ .text -+ popcntd 3,3';; -+ esac -+ -+ echo "$as_me:$LINENO: checking assembler for popcntd support" >&5 -+echo $ECHO_N "checking assembler for popcntd support... $ECHO_C" >&6 -+if test "${gcc_cv_as_powerpc_popcntd+set}" = set; then -+ echo $ECHO_N "(cached) $ECHO_C" >&6 -+else -+ gcc_cv_as_powerpc_popcntd=no -+ if test $in_tree_gas = yes; then -+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 2` -+ then gcc_cv_as_powerpc_popcntd=yes -+fi -+ elif test x$gcc_cv_as != x; then -+ echo "$conftest_s" > conftest.s -+ if { ac_try='$gcc_cv_as -a32 -o conftest.o conftest.s >&5' -+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 -+ (eval $ac_try) 2>&5 -+ ac_status=$? -+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 -+ (exit $ac_status); }; } -+ then -+ gcc_cv_as_powerpc_popcntd=yes -+ else -+ echo "configure: failed program was" >&5 -+ cat conftest.s >&5 -+ fi -+ rm -f conftest.o conftest.s -+ fi -+fi -+echo "$as_me:$LINENO: result: $gcc_cv_as_powerpc_popcntd" >&5 -+echo "${ECHO_T}$gcc_cv_as_powerpc_popcntd" >&6 -+if test $gcc_cv_as_powerpc_popcntd = yes; then -+ -+cat >>confdefs.h <<\_ACEOF -+#define HAVE_AS_POPCNTD 1 -+_ACEOF -+ -+fi -+ - echo "$as_me:$LINENO: checking assembler for .gnu_attribute support" >&5 - echo $ECHO_N "checking assembler for .gnu_attribute support... $ECHO_C" >&6 - if test "${gcc_cv_as_powerpc_gnu_attribute+set}" = set; then ---- gcc/config/rs6000/aix53.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/aix53.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/aix53.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/aix53.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -57,20 +57,24 @@ do { \ #undef ASM_SPEC #define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" @@ -1645,8 +2017,8 @@ testsuite/ %{mcpu=rs64a: -mppc} \ %{mcpu=603: -m603} \ --- gcc/config/rs6000/vector.md (.../trunk) (revision 0) -+++ gcc/config/rs6000/vector.md (.../branches/ibm/power7-meissner) (revision 144730) -@@ -0,0 +1,518 @@ ++++ gcc/config/rs6000/vector.md (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,664 @@ +;; Expander definitions for vector support between altivec & vsx. No +;; instructions are in this file, this file provides the generic vector +;; expander, and the actual vector instructions will be in altivec.md and @@ -1688,6 +2060,9 @@ testsuite/ +;; Vector comparison modes +(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF]) + ++;; Vector reload iterator ++(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI]) ++ +;; Base type from vector mode +(define_mode_attr VEC_base [(V16QI "QI") + (V8HI "HI") @@ -1710,15 +2085,16 @@ testsuite/ + (match_operand:VEC_M 1 "any_operand" ""))] + "VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)" +{ -+ /* modes without special handling just generate the normal SET operation. */ -+ if (mode != TImode && mode != V2DImode && mode != V2DFmode) ++ if (can_create_pseudo_p ()) + { -+ rs6000_emit_move (operands[0], operands[1], mode); -+ DONE; ++ if (CONSTANT_P (operands[1]) ++ && !easy_vector_constant (operands[1], mode)) ++ operands[1] = force_const_mem (mode, operands[1]); ++ ++ else if (!vlogical_operand (operands[0], mode) ++ && !vlogical_operand (operands[1], mode)) ++ operands[1] = force_reg (mode, operands[1]); + } -+ else if (!vlogical_operand (operands[0], mode) -+ && !vlogical_operand (operands[1], mode)) -+ operands[1] = force_reg (mode, operands[1]); +}) + +;; Generic vector floating point load/store instructions. These will match @@ -1749,6 +2125,49 @@ testsuite/ +}) + + ++;; Reload patterns for vector operations. We may need an addtional base ++;; register to convert the reg+offset addressing to reg+reg for vector ++;; registers and reg+reg or (reg+reg)&(-16) addressing to just an index ++;; register for gpr registers. ++(define_expand "reload___store" ++ [(parallel [(match_operand:VEC_R 0 "memory_operand" "m") ++ (match_operand:VEC_R 1 "gpc_reg_operand" "r") ++ (match_operand:P 2 "register_operand" "=&b")])] ++ "" ++{ ++ rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); ++ DONE; ++}) ++ ++(define_expand "reload___load" ++ [(parallel [(match_operand:VEC_R 0 "gpc_reg_operand" "=&r") ++ (match_operand:VEC_R 1 "memory_operand" "m") ++ (match_operand:P 2 "register_operand" "=&b")])] ++ "" ++{ ++ rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); ++ DONE; ++}) ++ ++;; Reload sometimes tries to move the address to a GPR, and can generate ++;; invalid RTL for addresses involving AND -16. ++ ++(define_insn_and_split "*vec_reload_and_plus_" ++ [(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")) ++ (const_int -16)))] ++ "TARGET_ALTIVEC || TARGET_VSX" ++ "#" ++ "&& reload_completed" ++ [(set (match_dup 0) ++ (plus:P (match_dup 1) ++ (match_dup 2))) ++ (parallel [(set (match_dup 0) ++ (and:P (match_dup 0) ++ (const_int -16))) ++ (clobber:CC (scratch:CC))])]) ++ +;; Generic floating point vector arithmetic support +(define_expand "add3" + [(set (match_operand:VEC_F 0 "vfloat_operand" "") @@ -2145,28 +2564,127 @@ testsuite/ + "VECTOR_UNIT_VSX_P (V2DFmode)" + "") + -+;; For 2 element vectors, even/odd is the same as high/low -+(define_expand "vec_extract_evenv2df" -+ [(set (match_operand:V2DF 0 "vfloat_operand" "") -+ (vec_concat:V2DF -+ (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") -+ (parallel [(const_int 0)])) -+ (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") -+ (parallel [(const_int 0)]))))] -+ "VECTOR_UNIT_VSX_P (V2DFmode)" -+ "") ++ ++;; Convert double word types to single word types ++(define_expand "vec_pack_trunc_v2df" ++ [(match_operand:V4SF 0 "vsx_register_operand" "") ++ (match_operand:V2DF 1 "vsx_register_operand" "") ++ (match_operand:V2DF 2 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" ++{ ++ rtx r1 = gen_reg_rtx (V4SFmode); ++ rtx r2 = gen_reg_rtx (V4SFmode); + -+(define_expand "vec_extract_oddv2df" -+ [(set (match_operand:V2DF 0 "vfloat_operand" "") -+ (vec_concat:V2DF -+ (vec_select:DF (match_operand:V2DF 1 "vfloat_operand" "") -+ (parallel [(const_int 1)])) -+ (vec_select:DF (match_operand:V2DF 2 "vfloat_operand" "") -+ (parallel [(const_int 1)]))))] -+ "VECTOR_UNIT_VSX_P (V2DFmode)" -+ "") ---- gcc/config/rs6000/spe.md (.../trunk) (revision 144557) -+++ gcc/config/rs6000/spe.md (.../branches/ibm/power7-meissner) (revision 144730) ++ emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); ++ emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); ++ emit_insn (gen_vec_extract_evenv4sf (operands[0], r1, r2)); ++ DONE; ++}) ++ ++(define_expand "vec_pack_sfix_trunc_v2df" ++ [(match_operand:V4SI 0 "vsx_register_operand" "") ++ (match_operand:V2DF 1 "vsx_register_operand" "") ++ (match_operand:V2DF 2 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" ++{ ++ rtx r1 = gen_reg_rtx (V4SImode); ++ rtx r2 = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); ++ emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); ++ emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); ++ DONE; ++}) ++ ++(define_expand "vec_pack_ufix_trunc_v2df" ++ [(match_operand:V4SI 0 "vsx_register_operand" "") ++ (match_operand:V2DF 1 "vsx_register_operand" "") ++ (match_operand:V2DF 2 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" ++{ ++ rtx r1 = gen_reg_rtx (V4SImode); ++ rtx r2 = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); ++ emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); ++ emit_insn (gen_vec_extract_evenv4si (operands[0], r1, r2)); ++ DONE; ++}) ++ ++;; Convert single word types to double word ++(define_expand "vec_unpacks_hi_v4sf" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SF 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" ++{ ++ rtx reg = gen_reg_rtx (V4SFmode); ++ ++ emit_insn (gen_vec_interleave_highv4sf (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); ++ DONE; ++}) ++ ++(define_expand "vec_unpacks_lo_v4sf" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SF 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" ++{ ++ rtx reg = gen_reg_rtx (V4SFmode); ++ ++ emit_insn (gen_vec_interleave_lowv4sf (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); ++ DONE; ++}) ++ ++(define_expand "vec_unpacks_float_hi_v4si" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SI 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" ++{ ++ rtx reg = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); ++ DONE; ++}) ++ ++(define_expand "vec_unpacks_float_lo_v4si" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SI 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" ++{ ++ rtx reg = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); ++ DONE; ++}) ++ ++(define_expand "vec_unpacku_float_hi_v4si" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SI 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" ++{ ++ rtx reg = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vec_interleave_highv4si (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); ++ DONE; ++}) ++ ++(define_expand "vec_unpacku_float_lo_v4si" ++ [(match_operand:V2DF 0 "vsx_register_operand" "") ++ (match_operand:V4SI 1 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" ++{ ++ rtx reg = gen_reg_rtx (V4SImode); ++ ++ emit_insn (gen_vec_interleave_lowv4si (reg, operands[1], operands[1])); ++ emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); ++ DONE; ++}) +--- gcc/config/rs6000/spe.md (.../trunk) (revision 145777) ++++ gcc/config/rs6000/spe.md (.../branches/ibm/power7-meissner) (revision 146027) @@ -99,7 +99,7 @@ (define_insn "*divsf3_gpr" ;; Floating point conversion instructions. @@ -2176,8 +2694,8 @@ testsuite/ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))] "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" ---- gcc/config/rs6000/constraints.md (.../trunk) (revision 144557) -+++ gcc/config/rs6000/constraints.md (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/constraints.md (.../trunk) (revision 145777) ++++ gcc/config/rs6000/constraints.md (.../branches/ibm/power7-meissner) (revision 146027) @@ -17,6 +17,8 @@ ;; along with GCC; see the file COPYING3. If not see ;; . @@ -2187,7 +2705,7 @@ testsuite/ ;; Register constraints (define_register_constraint "f" "TARGET_HARD_FLOAT && TARGET_FPRS -@@ -50,6 +52,23 @@ (define_register_constraint "y" "CR_REGS +@@ -50,6 +52,28 @@ (define_register_constraint "y" "CR_REGS (define_register_constraint "z" "XER_REGS" "@internal") @@ -2207,11 +2725,16 @@ testsuite/ +;; any VSX register +(define_register_constraint "wa" "rs6000_vsx_reg_class" + "@internal") ++ ++;; Altivec style load/store that ignores the bottom bits of the address ++(define_memory_constraint "wZ" ++ "Indexed or indirect memory operand, ignoring the bottom 4 bits" ++ (match_operand 0 "altivec_indexed_or_indirect_operand")) + ;; Integer constraints (define_constraint "I" -@@ -159,3 +178,7 @@ (define_constraint "t" +@@ -159,3 +183,7 @@ (define_constraint "t" (define_constraint "W" "vector constant that does not require memory" (match_operand 0 "easy_vector_constant")) @@ -2219,8 +2742,8 @@ testsuite/ +(define_constraint "j" + "Zero vector constant" + (match_test "(op == const0_rtx || op == CONST0_RTX (GET_MODE (op)))")) ---- gcc/config/rs6000/predicates.md (.../trunk) (revision 144557) -+++ gcc/config/rs6000/predicates.md (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/predicates.md (.../trunk) (revision 145777) ++++ gcc/config/rs6000/predicates.md (.../branches/ibm/power7-meissner) (revision 146027) @@ -38,6 +38,37 @@ (define_predicate "altivec_register_oper || ALTIVEC_REGNO_P (REGNO (op)) || REGNO (op) > LAST_VIRTUAL_REGISTER"))) @@ -2270,7 +2793,7 @@ testsuite/ /* Force constants to memory before reload to utilize compress_float_constant. Avoid this when flag_unsafe_math_optimizations is enabled -@@ -396,13 +431,16 @@ (define_predicate "indexed_or_indirect_o +@@ -396,16 +431,36 @@ (define_predicate "indexed_or_indirect_o (match_code "mem") { op = XEXP (op, 0); @@ -2289,7 +2812,27 @@ testsuite/ return indexed_or_indirect_address (op, mode); }) -@@ -1336,3 +1374,19 @@ (define_predicate "stmw_operation" ++;; Return 1 if the operand is an indexed or indirect memory operand with an ++;; AND -16 in it, used to recognize when we need to switch to Altivec loads ++;; to realign loops instead of VSX (altivec silently ignores the bottom bits, ++;; while VSX uses the full address and traps) ++(define_predicate "altivec_indexed_or_indirect_operand" ++ (match_code "mem") ++{ ++ op = XEXP (op, 0); ++ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) ++ && GET_CODE (op) == AND ++ && GET_CODE (XEXP (op, 1)) == CONST_INT ++ && INTVAL (XEXP (op, 1)) == -16) ++ return indexed_or_indirect_address (XEXP (op, 0), mode); ++ ++ return 0; ++}) ++ + ;; Return 1 if the operand is an indexed or indirect address. + (define_special_predicate "indexed_or_indirect_address" + (and (match_test "REG_P (op) +@@ -1336,3 +1391,19 @@ (define_predicate "stmw_operation" return 1; }) @@ -2309,8 +2852,8 @@ testsuite/ + + return 1; +}) ---- gcc/config/rs6000/ppc-asm.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/ppc-asm.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/ppc-asm.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/ppc-asm.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -63,7 +63,7 @@ #define f16 16 #define f17 17 @@ -2464,8 +3007,8 @@ testsuite/ /* * Macros to glue together two tokens. */ ---- gcc/config/rs6000/linux64.opt (.../trunk) (revision 144557) -+++ gcc/config/rs6000/linux64.opt (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/linux64.opt (.../trunk) (revision 145777) ++++ gcc/config/rs6000/linux64.opt (.../branches/ibm/power7-meissner) (revision 146027) @@ -20,5 +20,5 @@ ; . @@ -2473,8 +3016,8 @@ testsuite/ -Target Report Mask(PROFILE_KERNEL) +Target Report Var(TARGET_PROFILE_KERNEL) Call mcount for profiling before a function prologue ---- gcc/config/rs6000/sysv4.opt (.../trunk) (revision 144557) -+++ gcc/config/rs6000/sysv4.opt (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/sysv4.opt (.../trunk) (revision 145777) ++++ gcc/config/rs6000/sysv4.opt (.../branches/ibm/power7-meissner) (revision 146027) @@ -32,7 +32,7 @@ Target RejectNegative Joined Specify bit size of immediate TLS offsets @@ -2498,9 +3041,9 @@ testsuite/ Use alternate register names ;; FIXME: Does nothing. ---- gcc/config/rs6000/rs6000-protos.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000-protos.h (.../branches/ibm/power7-meissner) (revision 144730) -@@ -64,9 +64,14 @@ extern int insvdi_rshift_rlwimi_p (rtx, +--- gcc/config/rs6000/rs6000-protos.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000-protos.h (.../branches/ibm/power7-meissner) (revision 146027) +@@ -64,9 +64,15 @@ extern int insvdi_rshift_rlwimi_p (rtx, extern int registers_ok_for_quad_peep (rtx, rtx); extern int mems_ok_for_quad_peep (rtx, rtx); extern bool gpr_or_gpr_p (rtx, rtx); @@ -2513,10 +3056,11 @@ testsuite/ +extern bool rs6000_cannot_change_mode_class (enum machine_mode, + enum machine_mode, + enum reg_class); ++extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool); extern int paired_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx); extern void paired_expand_vector_move (rtx operands[]); -@@ -170,7 +175,6 @@ extern int rs6000_register_move_cost (en +@@ -170,7 +176,6 @@ 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); @@ -2524,15 +3068,15 @@ testsuite/ extern void rs6000_conditional_register_usage (void); /* Declare functions in rs6000-c.c */ -@@ -189,4 +193,6 @@ const char * rs6000_xcoff_strip_dollar ( +@@ -189,4 +194,6 @@ const char * rs6000_xcoff_strip_dollar ( void rs6000_final_prescan_insn (rtx, rtx *operand, int num_operands); extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER]; +extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES]; +extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER]; #endif /* rs6000-protos.h */ ---- gcc/config/rs6000/t-rs6000 (.../trunk) (revision 144557) -+++ gcc/config/rs6000/t-rs6000 (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/t-rs6000 (.../trunk) (revision 145777) ++++ gcc/config/rs6000/t-rs6000 (.../branches/ibm/power7-meissner) (revision 146027) @@ -16,3 +16,33 @@ rs6000-c.o: $(srcdir)/config/rs6000/rs60 # The rs6000 backend doesn't cause warnings in these files. @@ -2568,8 +3112,8 @@ testsuite/ + $(srcdir)/config/rs6000/dfp.md \ + $(srcdir)/config/rs6000/paired.md --- gcc/config/rs6000/power7.md (.../trunk) (revision 0) -+++ gcc/config/rs6000/power7.md (.../branches/ibm/power7-meissner) (revision 144730) -@@ -0,0 +1,320 @@ ++++ gcc/config/rs6000/power7.md (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,318 @@ +;; Scheduling description for IBM POWER7 processor. +;; Copyright (C) 2009 Free Software Foundation, Inc. +;; @@ -2888,11 +3432,72 @@ testsuite/ + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power7")) + "du2_power7,VSU_power7") +--- gcc/config/rs6000/rs6000-c.c (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000-c.c (.../branches/ibm/power7-meissner) (revision 146027) +@@ -105,11 +105,14 @@ altivec_categorize_keyword (const cpp_to + if (ident == C_CPP_HASHNODE (vector_keyword)) + return C_CPP_HASHNODE (__vector_keyword); + +- if (ident == C_CPP_HASHNODE (pixel_keyword)) +- return C_CPP_HASHNODE (__pixel_keyword); ++ if (TARGET_ALTIVEC) ++ { ++ if (ident == C_CPP_HASHNODE (pixel_keyword)) ++ return C_CPP_HASHNODE (__pixel_keyword); + +- if (ident == C_CPP_HASHNODE (bool_keyword)) +- return C_CPP_HASHNODE (__bool_keyword); ++ if (ident == C_CPP_HASHNODE (bool_keyword)) ++ return C_CPP_HASHNODE (__bool_keyword); ++ } + + return ident; + } +@@ -127,20 +130,23 @@ init_vector_keywords (void) + __vector_keyword = get_identifier ("__vector"); + C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL; + +- __pixel_keyword = get_identifier ("__pixel"); +- C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL; +- +- __bool_keyword = get_identifier ("__bool"); +- C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL; +- + vector_keyword = get_identifier ("vector"); + C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL; + +- pixel_keyword = get_identifier ("pixel"); +- C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL; ++ if (TARGET_ALTIVEC) ++ { ++ __pixel_keyword = get_identifier ("__pixel"); ++ C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL; + ++ __bool_keyword = get_identifier ("__bool"); ++ C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL; + ---- gcc/config/rs6000/rs6000-c.c (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000-c.c (.../branches/ibm/power7-meissner) (revision 144730) -@@ -265,6 +265,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi ++ pixel_keyword = get_identifier ("pixel"); ++ C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL; + +- bool_keyword = get_identifier ("bool"); +- C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL; ++ bool_keyword = get_identifier ("bool"); ++ C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL; ++ } + } + + /* Called to decide whether a conditional macro should be expanded. +@@ -207,7 +213,8 @@ rs6000_macro_to_expand (cpp_reader *pfil + if (rid_code == RID_UNSIGNED || rid_code == RID_LONG + || rid_code == RID_SHORT || rid_code == RID_SIGNED + || rid_code == RID_INT || rid_code == RID_CHAR +- || rid_code == RID_FLOAT) ++ || rid_code == RID_FLOAT ++ || (rid_code == RID_DOUBLE && TARGET_VSX)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + /* If the next keyword is bool or pixel, it +@@ -277,13 +284,14 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi builtin_define ("_ARCH_PWR6X"); if (! TARGET_POWER && ! TARGET_POWER2 && ! TARGET_POWERPC) builtin_define ("_ARCH_COM"); @@ -2901,7 +3506,34 @@ testsuite/ if (TARGET_ALTIVEC) { builtin_define ("__ALTIVEC__"); -@@ -306,6 +308,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi + builtin_define ("__VEC__=10206"); + + /* Define the AltiVec syntactic elements. */ +- builtin_define ("__vector=__attribute__((altivec(vector__)))"); + builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short"); + builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned"); + +@@ -292,9 +300,18 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi + /* Define this when supporting context-sensitive keywords. */ + builtin_define ("__APPLE_ALTIVEC__"); + +- builtin_define ("vector=vector"); + builtin_define ("pixel=pixel"); + builtin_define ("bool=bool"); ++ } ++ } ++ if (TARGET_ALTIVEC || TARGET_VSX) ++ { ++ /* Define the AltiVec/VSX syntactic elements. */ ++ builtin_define ("__vector=__attribute__((altivec(vector__)))"); ++ ++ if (!flag_iso) ++ { ++ builtin_define ("vector=vector"); + init_vector_keywords (); + + /* Enable context-sensitive macros. */ +@@ -318,6 +335,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi /* Used by libstdc++. */ if (TARGET_NO_LWSYNC) builtin_define ("__NO_LWSYNC__"); @@ -2910,9 +3542,119 @@ testsuite/ /* May be overridden by target configuration. */ RS6000_CPU_CPP_ENDIAN_BUILTINS(); ---- gcc/config/rs6000/rs6000.opt (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000.opt (.../branches/ibm/power7-meissner) (revision 144730) -@@ -111,24 +111,44 @@ mhard-float +@@ -496,6 +515,8 @@ const struct altivec_builtin_types altiv + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, +@@ -639,6 +660,12 @@ const struct altivec_builtin_types altiv + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, ++ { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, ++ RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, +@@ -687,6 +714,12 @@ const struct altivec_builtin_types altiv + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, ++ { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, ++ RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, +@@ -1190,6 +1223,8 @@ const struct altivec_builtin_types altiv + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, +@@ -1366,6 +1401,8 @@ const struct altivec_builtin_types altiv + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, +@@ -1451,6 +1488,8 @@ const struct altivec_builtin_types altiv + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, +@@ -1475,6 +1514,12 @@ const struct altivec_builtin_types altiv + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, ++ { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, ++ RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, +@@ -1932,6 +1977,8 @@ const struct altivec_builtin_types altiv + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, +@@ -2091,6 +2138,12 @@ const struct altivec_builtin_types altiv + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, ++ RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, 0 }, ++ { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, ++ RS6000_BTI_V2DF, RS6000_BTI_bool_V4SI, RS6000_BTI_V2DF, 0 }, ++ { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, +@@ -2981,8 +3034,10 @@ altivec_resolve_overloaded_builtin (tree + const struct altivec_builtin_types *desc; + int n; + +- 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)) + return NULL_TREE; + + /* For now treat vec_splats and vec_promote as the same. */ +--- gcc/config/rs6000/rs6000.opt (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000.opt (.../branches/ibm/power7-meissner) (revision 146027) +@@ -111,24 +111,60 @@ mhard-float Target Report RejectNegative InverseMask(SOFT_FLOAT, HARD_FLOAT) Use hardware floating point @@ -2928,24 +3670,40 @@ testsuite/ +Use vector/scalar (VSX) instructions + +mvsx-vector-memory -+Target Report Var(TARGET_VSX_VECTOR_MEMORY) Init(-1) -+If -mvsx, use VSX vector load/store instructions instead of Altivec instructions ++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 Report Var(TARGET_VSX_VECTOR_FLOAT) Init(-1) -+If -mvsx, use VSX arithmetic instructions for float vectors (on by default) ++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 Report Var(TARGET_VSX_VECTOR_DOUBLE) Init(-1) -+If -mvsx, use VSX arithmetic instructions for double vectors (on by default) ++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 Report Var(TARGET_VSX_SCALAR_DOUBLE) Init(-1) -+If -mvsx, use VSX arithmetic instructions for scalar double (on by default) ++Target Undocumented Report Var(TARGET_VSX_SCALAR_DOUBLE) Init(-1) ++; If -mvsx, use VSX arithmetic instructions for scalar double (on by default) + +mvsx-scalar-memory -+Target Report Var(TARGET_VSX_SCALAR_MEMORY) -+If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default) ++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 ++ ++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 mupdate -Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE) @@ -2966,7 +3724,7 @@ testsuite/ Generate fused multiply/add instructions msched-prolog -@@ -194,7 +214,7 @@ Target RejectNegative Joined +@@ -194,7 +230,7 @@ Target RejectNegative Joined -mvrsave=yes/no Deprecated option. Use -mvrsave/-mno-vrsave instead misel @@ -2975,8 +3733,8 @@ testsuite/ Generate isel instructions misel= ---- gcc/config/rs6000/linux64.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/linux64.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/linux64.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/linux64.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -114,7 +114,7 @@ extern int dot_symbols; error (INVALID_32BIT, "32"); \ if (TARGET_PROFILE_KERNEL) \ @@ -2986,8 +3744,8 @@ testsuite/ error (INVALID_32BIT, "profile-kernel"); \ } \ } \ ---- gcc/config/rs6000/rs6000.c (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000.c (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/rs6000.c (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -178,9 +178,6 @@ int rs6000_spe; /* Nonzero if we want SPE ABI extensions. */ int rs6000_spe_abi; @@ -2998,26 +3756,35 @@ testsuite/ /* Nonzero if floating point operations are done in the GPRs. */ int rs6000_float_gprs = 0; -@@ -227,10 +224,18 @@ int dot_symbols; +@@ -227,12 +224,26 @@ int dot_symbols; const char *rs6000_debug_name; int rs6000_debug_stack; /* debug stack applications */ int rs6000_debug_arg; /* debug argument handling */ +int rs6000_debug_reg; /* debug register classes */ +int rs6000_debug_addr; /* debug memory addressing */ ++int rs6000_debug_cost; /* debug rtx_costs */ /* Value is TRUE if register/mode pair is acceptable. */ bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; +-/* Built in types. */ +/* Maximum number of registers needed for a given register class and mode. */ +unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES]; + +/* How many registers are needed for a given register and mode. */ +unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; + - /* Built in types. */ ++/* Map register number to register class. */ ++enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; ++/* Reload functions based on the type and the vector unit. */ ++static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2]; ++ ++/* Built in types. */ tree rs6000_builtin_types[RS6000_BTI_MAX]; -@@ -270,7 +275,6 @@ struct { + tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; + +@@ -270,7 +281,6 @@ struct { bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */ bool spe; /* True if -mspe= was used. */ bool float_gprs; /* True if -mfloat-gprs= was used. */ @@ -3025,7 +3792,7 @@ testsuite/ bool long_double; /* True if -mlong-double- was used. */ bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */ bool vrsave; /* True if -mvrsave was used. */ -@@ -286,6 +290,18 @@ struct builtin_description +@@ -286,6 +296,18 @@ struct builtin_description const char *const name; const enum rs6000_builtins code; }; @@ -3044,7 +3811,7 @@ testsuite/ /* Target cpu costs. */ -@@ -749,6 +765,25 @@ struct processor_costs power6_cost = { +@@ -749,6 +771,25 @@ struct processor_costs power6_cost = { 16, /* prefetch streams */ }; @@ -3070,7 +3837,26 @@ testsuite/ static bool rs6000_function_ok_for_sibcall (tree, tree); static const char *rs6000_invalid_within_doloop (const_rtx); -@@ -963,12 +998,10 @@ static tree rs6000_gimplify_va_arg (tree +@@ -827,7 +868,10 @@ static void rs6000_xcoff_file_end (void) + #endif + static int rs6000_variable_issue (FILE *, int, rtx, int); + static bool rs6000_rtx_costs (rtx, int, int, int *, bool); ++static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool); ++static int rs6000_debug_address_cost (rtx, bool); + static int rs6000_adjust_cost (rtx, rtx, rtx, int); ++static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int); + static void rs6000_sched_init (FILE *, int, int); + static bool is_microcoded_insn (rtx); + static bool is_nonpipeline_insn (rtx); +@@ -906,6 +950,7 @@ static rtx altivec_expand_stv_builtin (e + static rtx altivec_expand_vec_init_builtin (tree, tree, rtx); + static rtx altivec_expand_vec_set_builtin (tree); + static rtx altivec_expand_vec_ext_builtin (tree, rtx); ++static rtx vsx_expand_builtin (tree, rtx, bool *); + static int get_element_number (tree, tree); + static bool rs6000_handle_option (size_t, const char *, int); + static void rs6000_parse_tls_size_option (void); +@@ -963,14 +1008,16 @@ static tree rs6000_gimplify_va_arg (tree static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree); static bool rs6000_scalar_mode_supported_p (enum machine_mode); static bool rs6000_vector_mode_supported_p (enum machine_mode); @@ -3084,8 +3870,14 @@ testsuite/ -static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx); static tree rs6000_stack_protect_fail (void); ++static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class, ++ enum machine_mode, ++ struct secondary_reload_info *); ++ const int INSN_NOT_AVAILABLE = -1; -@@ -1045,6 +1078,9 @@ static const char alt_reg_names[][8] = + static enum machine_mode rs6000_eh_return_filter_mode (void); + +@@ -1045,6 +1092,9 @@ static const char alt_reg_names[][8] = #endif #ifndef TARGET_PROFILE_KERNEL #define TARGET_PROFILE_KERNEL 0 @@ -3095,8 +3887,13 @@ testsuite/ #endif /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ -@@ -1299,28 +1335,96 @@ static const char alt_reg_names[][8] = +@@ -1297,30 +1347,101 @@ static const char alt_reg_names[][8] = + #undef TARGET_INSTANTIATE_DECLS + #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls ++#undef TARGET_SECONDARY_RELOAD ++#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload ++ struct gcc_target targetm = TARGET_INITIALIZER; +/* Return number of consecutive hard regs needed starting at reg REGNO @@ -3202,7 +3999,7 @@ testsuite/ /* The CR register can only hold CC modes. */ if (CR_REGNO_P (regno)) -@@ -1331,28 +1435,312 @@ rs6000_hard_regno_mode_ok (int regno, en +@@ -1331,28 +1452,389 @@ rs6000_hard_regno_mode_ok (int regno, en /* AltiVec only in AldyVec registers. */ if (ALTIVEC_REGNO_P (regno)) @@ -3215,10 +4012,16 @@ testsuite/ - /* We cannot put TImode anywhere except general register and it must be - able to fit within the register set. */ -+ /* Don't allow anything but word sized integers (aka pointers) in CTR/LR. You -+ really don't want to spill your floating point values to those -+ registers. Also do it for the old MQ register in the power. */ -+ if (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO) ++ /* Don't allow anything but word sized integers (aka pointers) in CTR/LR. ++ You really don't want to spill your floating point values to those ++ registers. Also do it for the old MQ register in the power. ++ ++ While this is desirable in theory, disabling float to go in LR/CTR does ++ cause some regressions, so until they are taken care of, revert to the old ++ behavior by default for most power systems, but enable it for power7. */ ++ if ((TARGET_DISALLOW_FLOAT_IN_LR_CTR > 0 ++ || (TARGET_DISALLOW_FLOAT_IN_LR_CTR < 0 && TARGET_VSX)) ++ && (regno == CTR_REGNO || regno == LR_REGNO || regno == MQ_REGNO)) + return (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) <= UNITS_PER_WORD); + @@ -3327,12 +4130,43 @@ testsuite/ + enum reg_class vsx_rc = (TARGET_ALTIVEC ? VSX_REGS : FLOAT_REGS); + bool float_p = (TARGET_HARD_FLOAT && TARGET_FPRS); + ++ /* Precalculate REGNO_REG_CLASS. */ ++ rs6000_regno_regclass[0] = GENERAL_REGS; ++ for (r = 1; r < 32; ++r) ++ rs6000_regno_regclass[r] = BASE_REGS; ++ ++ for (r = 32; r < 64; ++r) ++ rs6000_regno_regclass[r] = FLOAT_REGS; ++ ++ for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r) ++ rs6000_regno_regclass[r] = NO_REGS; ++ ++ for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r) ++ rs6000_regno_regclass[r] = ALTIVEC_REGS; ++ ++ rs6000_regno_regclass[CR0_REGNO] = CR0_REGS; ++ for (r = CR1_REGNO; r <= CR7_REGNO; ++r) ++ rs6000_regno_regclass[r] = CR_REGS; ++ ++ rs6000_regno_regclass[MQ_REGNO] = MQ_REGS; ++ rs6000_regno_regclass[LR_REGNO] = LINK_REGS; ++ rs6000_regno_regclass[CTR_REGNO] = CTR_REGS; ++ rs6000_regno_regclass[XER_REGNO] = XER_REGS; ++ rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS; ++ rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS; ++ rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS; ++ rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS; ++ rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS; ++ rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS; ++ + /* Precalculate vector information, this must be set up before the + rs6000_hard_regno_nregs_internal below. */ + for (m = 0; m < NUM_MACHINE_MODES; ++m) + { + rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE; + rs6000_vector_reg_class[m] = NO_REGS; ++ rs6000_vector_reload[m][0] = CODE_FOR_nothing; ++ rs6000_vector_reload[m][1] = CODE_FOR_nothing; + } + + /* TODO, add TI/V2DI mode for moving data if Altivec or VSX. */ @@ -3409,8 +4243,13 @@ testsuite/ + /* 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)) ++ = ((VECTOR_UNIT_VSX_P (V4SFmode) ++ && VECTOR_MEM_VSX_P (V4SFmode) ++ && !TARGET_V4SF_ALTIVEC_REGS) + ? vsx_rc + : (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) + ? ALTIVEC_REGS @@ -3428,6 +4267,41 @@ testsuite/ + + 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_64BIT) ++ { ++ rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store; ++ rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load; ++ rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store; ++ rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load; ++ rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store; ++ rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load; ++ rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store; ++ rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load; ++ rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store; ++ 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; ++ } ++ else ++ { ++ rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store; ++ rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load; ++ rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store; ++ rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load; ++ rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store; ++ rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load; ++ rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store; ++ rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load; ++ rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store; ++ 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; ++ } ++ } ++ + /* Precalculate HARD_REGNO_NREGS. */ + for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) + for (m = 0; m < NUM_MACHINE_MODES; ++m) @@ -3520,7 +4394,7 @@ testsuite/ } #if TARGET_MACHO -@@ -1482,12 +1870,15 @@ rs6000_override_options (const char *def +@@ -1482,12 +1964,15 @@ rs6000_override_options (const char *def {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, @@ -3539,7 +4413,7 @@ testsuite/ {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT}, {"970", PROCESSOR_POWER4, POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64}, -@@ -1520,9 +1911,10 @@ rs6000_override_options (const char *def +@@ -1520,9 +2005,10 @@ rs6000_override_options (const char *def POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_MFPGPR}, @@ -3552,7 +4426,7 @@ testsuite/ {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK}, {"powerpc64", PROCESSOR_POWERPC64, POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}, -@@ -1549,7 +1941,8 @@ rs6000_override_options (const char *def +@@ -1549,7 +2035,8 @@ rs6000_override_options (const char *def POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW @@ -3562,7 +4436,7 @@ testsuite/ }; set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT; -@@ -1594,10 +1987,6 @@ rs6000_override_options (const char *def +@@ -1594,10 +2081,6 @@ rs6000_override_options (const char *def } } @@ -3573,7 +4447,7 @@ testsuite/ if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 || rs6000_cpu == PROCESSOR_PPCE500MC) { -@@ -1642,15 +2031,47 @@ rs6000_override_options (const char *def +@@ -1642,17 +2125,61 @@ rs6000_override_options (const char *def } } @@ -3610,7 +4484,7 @@ testsuite/ if (! strcmp (rs6000_debug_name, "all")) - rs6000_debug_stack = rs6000_debug_arg = 1; + rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg -+ = rs6000_debug_addr = 1; ++ = rs6000_debug_addr = rs6000_debug_cost = 1; else if (! strcmp (rs6000_debug_name, "stack")) rs6000_debug_stack = 1; else if (! strcmp (rs6000_debug_name, "arg")) @@ -3619,10 +4493,24 @@ testsuite/ + rs6000_debug_reg = 1; + else if (! strcmp (rs6000_debug_name, "addr")) + rs6000_debug_addr = 1; ++ else if (! strcmp (rs6000_debug_name, "cost")) ++ rs6000_debug_cost = 1; else error ("unknown -mdebug-%s switch", rs6000_debug_name); ++ ++ /* If -mdebug=cost or -mdebug=all, replace the cost target hooks with ++ debug versions that call the real version and then prints debugging ++ information. */ ++ if (TARGET_DEBUG_COST) ++ { ++ targetm.rtx_costs = rs6000_debug_rtx_costs; ++ targetm.address_cost = rs6000_debug_address_cost; ++ targetm.sched.adjust_cost = rs6000_debug_adjust_cost; ++ } } -@@ -1741,8 +2162,8 @@ rs6000_override_options (const char *def + + if (rs6000_traceback_name) +@@ -1741,8 +2268,8 @@ rs6000_override_options (const char *def rs6000_spe = 0; if (!rs6000_explicit_options.float_gprs) rs6000_float_gprs = 0; @@ -3633,7 +4521,7 @@ testsuite/ } /* Detect invalid option combinations with E500. */ -@@ -1751,12 +2172,14 @@ rs6000_override_options (const char *def +@@ -1751,12 +2278,14 @@ rs6000_override_options (const char *def rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4 && rs6000_cpu != PROCESSOR_POWER5 && rs6000_cpu != PROCESSOR_POWER6 @@ -3649,7 +4537,7 @@ testsuite/ rs6000_sched_restricted_insns_priority = (rs6000_sched_groups ? 1 : 0); -@@ -1951,6 +2374,10 @@ rs6000_override_options (const char *def +@@ -1951,6 +2480,10 @@ rs6000_override_options (const char *def rs6000_cost = &power6_cost; break; @@ -3660,7 +4548,7 @@ testsuite/ default: gcc_unreachable (); } -@@ -2001,7 +2428,7 @@ rs6000_override_options (const char *def +@@ -2001,7 +2534,7 @@ rs6000_override_options (const char *def static tree rs6000_builtin_mask_for_load (void) { @@ -3669,7 +4557,7 @@ testsuite/ return altivec_builtin_mask_for_load; else return 0; -@@ -2015,18 +2442,19 @@ rs6000_builtin_mask_for_load (void) +@@ -2015,18 +2548,27 @@ rs6000_builtin_mask_for_load (void) static tree rs6000_builtin_conversion (enum tree_code code, tree type) { @@ -3681,6 +4569,14 @@ testsuite/ case FIX_TRUNC_EXPR: switch (TYPE_MODE (type)) { ++ case V2DImode: ++ if (!VECTOR_UNIT_VSX_P (V2DFmode)) ++ return NULL_TREE; ++ ++ return TYPE_UNSIGNED (type) ++ ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS] ++ : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS]; ++ case V4SImode: + if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) + return NULL_TREE; @@ -3694,9 +4590,18 @@ testsuite/ default: return NULL_TREE; } -@@ -2035,9 +2463,12 @@ rs6000_builtin_conversion (enum tree_cod +@@ -2034,10 +2576,22 @@ rs6000_builtin_conversion (enum tree_cod + case FLOAT_EXPR: switch (TYPE_MODE (type)) { ++ case V2DImode: ++ if (!VECTOR_UNIT_VSX_P (V2DFmode)) ++ return NULL_TREE; ++ ++ return TYPE_UNSIGNED (type) ++ ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDSP] ++ : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDSP]; ++ case V4SImode: + if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode)) + return NULL_TREE; @@ -3706,10 +4611,11 @@ testsuite/ - : rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFSX]; + ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF] + : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF]; ++ default: return NULL_TREE; } -@@ -2150,6 +2581,14 @@ rs6000_builtin_vec_perm (tree type, tree +@@ -2150,6 +2704,14 @@ rs6000_builtin_vec_perm (tree type, tree d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF]; break; @@ -3724,7 +4630,7 @@ testsuite/ default: return NULL_TREE; } -@@ -2229,6 +2668,7 @@ static bool +@@ -2229,6 +2791,7 @@ static bool rs6000_handle_option (size_t code, const char *arg, int value) { enum fpu_type_t fpu_type = FPU_NONE; @@ -3732,7 +4638,7 @@ testsuite/ switch (code) { -@@ -2331,14 +2771,14 @@ rs6000_handle_option (size_t code, const +@@ -2336,14 +2899,14 @@ rs6000_handle_option (size_t code, const rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE)); break; @@ -3754,7 +4660,7 @@ testsuite/ break; case OPT_mspe: -@@ -2967,6 +3407,9 @@ output_vec_const_move (rtx *operands) +@@ -2972,6 +3535,9 @@ output_vec_const_move (rtx *operands) vec = operands[1]; mode = GET_MODE (dest); @@ -3764,7 +4670,7 @@ testsuite/ if (TARGET_ALTIVEC) { rtx splat_vec; -@@ -3190,20 +3633,21 @@ rs6000_expand_vector_init (rtx target, r +@@ -3195,20 +3761,21 @@ rs6000_expand_vector_init (rtx target, r if (n_var == 0) { rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)); @@ -3789,7 +4695,7 @@ testsuite/ ; /* Splat vector element. */ else { -@@ -3213,6 +3657,18 @@ rs6000_expand_vector_init (rtx target, r +@@ -3218,6 +3785,18 @@ rs6000_expand_vector_init (rtx target, r } } @@ -3808,7 +4714,7 @@ testsuite/ /* Store value to stack temp. Load vector element. Splat. */ if (all_same) { -@@ -3272,6 +3728,13 @@ rs6000_expand_vector_set (rtx target, rt +@@ -3277,6 +3856,13 @@ rs6000_expand_vector_set (rtx target, rt int width = GET_MODE_SIZE (inner_mode); int i; @@ -3822,7 +4728,7 @@ testsuite/ /* Load single variable value. */ mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0); emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val); -@@ -3309,6 +3772,13 @@ rs6000_expand_vector_extract (rtx target +@@ -3314,6 +3900,13 @@ rs6000_expand_vector_extract (rtx target enum machine_mode inner_mode = GET_MODE_INNER (mode); rtx mem, x; @@ -3836,7 +4742,7 @@ testsuite/ /* Allocate mode-sized buffer. */ mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0); -@@ -3627,9 +4097,13 @@ rs6000_legitimate_offset_address_p (enum +@@ -3632,9 +4225,13 @@ rs6000_legitimate_offset_address_p (enum case V8HImode: case V4SFmode: case V4SImode: @@ -3846,13 +4752,13 @@ testsuite/ + /* AltiVec/VSX vector modes. Only reg+reg addressing is valid and constant offset zero should not occur due to canonicalization. */ - return false; -+ if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)) ++ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) + return false; + break; case V4HImode: case V2SImode: -@@ -3646,6 +4120,11 @@ rs6000_legitimate_offset_address_p (enum +@@ -3651,6 +4248,11 @@ rs6000_legitimate_offset_address_p (enum if (TARGET_E500_DOUBLE) return SPE_CONST_OFFSET_OK (offset); @@ -3864,7 +4770,7 @@ testsuite/ case DDmode: case DImode: /* On e500v2, we may have: -@@ -3716,7 +4195,9 @@ avoiding_indexed_address_p (enum machine +@@ -3721,7 +4323,9 @@ avoiding_indexed_address_p (enum machine { /* Avoid indexed addressing for modes that have non-indexed load/store instruction forms. */ @@ -3875,7 +4781,7 @@ testsuite/ } inline bool -@@ -3808,25 +4289,30 @@ rtx +@@ -3813,25 +4417,30 @@ rtx rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode) { @@ -3919,7 +4825,7 @@ testsuite/ { HOST_WIDE_INT high_int, low_int; rtx sum; -@@ -3834,7 +4320,7 @@ rs6000_legitimize_address (rtx x, rtx ol +@@ -3839,7 +4448,7 @@ rs6000_legitimize_address (rtx x, rtx ol high_int = INTVAL (XEXP (x, 1)) - low_int; sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0), GEN_INT (high_int)), 0); @@ -3928,7 +4834,7 @@ testsuite/ } else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG -@@ -3850,32 +4336,29 @@ rs6000_legitimize_address (rtx x, rtx ol +@@ -3855,32 +4464,29 @@ rs6000_legitimize_address (rtx x, rtx ol && mode != TFmode && mode != TDmode) { @@ -3973,7 +4879,7 @@ testsuite/ rtx op1 = XEXP (x, 0); rtx op2 = XEXP (x, 1); rtx y; -@@ -3894,12 +4377,12 @@ rs6000_legitimize_address (rtx x, rtx ol +@@ -3899,12 +4505,12 @@ rs6000_legitimize_address (rtx x, rtx ol y = gen_rtx_PLUS (Pmode, op1, op2); if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2)) @@ -3990,7 +4896,7 @@ testsuite/ } else if (TARGET_ELF && TARGET_32BIT -@@ -3915,7 +4398,7 @@ rs6000_legitimize_address (rtx x, rtx ol +@@ -3920,7 +4526,7 @@ rs6000_legitimize_address (rtx x, rtx ol { rtx reg = gen_reg_rtx (Pmode); emit_insn (gen_elf_high (reg, x)); @@ -3999,7 +4905,7 @@ testsuite/ } else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic -@@ -3933,17 +4416,34 @@ rs6000_legitimize_address (rtx x, rtx ol +@@ -3938,17 +4544,35 @@ rs6000_legitimize_address (rtx x, rtx ol { rtx reg = gen_reg_rtx (Pmode); emit_insn (gen_macho_high (reg, x)); @@ -4031,13 +4937,14 @@ testsuite/ + } + else + fprintf (stderr, "NULL returned\n"); ++ fprintf (stderr, "\n"); + } + + return ret; } /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. -@@ -4232,6 +4732,9 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4237,6 +4861,9 @@ rs6000_legitimize_reload_address (rtx x, int opnum, int type, int ind_levels ATTRIBUTE_UNUSED, int *win) { @@ -4047,7 +4954,7 @@ testsuite/ /* We must recognize output that we have already generated ourselves. */ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS -@@ -4243,17 +4746,17 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4248,17 +4875,17 @@ rs6000_legitimize_reload_address (rtx x, BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, opnum, (enum reload_type)type); *win = 1; @@ -4073,7 +4980,7 @@ testsuite/ { /* Result of previous invocation of this function on Darwin floating point constant. */ -@@ -4261,40 +4764,42 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4266,40 +4893,40 @@ rs6000_legitimize_reload_address (rtx x, BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, (enum reload_type)type); *win = 1; @@ -4099,8 +5006,7 @@ testsuite/ + && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode) + && GET_CODE (XEXP (x, 1)) == CONST_INT + && (INTVAL (XEXP (x, 1)) & 3) != 0 -+ && !ALTIVEC_VECTOR_MODE (mode) -+ && !VSX_VECTOR_MODE (mode) ++ && VECTOR_MEM_NONE_P (mode) + && GET_MODE_SIZE (mode) >= UNITS_PER_WORD + && TARGET_POWERPC64) { @@ -4132,12 +5038,11 @@ testsuite/ + && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode + || mode == DDmode || mode == TDmode + || mode == DImode)) -+ && !ALTIVEC_VECTOR_MODE (mode) -+ && !VSX_VECTOR_MODE (mode)) ++ && VECTOR_MEM_NONE_P (mode)) { HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; -@@ -4305,42 +4810,44 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4310,42 +4937,45 @@ rs6000_legitimize_reload_address (rtx x, if (high + low != val) { *win = 0; @@ -4202,6 +5107,7 @@ testsuite/ + /* Don't do this for TFmode or TDmode, since the result isn't + offsettable. The same goes for DImode without 64-bit gprs and + DFmode and DDmode without fprs. */ ++ && VECTOR_MEM_NONE_P (mode) + && mode != TFmode + && mode != TDmode + && (mode != DImode || TARGET_POWERPC64) @@ -4210,7 +5116,7 @@ testsuite/ { #if TARGET_MACHO if (flag_pic) -@@ -4359,37 +4866,61 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4364,37 +4994,63 @@ rs6000_legitimize_reload_address (rtx x, BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, (enum reload_type)type); *win = 1; @@ -4229,7 +5135,7 @@ testsuite/ - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) == -16) -+ else if (VECTOR_MEM_ALTIVEC_P (mode) ++ else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) + && GET_CODE (x) == AND + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG @@ -4262,9 +5168,7 @@ testsuite/ + { + *win = 0; + ret = x; - } -- *win = 0; -- return x; ++ } + + if (TARGET_DEBUG_ADDR) + { @@ -4283,13 +5187,17 @@ testsuite/ + fprintf (stderr, "New address:\n"); + debug_rtx (ret); + } -+ } ++ ++ fprintf (stderr, "\n"); + } +- *win = 0; +- return x; + + return ret; } /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression -@@ -4412,77 +4943,101 @@ rs6000_legitimize_reload_address (rtx x, +@@ -4417,77 +5073,101 @@ rs6000_legitimize_reload_address (rtx x, int rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) { @@ -4297,9 +5205,10 @@ testsuite/ + rtx orig_x = x; + /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */ - if (TARGET_ALTIVEC +- if (TARGET_ALTIVEC - && ALTIVEC_VECTOR_MODE (mode) -+ && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)) ++ if ((TARGET_ALTIVEC || TARGET_VSX) ++ && VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) && GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == -16) @@ -4328,8 +5237,7 @@ testsuite/ + else if (legitimate_indirect_address_p (x, reg_ok_strict)) + ret = 1; + else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC) -+ && !VECTOR_MEM_ALTIVEC_P (mode) -+ /* && !VECTOR_MEM_VSX_P (mode) */ ++ && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) + && (TARGET_SPE && !SPE_VECTOR_MODE (mode)) + && mode != TFmode + && mode != TDmode @@ -4447,13 +5355,14 @@ testsuite/ + GET_MODE_NAME (mode), + reg_ok_strict); + debug_rtx (orig_x); ++ fprintf (stderr, "\n"); + } + + return ret; } /* Go to LABEL if ADDR (a legitimate address expression) -@@ -4499,28 +5054,40 @@ rs6000_legitimate_address (enum machine_ +@@ -4504,28 +5184,46 @@ rs6000_legitimate_address (enum machine_ bool rs6000_mode_dependent_address (rtx addr) { @@ -4479,6 +5388,11 @@ testsuite/ case PRE_MODIFY: - return TARGET_UPDATE; + ret = (TARGET_UPDATE != 0); ++ break; ++ ++ /* AND is only allowed in Altivec loads. */ ++ case AND: ++ ret = true; + break; default: @@ -4489,16 +5403,17 @@ testsuite/ + if (TARGET_DEBUG_ADDR) + { + fprintf (stderr, -+ "\nrs6000_mode_dependent_address: ret = %d\n", -+ (int)ret); ++ "\nrs6000_mode_dependent_address: ret = %s\n", ++ ret ? "true" : "false"); + debug_rtx (addr); ++ fprintf (stderr, "\n"); + } + + return ret; } /* Implement FIND_BASE_TERM. */ -@@ -4571,43 +5138,6 @@ rs6000_offsettable_memref_p (rtx op) +@@ -4576,43 +5274,6 @@ rs6000_offsettable_memref_p (rtx op) return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1); } @@ -4542,7 +5457,7 @@ testsuite/ /* Change register usage conditional on target flags. */ void rs6000_conditional_register_usage (void) -@@ -4672,14 +5202,14 @@ rs6000_conditional_register_usage (void) +@@ -4677,14 +5338,14 @@ rs6000_conditional_register_usage (void) = call_really_used_regs[14] = 1; } @@ -4559,7 +5474,28 @@ testsuite/ global_regs[VSCR_REGNO] = 1; if (TARGET_ALTIVEC_ABI) -@@ -5101,6 +5631,8 @@ rs6000_emit_move (rtx dest, rtx source, +@@ -4902,6 +5563,20 @@ rs6000_emit_move (rtx dest, rtx source, + operands[0] = dest; + operands[1] = source; + ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, ++ "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, " ++ "reload_completed = %d, can_create_pseudos = %d.\ndest:\n", ++ GET_MODE_NAME (mode), ++ reload_in_progress, ++ reload_completed, ++ can_create_pseudo_p ()); ++ debug_rtx (dest); ++ fprintf (stderr, "source:\n"); ++ debug_rtx (source); ++ } ++ + /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE + && ! FLOAT_MODE_P (mode) +@@ -5106,6 +5781,8 @@ rs6000_emit_move (rtx dest, rtx source, case V2SFmode: case V2SImode: case V1DImode: @@ -4568,7 +5504,7 @@ testsuite/ if (CONSTANT_P (operands[1]) && !easy_vector_constant (operands[1], mode)) operands[1] = force_const_mem (mode, operands[1]); -@@ -5270,6 +5802,9 @@ rs6000_emit_move (rtx dest, rtx source, +@@ -5275,6 +5952,9 @@ rs6000_emit_move (rtx dest, rtx source, break; case TImode: @@ -4578,7 +5514,7 @@ testsuite/ rs6000_eliminate_indexed_memrefs (operands); if (TARGET_POWER) -@@ -5285,7 +5820,7 @@ rs6000_emit_move (rtx dest, rtx source, +@@ -5290,7 +5970,7 @@ rs6000_emit_move (rtx dest, rtx source, break; default: @@ -4587,7 +5523,7 @@ testsuite/ } /* Above, we may have called force_const_mem which may have returned -@@ -5305,10 +5840,10 @@ rs6000_emit_move (rtx dest, rtx source, +@@ -5310,10 +5990,10 @@ rs6000_emit_move (rtx dest, rtx source, && TARGET_HARD_FLOAT && TARGET_FPRS) /* Nonzero if we can use an AltiVec register to pass this arg. */ @@ -4602,7 +5538,7 @@ testsuite/ && (NAMED)) /* Return a nonzero value to say to return the function value in -@@ -5549,7 +6084,7 @@ function_arg_boundary (enum machine_mode +@@ -5554,7 +6234,7 @@ function_arg_boundary (enum machine_mode && int_size_in_bytes (type) >= 8 && int_size_in_bytes (type) < 16)) return 64; @@ -4611,7 +5547,7 @@ testsuite/ || (type && TREE_CODE (type) == VECTOR_TYPE && int_size_in_bytes (type) >= 16)) return 128; -@@ -5694,7 +6229,7 @@ function_arg_advance (CUMULATIVE_ARGS *c +@@ -5699,7 +6379,7 @@ function_arg_advance (CUMULATIVE_ARGS *c cum->nargs_prototype--; if (TARGET_ALTIVEC_ABI @@ -4620,7 +5556,7 @@ testsuite/ || (type && TREE_CODE (type) == VECTOR_TYPE && int_size_in_bytes (type) == 16))) { -@@ -6288,7 +6823,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum +@@ -6293,7 +6973,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum else return gen_rtx_REG (mode, cum->vregno); else if (TARGET_ALTIVEC_ABI @@ -4629,7 +5565,7 @@ testsuite/ || (type && TREE_CODE (type) == VECTOR_TYPE && int_size_in_bytes (type) == 16))) { -@@ -7212,10 +7747,13 @@ static const struct builtin_description +@@ -7217,10 +7897,13 @@ static const struct builtin_description { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI }, { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI }, { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI }, @@ -4647,7 +5583,24 @@ testsuite/ { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI }, { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI }, { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI }, -@@ -7289,18 +7827,18 @@ static struct builtin_description bdesc_ +@@ -7242,6 +7925,16 @@ static const struct builtin_description + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL }, + ++ { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP }, ++ { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP }, ++ { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP }, ++ { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP }, ++ ++ { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP }, ++ { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP }, ++ { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP }, ++ { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP }, ++ + { 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 }, +@@ -7294,18 +7987,18 @@ static struct builtin_description bdesc_ { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX }, { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX }, { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP }, @@ -4678,7 +5631,7 @@ testsuite/ { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS }, { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS }, { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB }, -@@ -7331,7 +7869,7 @@ static struct builtin_description bdesc_ +@@ -7336,7 +8029,7 @@ static struct builtin_description bdesc_ { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB }, { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH }, { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH }, @@ -4687,7 +5640,133 @@ testsuite/ { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR }, { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM }, { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM }, -@@ -7796,6 +8334,11 @@ static struct builtin_description bdesc_ +@@ -7384,8 +8077,24 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS }, + { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR }, + +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP }, ++ { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP }, ++ { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP }, ++ { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP }, ++ { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP }, ++ { 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_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP }, ++ { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP }, ++ { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP }, ++ { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP }, ++ { 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_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 }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM }, +@@ -7397,8 +8106,8 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW }, +@@ -7423,8 +8132,8 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH }, +@@ -7439,8 +8148,8 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH }, +@@ -7457,8 +8166,8 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM }, +@@ -7491,8 +8200,8 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM }, +@@ -7510,7 +8219,10 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S }, + { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS }, +- { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR }, ++ { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR }, ++ ++ { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL }, ++ { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV }, + + { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 }, + { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 }, +@@ -7755,7 +8467,11 @@ static const struct builtin_description + { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI }, + { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI }, + { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI }, +- { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI } ++ { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }, ++ { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP }, ++ { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP }, ++ { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP }, ++ { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP }, + }; + + /* Simple unary operations: VECb = foo (unsigned literal) or VECb = +@@ -7781,6 +8497,18 @@ static struct builtin_description bdesc_ + { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX }, + { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH }, + ++ { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP }, ++ { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP }, ++ { MASK_VSX, CODE_FOR_vsx_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP }, ++ { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2, "__builtin_vsx_xvtsqrtdp", VSX_BUILTIN_XVTSQRTDP }, ++ { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP }, ++ ++ { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP }, ++ { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP }, ++ { MASK_VSX, CODE_FOR_vsx_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP }, ++ { 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_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 }, +@@ -7801,6 +8529,20 @@ static struct builtin_description bdesc_ { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH }, { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB }, @@ -4695,11 +5774,20 @@ testsuite/ + { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF }, + { 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 }, -@@ -8352,16 +8895,16 @@ altivec_expand_ld_builtin (tree exp, rtx +@@ -8357,16 +9099,16 @@ altivec_expand_ld_builtin (tree exp, rtx switch (fcode) { case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: @@ -4720,7 +5808,7 @@ testsuite/ break; default: *expandedp = false; -@@ -8405,16 +8948,16 @@ altivec_expand_st_builtin (tree exp, rtx +@@ -8410,16 +9152,16 @@ altivec_expand_st_builtin (tree exp, rtx switch (fcode) { case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: @@ -4741,7 +5829,57 @@ testsuite/ break; default: *expandedp = false; -@@ -9372,6 +9915,8 @@ rs6000_init_builtins (void) +@@ -8814,6 +9556,26 @@ altivec_expand_builtin (tree exp, rtx ta + /* Expand the builtin in EXP and store the result in TARGET. Store + true in *EXPANDEDP if we found a builtin to expand. */ + static rtx ++vsx_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, bool *expandedp) ++{ ++ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); ++ unsigned int fcode = DECL_FUNCTION_CODE (fndecl); ++ ++ if (fcode >= VSX_BUILTIN_OVERLOADED_FIRST ++ && fcode <= VSX_BUILTIN_OVERLOADED_LAST) ++ { ++ *expandedp = true; ++ error ("unresolved overload for vsx builtin %qF", fndecl); ++ return const0_rtx; ++ } ++ ++ *expandedp = false; ++ return NULL_RTX; ++} ++ ++/* Expand the builtin in EXP and store the result in TARGET. Store ++ true in *EXPANDEDP if we found a builtin to expand. */ ++static rtx + paired_expand_builtin (tree exp, rtx target, bool * expandedp) + { + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); +@@ -9325,6 +10087,13 @@ rs6000_expand_builtin (tree exp, rtx tar + if (success) + return ret; + } ++ if (TARGET_VSX) ++ { ++ ret = vsx_expand_builtin (exp, target, &success); ++ ++ if (success) ++ return ret; ++ } + if (TARGET_SPE) + { + ret = spe_expand_builtin (exp, target, &success); +@@ -9340,7 +10109,7 @@ rs6000_expand_builtin (tree exp, rtx tar + return ret; + } + +- gcc_assert (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT); ++ gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT); + + /* Handle simple unary operations. */ + d = (struct builtin_description *) bdesc_1arg; +@@ -9377,6 +10146,8 @@ rs6000_init_builtins (void) { V2SI_type_node = build_vector_type (intSI_type_node, 2); V2SF_type_node = build_vector_type (float_type_node, 2); @@ -4750,7 +5888,7 @@ testsuite/ V4HI_type_node = build_vector_type (intHI_type_node, 4); V4SI_type_node = build_vector_type (intSI_type_node, 4); V4SF_type_node = build_vector_type (float_type_node, 4); -@@ -9404,7 +9949,10 @@ rs6000_init_builtins (void) +@@ -9409,7 +10180,10 @@ rs6000_init_builtins (void) uintHI_type_internal_node = unsigned_intHI_type_node; intSI_type_internal_node = intSI_type_node; uintSI_type_internal_node = unsigned_intSI_type_node; @@ -4761,7 +5899,7 @@ testsuite/ void_type_internal_node = void_type_node; (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL, -@@ -9462,13 +10010,18 @@ rs6000_init_builtins (void) +@@ -9467,13 +10241,18 @@ rs6000_init_builtins (void) get_identifier ("__vector __pixel"), pixel_V8HI_type_node)); @@ -4781,10 +5919,41 @@ testsuite/ rs6000_common_init_builtins (); if (TARGET_PPC_GFXOPT) { -@@ -10407,6 +10960,26 @@ rs6000_common_init_builtins (void) +@@ -9936,6 +10715,8 @@ altivec_init_builtins (void) + = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); + tree v4sf_ftype_v4sf + = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); ++ tree v2df_ftype_v2df ++ = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE); + tree void_ftype_pcvoid_int_int + = build_function_type_list (void_type_node, + pcvoid_type_node, integer_type_node, +@@ -10093,6 +10874,9 @@ altivec_init_builtins (void) + case V4SFmode: + type = v4sf_ftype_v4sf; + break; ++ case V2DFmode: ++ type = v2df_ftype_v2df; ++ break; + default: + gcc_unreachable (); + } +@@ -10412,6 +11196,38 @@ rs6000_common_init_builtins (void) 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, @@ -4808,7 +5977,7 @@ testsuite/ /* Add the simple ternary operators. */ d = bdesc_3arg; -@@ -10443,6 +11016,12 @@ rs6000_common_init_builtins (void) +@@ -10448,6 +11264,12 @@ rs6000_common_init_builtins (void) case VOIDmode: type = opaque_ftype_opaque_opaque_opaque; break; @@ -4821,7 +5990,7 @@ testsuite/ case V4SImode: type = v4si_ftype_v4si_v4si_v4si; break; -@@ -10466,6 +11045,12 @@ rs6000_common_init_builtins (void) +@@ -10471,6 +11293,12 @@ rs6000_common_init_builtins (void) { switch (mode0) { @@ -4834,7 +6003,26 @@ testsuite/ case V4SImode: type = v4si_ftype_v4si_v4si_v16qi; break; -@@ -10721,6 +11306,10 @@ rs6000_common_init_builtins (void) +@@ -10556,6 +11384,9 @@ rs6000_common_init_builtins (void) + case VOIDmode: + type = opaque_ftype_opaque_opaque; + break; ++ case V2DFmode: ++ type = v2df_ftype_v2df_v2df; ++ break; + case V4SFmode: + type = v4sf_ftype_v4sf_v4sf; + break; +@@ -10705,6 +11536,8 @@ rs6000_common_init_builtins (void) + 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) +@@ -10726,6 +11559,14 @@ rs6000_common_init_builtins (void) type = v2si_ftype_v2sf; else if (mode0 == V2SImode && mode1 == QImode) type = v2si_ftype_char; @@ -4842,10 +6030,332 @@ testsuite/ + 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 (); -@@ -11601,13 +12190,101 @@ rs6000_instantiate_decls (void) +@@ -11508,8 +12349,10 @@ rtx + rs6000_secondary_memory_needed_rtx (enum machine_mode mode) + { + static bool eliminated = false; ++ rtx ret; ++ + if (mode != SDmode) +- return assign_stack_local (mode, GET_MODE_SIZE (mode), 0); ++ ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); + else + { + rtx mem = cfun->machine->sdmode_stack_slot; +@@ -11521,8 +12364,21 @@ rs6000_secondary_memory_needed_rtx (enum + cfun->machine->sdmode_stack_slot = mem; + eliminated = true; + } +- return mem; ++ ret = mem; + } ++ ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, "rs6000_secondary_memory_needed_rtx, mode %s, rtx:\n", ++ GET_MODE_NAME (mode)); ++ if (!ret) ++ fprintf (stderr, "\tNULL_RTX\n"); ++ else ++ debug_rtx (ret); ++ fprintf (stderr, "\n"); ++ } ++ ++ return ret; + } + + static tree +@@ -11556,6 +12412,282 @@ rs6000_check_sdmode (tree *tp, int *walk + return NULL_TREE; + } + ++enum reload_reg_type { ++ GPR_REGISTER_TYPE, ++ VECTOR_REGISTER_TYPE, ++ OTHER_REGISTER_TYPE ++}; ++ ++static enum reload_reg_type ++rs6000_reload_register_type (enum reg_class rclass) ++{ ++ switch (rclass) ++ { ++ case GENERAL_REGS: ++ case BASE_REGS: ++ return GPR_REGISTER_TYPE; ++ ++ case FLOAT_REGS: ++ case ALTIVEC_REGS: ++ case VSX_REGS: ++ return VECTOR_REGISTER_TYPE; ++ ++ default: ++ return OTHER_REGISTER_TYPE; ++ } ++} ++ ++/* Inform reload about cases where moving X with a mode MODE to a register in ++ RCLASS requires an extra scratch or immediate register. Return the class ++ needed for the immediate register. ++ ++ For VSX and Altivec, we may need a register to convert sp+offset into ++ reg+sp. */ ++ ++static enum reg_class ++rs6000_secondary_reload (bool in_p, ++ rtx x, ++ enum reg_class rclass, ++ enum machine_mode mode, ++ secondary_reload_info *sri) ++{ ++ enum reg_class ret; ++ enum insn_code icode; ++ ++ /* Convert vector loads and stores into gprs to use an additional base ++ register. */ ++ icode = rs6000_vector_reload[mode][in_p != false]; ++ if (icode != CODE_FOR_nothing) ++ { ++ ret = NO_REGS; ++ sri->icode = CODE_FOR_nothing; ++ sri->extra_cost = 0; ++ ++ if (GET_CODE (x) == MEM) ++ { ++ rtx addr = XEXP (x, 0); ++ ++ /* Loads to and stores from gprs can do reg+offset, and wouldn't need ++ an extra register in that case, but it would need an extra ++ register if the addressing is reg+reg or (reg+reg)&(-16). */ ++ if (rclass == GENERAL_REGS || rclass == BASE_REGS) ++ { ++ if (! rs6000_legitimate_offset_address_p (TImode, addr, true)) ++ { ++ sri->icode = icode; ++ /* account for splitting the loads, and converting the ++ address from reg+reg to reg. */ ++ sri->extra_cost = (((TARGET_64BIT) ? 3 : 5) ++ + ((GET_CODE (addr) == AND) ? 1 : 0)); ++ } ++ } ++ /* Loads to and stores from vector registers can only do reg+reg ++ addressing. Altivec registers can also do (reg+reg)&(-16). */ ++ else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS ++ || rclass == FLOAT_REGS) ++ { ++ if (rclass != ALTIVEC_REGS ++ && GET_CODE (addr) == AND ++ && GET_CODE (XEXP (addr, 1)) == CONST_INT ++ && INTVAL (XEXP (addr, 1)) == -16 ++ && (legitimate_indirect_address_p (XEXP (addr, 0), true) ++ || legitimate_indexed_address_p (XEXP (addr, 0), true))) ++ { ++ sri->icode = icode; ++ sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS) ++ ? 2 : 1); ++ } ++ else if (!legitimate_indexed_address_p (addr, true) ++ && !legitimate_indirect_address_p (addr, true)) ++ { ++ sri->icode = icode; ++ sri->extra_cost = 1; ++ } ++ else ++ icode = CODE_FOR_nothing; ++ } ++ /* Any other loads, including to pseudo registers which haven't been ++ assigned to a register yet, default to require a scratch ++ register. */ ++ else ++ { ++ sri->icode = icode; ++ sri->extra_cost = 2; ++ } ++ } ++ else ++ { ++ int regno = true_regnum (x); ++ ++ icode = CODE_FOR_nothing; ++ if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER) ++ ret = default_secondary_reload (in_p, x, rclass, mode, sri); ++ else ++ { ++ enum reg_class xclass = REGNO_REG_CLASS (regno); ++ enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass); ++ enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass); ++ ++ /* If memory is needed, use default_secondary_reload to create the ++ stack slot. */ ++ if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE) ++ ret = default_secondary_reload (in_p, x, rclass, mode, sri); ++ else ++ ret = NO_REGS; ++ } ++ } ++ } ++ else ++ ret = default_secondary_reload (in_p, x, rclass, mode, sri); ++ ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, ++ "rs6000_secondary_reload, return %s, in_p = %s, rclass = %s, " ++ "mode = %s", ++ reg_class_names[ret], ++ in_p ? "true" : "false", ++ reg_class_names[rclass], ++ GET_MODE_NAME (mode)); ++ ++ if (icode != CODE_FOR_nothing) ++ fprintf (stderr, ", reload func = %s, extra cost = %d\n", ++ insn_data[icode].name, sri->extra_cost); ++ else ++ fprintf (stderr, "\n"); ++ ++ debug_rtx (x); ++ fprintf (stderr, "\n"); ++ } ++ ++ return ret; ++} ++ ++/* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset ++ to SP+reg addressing. */ ++ ++void ++rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p) ++{ ++ int regno = true_regnum (reg); ++ enum machine_mode mode = GET_MODE (reg); ++ enum reg_class rclass; ++ rtx addr; ++ rtx and_op2 = NULL_RTX; ++ ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, "rs6000_secondary_reload_inner, type = %s\n", ++ store_p ? "store" : "load"); ++ fprintf (stderr, "reg:\n"); ++ debug_rtx (reg); ++ fprintf (stderr, "mem:\n"); ++ debug_rtx (mem); ++ fprintf (stderr, "scratch:\n"); ++ debug_rtx (scratch); ++ fprintf (stderr, "\n"); ++ } ++ ++ gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER); ++ gcc_assert (GET_CODE (mem) == MEM); ++ rclass = REGNO_REG_CLASS (regno); ++ addr = XEXP (mem, 0); ++ ++ switch (rclass) ++ { ++ /* Move reg+reg addresses into a scratch register for GPRs. */ ++ case GENERAL_REGS: ++ case BASE_REGS: ++ if (GET_CODE (addr) == AND) ++ { ++ and_op2 = XEXP (addr, 1); ++ addr = XEXP (addr, 0); ++ } ++ 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; ++ } ++ else if (GET_CODE (addr) == PRE_MODIFY ++ && REG_P (XEXP (addr, 0)) ++ && GET_CODE (XEXP (addr, 1)) == PLUS) ++ { ++ emit_insn (gen_rtx_SET (VOIDmode, XEXP (addr, 0), XEXP (addr, 1))); ++ addr = XEXP (addr, 0); ++ } ++ break; ++ ++ /* 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) ++ { ++ 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 ++ || and_op2 != NULL_RTX ++ || !rs6000_legitimate_offset_address_p (mode, addr, 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; ++ } ++ break; ++ ++ default: ++ gcc_unreachable (); ++ } ++ ++ /* If the original address involved an AND -16 that is part of the Altivec ++ addresses, recreate the and now. */ ++ 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)); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, ++ gen_rtvec (2, and_rtx, cc_clobber))); ++ addr = scratch; ++ } ++ ++ /* Adjust the address if it changed. */ ++ if (addr != XEXP (mem, 0)) ++ { ++ mem = change_address (mem, mode, addr); ++ if (TARGET_DEBUG_ADDR) ++ fprintf (stderr, "rs6000_secondary_reload_inner, mem adjusted.\n"); ++ } ++ ++ /* Now create the move. */ ++ if (store_p) ++ emit_insn (gen_rtx_SET (VOIDmode, mem, reg)); ++ else ++ emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); ++ ++ return; ++} + + /* Allocate a 64-bit stack slot to be used for copying SDmode + values through if this function has any SDmode references. */ +@@ -11606,15 +12738,146 @@ rs6000_instantiate_decls (void) instantiate_decl_rtl (cfun->machine->sdmode_stack_slot); } @@ -4871,32 +6381,52 @@ testsuite/ +rs6000_preferred_reload_class (rtx x, enum reg_class rclass) +{ + 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)) -+ return rclass; ++ ret = rclass; + -+ if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode) && rclass == ALTIVEC_REGS -+ && easy_vector_constant (x, mode)) -+ return rclass; ++ else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode) ++ && rclass == ALTIVEC_REGS && easy_vector_constant (x, mode)) ++ ret = rclass; + -+ if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) -+ return NO_REGS; ++ else if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) ++ ret = NO_REGS; + -+ if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) -+ return GENERAL_REGS; ++ else if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) ++ ret = GENERAL_REGS; + -+ /* For VSX, prefer the traditional registers. */ -+ if (rclass == VSX_REGS) ++ /* For VSX, prefer the traditional registers unless the address involves AND ++ -16, where we prefer to use the Altivec register so we don't have to break ++ down the AND. */ ++ else if (rclass == VSX_REGS) + { + if (mode == DFmode) -+ return FLOAT_REGS; ++ ret = FLOAT_REGS; + -+ if (ALTIVEC_VECTOR_MODE (mode)) -+ return ALTIVEC_REGS; ++ else if (altivec_indexed_or_indirect_operand (x, mode)) ++ ret = ALTIVEC_REGS; ++ ++ else if (ALTIVEC_VECTOR_MODE (mode)) ++ ret = ALTIVEC_REGS; ++ ++ else ++ ret = rclass; ++ } ++ else ++ ret = rclass; ++ ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, ++ "rs6000_preferred_reload_class, return %s, rclass = %s, x:\n", ++ reg_class_names[ret], reg_class_names[rclass]); ++ debug_rtx (x); ++ fprintf (stderr, "\n"); + } + -+ return rclass; ++ return ret; +} + +/* If we are copying between FP or AltiVec registers and anything else, we need @@ -4910,31 +6440,53 @@ testsuite/ + enum reg_class class2, + enum machine_mode mode) +{ ++ bool ret; ++ + if (class1 == class2) -+ return false; ++ ret = false; + -+ if (TARGET_VSX && VSX_MOVE_MODE (mode) && VSX_REG_CLASS_P (class1) -+ && VSX_REG_CLASS_P (class2)) -+ return false; ++ /* Under VSX, there are 3 register classes that values could be in (VSX_REGS, ++ ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy ++ between these classes. But we need memory for other things that can go in ++ FLOAT_REGS like SFmode. */ ++ else if (TARGET_VSX ++ && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode)) ++ && (class1 == VSX_REGS || class1 == ALTIVEC_REGS ++ || class1 == FLOAT_REGS)) ++ ret = (class2 != VSX_REGS && class2 != ALTIVEC_REGS ++ && class2 != FLOAT_REGS); + -+ if (class1 == FLOAT_REGS -+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 -+ || ((mode != DFmode) -+ && (mode != DDmode) -+ && (mode != DImode)))) -+ return true; ++ else if (class1 == VSX_REGS || class2 == VSX_REGS) ++ ret = true; + -+ if (class2 == FLOAT_REGS -+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 -+ || ((mode != DFmode) -+ && (mode != DDmode) -+ && (mode != DImode)))) -+ return true; ++ else if (class1 == FLOAT_REGS ++ && (!TARGET_MFPGPR || !TARGET_POWERPC64 ++ || ((mode != DFmode) ++ && (mode != DDmode) ++ && (mode != DImode)))) ++ ret = true; + -+ if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) -+ return true; ++ else if (class2 == FLOAT_REGS ++ && (!TARGET_MFPGPR || !TARGET_POWERPC64 ++ || ((mode != DFmode) ++ && (mode != DDmode) ++ && (mode != DImode)))) ++ ret = true; + -+ return false; ++ else if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) ++ ret = true; ++ ++ else ++ ret = false; ++ ++ if (TARGET_DEBUG_ADDR) ++ fprintf (stderr, ++ "rs6000_secondary_memory_needed, return: %s, class1 = %s, " ++ "class2 = %s, mode = %s\n", ++ ret ? "true" : "false", reg_class_names[class1], ++ reg_class_names[class2], GET_MODE_NAME (mode)); ++ ++ return ret; +} + /* Return the register class of a scratch register needed to copy IN into @@ -4947,51 +6499,157 @@ testsuite/ + enum machine_mode mode, rtx in) { ++ enum reg_class ret = NO_REGS; int regno; -@@ -11663,6 +12340,13 @@ rs6000_secondary_reload_class (enum reg_ - && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) - return (mode != SDmode) ? NO_REGS : GENERAL_REGS; -+ /* Memory, and FP/altivec registers can go into fp/altivec registers under -+ VSX. */ -+ if (TARGET_VSX -+ && (regno == -1 || VSX_REGNO_P (regno)) -+ && VSX_REG_CLASS_P (rclass)) -+ return NO_REGS; + if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN +@@ -11635,51 +12898,112 @@ rs6000_secondary_reload_class (enum reg_ + || GET_CODE (in) == HIGH + || GET_CODE (in) == LABEL_REF + || GET_CODE (in) == CONST)) +- return BASE_REGS; ++ ret = BASE_REGS; + } + +- if (GET_CODE (in) == REG) ++ if (ret == NO_REGS) + { +- regno = REGNO (in); +- if (regno >= FIRST_PSEUDO_REGISTER) ++ if (GET_CODE (in) == REG) ++ { ++ regno = REGNO (in); ++ if (regno >= FIRST_PSEUDO_REGISTER) ++ { ++ regno = true_regnum (in); ++ if (regno >= FIRST_PSEUDO_REGISTER) ++ regno = -1; ++ } ++ } ++ else if (GET_CODE (in) == SUBREG) + { + regno = true_regnum (in); + if (regno >= FIRST_PSEUDO_REGISTER) + regno = -1; + } +- } +- else if (GET_CODE (in) == SUBREG) +- { +- regno = true_regnum (in); +- if (regno >= FIRST_PSEUDO_REGISTER) ++ else + regno = -1; + - /* Memory, and AltiVec registers can go into AltiVec registers. */ - if ((regno == -1 || ALTIVEC_REGNO_P (regno)) - && rclass == ALTIVEC_REGS) -@@ -11676,6 +12360,28 @@ rs6000_secondary_reload_class (enum reg_ - /* Otherwise, we need GENERAL_REGS. */ - return GENERAL_REGS; - } ++ /* We can place anything into GENERAL_REGS and can put GENERAL_REGS ++ into anything. */ ++ if (rclass == GENERAL_REGS || rclass == BASE_REGS ++ || (regno >= 0 && INT_REGNO_P (regno))) ++ ret = NO_REGS; ++ ++ /* Constants, memory, and FP registers can go into FP registers. */ ++ else if ((regno == -1 || FP_REGNO_P (regno)) ++ && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) ++ ret = (mode != SDmode) ? NO_REGS : GENERAL_REGS; ++ ++ /* Memory, and FP/altivec registers can go into fp/altivec registers under ++ VSX. */ ++ else if (TARGET_VSX ++ && (regno == -1 || VSX_REGNO_P (regno)) ++ && VSX_REG_CLASS_P (rclass)) ++ ret = NO_REGS; ++ ++ /* Memory, and AltiVec registers can go into AltiVec registers. */ ++ else if ((regno == -1 || ALTIVEC_REGNO_P (regno)) ++ && rclass == ALTIVEC_REGS) ++ ret = NO_REGS; ++ ++ /* We can copy among the CR registers. */ ++ else if ((rclass == CR_REGS || rclass == CR0_REGS) ++ && regno >= 0 && CR_REGNO_P (regno)) ++ ret = NO_REGS; ++ ++ /* Otherwise, we need GENERAL_REGS. */ ++ else ++ ret = GENERAL_REGS; ++ } ++ ++ if (TARGET_DEBUG_ADDR) ++ { ++ fprintf (stderr, ++ "rs6000_secondary_reload_class, return %s, rclass = %s, " ++ "mode = %s, input rtx:\n", ++ reg_class_names[ret], reg_class_names[rclass], ++ GET_MODE_NAME (mode)); ++ debug_rtx (in); ++ fprintf (stderr, "\n"); + } +- else +- regno = -1; + +- /* We can place anything into GENERAL_REGS and can put GENERAL_REGS +- into anything. */ +- if (rclass == GENERAL_REGS || rclass == BASE_REGS +- || (regno >= 0 && INT_REGNO_P (regno))) +- return NO_REGS; +- +- /* Constants, memory, and FP registers can go into FP registers. */ +- if ((regno == -1 || FP_REGNO_P (regno)) +- && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) +- return (mode != SDmode) ? NO_REGS : GENERAL_REGS; +- +- /* Memory, and AltiVec registers can go into AltiVec registers. */ +- if ((regno == -1 || ALTIVEC_REGNO_P (regno)) +- && rclass == ALTIVEC_REGS) +- return NO_REGS; +- +- /* We can copy among the CR registers. */ +- if ((rclass == CR_REGS || rclass == CR0_REGS) +- && regno >= 0 && CR_REGNO_P (regno)) +- return NO_REGS; ++ return ret; ++} + +/* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */ -+ + +- /* Otherwise, we need GENERAL_REGS. */ +- return GENERAL_REGS; +bool +rs6000_cannot_change_mode_class (enum machine_mode from, + enum machine_mode to, + enum reg_class rclass) +{ -+ return (GET_MODE_SIZE (from) != GET_MODE_SIZE (to) -+ ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8 -+ || TARGET_IEEEQUAD) -+ && reg_classes_intersect_p (FLOAT_REGS, rclass)) -+ : (((TARGET_E500_DOUBLE -+ && ((((to) == DFmode) + ((from) == DFmode)) == 1 -+ || (((to) == TFmode) + ((from) == TFmode)) == 1 -+ || (((to) == DDmode) + ((from) == DDmode)) == 1 -+ || (((to) == TDmode) + ((from) == TDmode)) == 1 -+ || (((to) == DImode) + ((from) == DImode)) == 1)) -+ || (TARGET_SPE -+ && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1)) -+ && reg_classes_intersect_p (GENERAL_REGS, rclass))); -+} ++ bool ret = (GET_MODE_SIZE (from) != GET_MODE_SIZE (to) ++ ? ((GET_MODE_SIZE (from) < 8 || GET_MODE_SIZE (to) < 8 ++ || TARGET_IEEEQUAD) ++ && reg_classes_intersect_p (FLOAT_REGS, rclass)) ++ : (((TARGET_E500_DOUBLE ++ && ((((to) == DFmode) + ((from) == DFmode)) == 1 ++ || (((to) == TFmode) + ((from) == TFmode)) == 1 ++ || (((to) == DDmode) + ((from) == DDmode)) == 1 ++ || (((to) == TDmode) + ((from) == TDmode)) == 1 ++ || (((to) == DImode) + ((from) == DImode)) == 1)) ++ || (TARGET_VSX ++ && (VSX_VECTOR_MODE (from) + VSX_VECTOR_MODE (to)) == 1) ++ || (TARGET_ALTIVEC ++ && (ALTIVEC_VECTOR_MODE (from) ++ + ALTIVEC_VECTOR_MODE (to)) == 1) ++ || (TARGET_SPE ++ && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1)) ++ && reg_classes_intersect_p (GENERAL_REGS, rclass))); ++ ++ if (TARGET_DEBUG_ADDR) ++ fprintf (stderr, ++ "rs6000_cannot_change_mode_class, return %s, from = %s, " ++ "to = %s, rclass = %s\n", ++ ret ? "true" : "false", ++ GET_MODE_NAME (from), GET_MODE_NAME (to), ++ reg_class_names[rclass]); ++ ++ return ret; + } /* Given a comparison operation, return the bit number in CCR to test. We - know this is a valid comparison. -@@ -12406,6 +13112,26 @@ print_operand (FILE *file, rtx x, int co +@@ -12411,6 +13735,26 @@ print_operand (FILE *file, rtx x, int co fprintf (file, "%d", i + 1); return; @@ -5018,12 +6676,12 @@ testsuite/ case 'X': if (GET_CODE (x) == MEM && (legitimate_indexed_address_p (XEXP (x, 0), 0) -@@ -12518,13 +13244,16 @@ print_operand (FILE *file, rtx x, int co +@@ -12523,13 +13867,16 @@ print_operand (FILE *file, rtx x, int co /* Fall through. Must be [reg+reg]. */ } - if (TARGET_ALTIVEC -+ if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x)) ++ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (GET_MODE (x)) && GET_CODE (tmp) == AND && GET_CODE (XEXP (tmp, 1)) == CONST_INT && INTVAL (XEXP (tmp, 1)) == -16) @@ -5037,7 +6695,7 @@ testsuite/ else { if (!GET_CODE (tmp) == PLUS -@@ -13296,55 +14025,62 @@ output_e500_flip_gt_bit (rtx dst, rtx sr +@@ -13301,55 +14648,62 @@ output_e500_flip_gt_bit (rtx dst, rtx sr return string; } @@ -5139,7 +6797,7 @@ testsuite/ } /* Emit vector compare for operands OP0 and OP1 using code RCODE. -@@ -13355,129 +14091,111 @@ rs6000_emit_vector_compare (enum rtx_cod +@@ -13360,129 +14714,111 @@ rs6000_emit_vector_compare (enum rtx_cod rtx op0, rtx op1, enum machine_mode dmode) { @@ -5358,7 +7016,7 @@ testsuite/ if (swap_operands) { rtx tmp; -@@ -13485,69 +14203,23 @@ rs6000_emit_vector_compare (enum rtx_cod +@@ -13490,69 +14826,23 @@ rs6000_emit_vector_compare (enum rtx_cod op0 = op1; op1 = tmp; } @@ -5376,10 +7034,10 @@ testsuite/ - } - return mask; -} -- + -/* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if - valid insn doesn exist for given mode. */ - +- -static int -get_vsel_insn (enum machine_mode mode) -{ @@ -5425,9 +7083,9 @@ testsuite/ - rtx t, temp; - enum machine_mode dest_mode = GET_MODE (dest); - int vsel_insn_index = get_vsel_insn (GET_MODE (dest)); - -- temp = gen_reg_rtx (dest_mode); - +- temp = gen_reg_rtx (dest_mode); + - /* For each vector element, select op1 when mask is 1 otherwise - select op2. */ - t = gen_rtx_SET (VOIDmode, temp, @@ -5442,7 +7100,7 @@ testsuite/ } /* Emit vector conditional expression. -@@ -13562,15 +14234,29 @@ rs6000_emit_vector_cond_expr (rtx dest, +@@ -13567,15 +14857,29 @@ rs6000_emit_vector_cond_expr (rtx dest, enum rtx_code rcode = GET_CODE (cond); rtx mask; @@ -5475,7 +7133,7 @@ testsuite/ } /* Emit a conditional move: move TRUE_COND to DEST if OP of the -@@ -13766,8 +14452,8 @@ rs6000_emit_int_cmove (rtx dest, rtx op, +@@ -13771,8 +15075,8 @@ rs6000_emit_int_cmove (rtx dest, rtx op, { rtx condition_rtx, cr; @@ -5486,7 +7144,7 @@ testsuite/ return 0; /* We still have to do the compare, because isel doesn't do a -@@ -13776,12 +14462,24 @@ rs6000_emit_int_cmove (rtx dest, rtx op, +@@ -13781,12 +15085,24 @@ rs6000_emit_int_cmove (rtx dest, rtx op, condition_rtx = rs6000_generate_compare (GET_CODE (op)); cr = XEXP (condition_rtx, 0); @@ -5516,7 +7174,7 @@ testsuite/ return 1; } -@@ -13808,6 +14506,15 @@ rs6000_emit_minmax (rtx dest, enum rtx_c +@@ -13813,6 +15129,15 @@ rs6000_emit_minmax (rtx dest, enum rtx_c enum rtx_code c; rtx target; @@ -5532,7 +7190,7 @@ testsuite/ if (code == SMAX || code == SMIN) c = GE; else -@@ -15785,6 +16492,7 @@ emit_frame_save (rtx frame_reg, rtx fram +@@ -15790,6 +17115,7 @@ emit_frame_save (rtx frame_reg, rtx fram /* Some cases that need register indexed addressing. */ if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) @@ -5540,7 +7198,51 @@ testsuite/ || (TARGET_E500_DOUBLE && mode == DFmode) || (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode) -@@ -19320,6 +20028,7 @@ rs6000_issue_rate (void) +@@ -18804,6 +20130,7 @@ rs6000_adjust_cost (rtx insn, rtx link, + || rs6000_cpu_attr == CPU_PPC7450 + || rs6000_cpu_attr == CPU_POWER4 + || rs6000_cpu_attr == CPU_POWER5 ++ || (rs6000_cpu_attr == CPU_POWER7 && TARGET_POWER7_ADJUST_COST) + || rs6000_cpu_attr == CPU_CELL) + && recog_memoized (dep_insn) + && (INSN_CODE (dep_insn) >= 0)) +@@ -19043,6 +20370,35 @@ rs6000_adjust_cost (rtx insn, rtx link, + return cost; + } + ++/* Debug version of rs6000_adjust_cost. */ ++ ++static int ++rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) ++{ ++ int ret = rs6000_adjust_cost (insn, link, dep_insn, cost); ++ ++ if (ret != cost) ++ { ++ const char *dep; ++ ++ switch (REG_NOTE_KIND (link)) ++ { ++ default: dep = "unknown depencency"; break; ++ case REG_DEP_TRUE: dep = "data dependency"; break; ++ case REG_DEP_OUTPUT: dep = "output dependency"; break; ++ case REG_DEP_ANTI: dep = "anti depencency"; break; ++ } ++ ++ fprintf (stderr, ++ "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, " ++ "%s, insn:\n", ret, cost, dep); ++ ++ debug_rtx (insn); ++ } ++ ++ return ret; ++} ++ + /* The function returns a true if INSN is microcoded. + Return false otherwise. */ + +@@ -19324,6 +20680,7 @@ rs6000_issue_rate (void) case CPU_POWER4: case CPU_POWER5: case CPU_POWER6: @@ -5548,7 +7250,7 @@ testsuite/ return 5; default: return 1; -@@ -19921,6 +20630,41 @@ insn_must_be_first_in_group (rtx insn) +@@ -19925,6 +21282,41 @@ insn_must_be_first_in_group (rtx insn) break; } break; @@ -5590,7 +7292,7 @@ testsuite/ default: break; } -@@ -19982,6 +20726,23 @@ insn_must_be_last_in_group (rtx insn) +@@ -19986,6 +21378,23 @@ insn_must_be_last_in_group (rtx insn) break; } break; @@ -5614,7 +7316,7 @@ testsuite/ default: break; } -@@ -20554,8 +21315,8 @@ rs6000_handle_altivec_attribute (tree *n +@@ -20558,8 +21967,8 @@ rs6000_handle_altivec_attribute (tree *n else if (type == long_long_unsigned_type_node || type == long_long_integer_type_node) error ("use of % in AltiVec types is invalid"); @@ -5625,7 +7327,7 @@ testsuite/ else if (type == long_double_type_node) error ("use of % in AltiVec types is invalid"); else if (type == boolean_type_node) -@@ -20581,6 +21342,7 @@ rs6000_handle_altivec_attribute (tree *n +@@ -20585,6 +21994,7 @@ rs6000_handle_altivec_attribute (tree *n result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); break; case SFmode: result = V4SF_type_node; break; @@ -5633,7 +7335,51 @@ testsuite/ /* 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. */ -@@ -22116,7 +22878,7 @@ rs6000_register_move_cost (enum machine_ +@@ -22106,6 +23516,43 @@ rs6000_rtx_costs (rtx x, int code, int o + return false; + } + ++/* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */ ++ ++static bool ++rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total, ++ bool speed) ++{ ++ bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed); ++ ++ fprintf (stderr, ++ "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, " ++ "total = %d, speed = %s, x:\n", ++ ret ? "complete" : "scan inner", ++ GET_RTX_NAME (code), ++ GET_RTX_NAME (outer_code), ++ *total, ++ speed ? "true" : "false"); ++ ++ debug_rtx (x); ++ ++ return ret; ++} ++ ++/* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */ ++ ++static int ++rs6000_debug_address_cost (rtx x, bool speed) ++{ ++ int ret = TARGET_ADDRESS_COST (x, speed); ++ ++ fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n", ++ ret, speed ? "true" : "false"); ++ debug_rtx (x); ++ ++ return ret; ++} ++ ++ + /* A C expression returning the cost of moving data from a register of class + CLASS1 to one of CLASS2. */ + +@@ -22120,7 +23567,7 @@ rs6000_register_move_cost (enum machine_ if (! reg_classes_intersect_p (to, GENERAL_REGS)) from = to; @@ -5642,7 +7388,7 @@ testsuite/ return (rs6000_memory_move_cost (mode, from, 0) + rs6000_memory_move_cost (mode, GENERAL_REGS, 0)); -@@ -22136,6 +22898,12 @@ rs6000_register_move_cost (enum machine_ +@@ -22140,6 +23587,12 @@ rs6000_register_move_cost (enum machine_ return 2 * hard_regno_nregs[0][mode]; } @@ -5655,7 +7401,7 @@ testsuite/ /* Moving between two similar registers is just one instruction. */ else if (reg_classes_intersect_p (to, from)) return (mode == TFmode || mode == TDmode) ? 4 : 2; -@@ -22376,8 +23144,8 @@ rs6000_emit_swrsqrtsf (rtx dst, rtx src) +@@ -22380,8 +23833,8 @@ rs6000_emit_swrsqrtsf (rtx dst, rtx src) emit_label (XEXP (label, 0)); } @@ -5666,7 +7412,7 @@ testsuite/ void rs6000_emit_popcount (rtx dst, rtx src) -@@ -22385,6 +23153,16 @@ rs6000_emit_popcount (rtx dst, rtx src) +@@ -22389,6 +23842,16 @@ rs6000_emit_popcount (rtx dst, rtx src) enum machine_mode mode = GET_MODE (dst); rtx tmp1, tmp2; @@ -5683,7 +7429,7 @@ testsuite/ tmp1 = gen_reg_rtx (mode); if (mode == SImode) -@@ -22797,7 +23575,7 @@ rs6000_vector_mode_supported_p (enum mac +@@ -22801,7 +24264,7 @@ rs6000_vector_mode_supported_p (enum mac if (TARGET_SPE && SPE_VECTOR_MODE (mode)) return true; @@ -5693,8 +7439,8 @@ testsuite/ else --- gcc/config/rs6000/vsx.md (.../trunk) (revision 0) -+++ gcc/config/rs6000/vsx.md (.../branches/ibm/power7-meissner) (revision 144730) -@@ -0,0 +1,864 @@ ++++ gcc/config/rs6000/vsx.md (.../branches/ibm/power7-meissner) (revision 146027) +@@ -0,0 +1,1004 @@ +;; VSX patterns. +;; Copyright (C) 2009 +;; Free Software Foundation, Inc. @@ -5716,12 +7462,18 @@ testsuite/ +;; along with GCC; see the file COPYING3. If not see +;; . + ++;; Iterator for both scalar and vector floating point types supported by VSX ++(define_mode_iterator VSX_B [DF V4SF V2DF]) ++ +;; 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 types for load/store with update ++(define_mode_iterator VSX_U [V16QI V8HI V4SI V2DI V4SF V2DF TI DF]) ++ +;; Map into the appropriate load/store name based on the type +(define_mode_attr VSm [(V16QI "vw4") + (V8HI "vw4") @@ -5729,6 +7481,7 @@ testsuite/ + (V4SF "vw4") + (V2DF "vd2") + (V2DI "vd2") ++ (DF "d") + (TI "vw4")]) + +;; Map into the appropriate suffix based on the type @@ -5738,6 +7491,7 @@ testsuite/ + (V4SF "sp") + (V2DF "dp") + (V2DI "dp") ++ (DF "dp") + (TI "sp")]) + +;; Map into the register class used @@ -5747,30 +7501,126 @@ testsuite/ + (V4SF "wf") + (V2DI "wd") + (V2DF "wd") ++ (DF "ws") + (TI "wd")]) + ++;; Map into the register class used for float<->int conversions ++(define_mode_attr VSr2 [(V2DF "wd") ++ (V4SF "wf") ++ (DF "!f#r")]) ++ ++(define_mode_attr VSr3 [(V2DF "wa") ++ (V4SF "wa") ++ (DF "!f#r")]) ++ +;; Same size integer type for floating point data +(define_mode_attr VSi [(V4SF "v4si") -+ (V2DF "v2di")]) ++ (V2DF "v2di") ++ (DF "di")]) + +(define_mode_attr VSI [(V4SF "V4SI") -+ (V2DF "V2DI")]) ++ (V2DF "V2DI") ++ (DF "DI")]) + +;; Word size for same size conversion +(define_mode_attr VSc [(V4SF "w") -+ (V2DF "d")]) ++ (V2DF "d") ++ (DF "d")]) + +;; Bitsize for DF load with update +(define_mode_attr VSbit [(SI "32") + (DI "64")]) + ++;; Map into either s or v, depending on whether this is a scalar or vector ++;; operation ++(define_mode_attr VSv [(V16QI "v") ++ (V8HI "v") ++ (V4SI "v") ++ (V4SF "v") ++ (V2DI "v") ++ (V2DF "v") ++ (TI "v") ++ (DF "s")]) ++ ++;; Appropriate type for add ops (and other simple FP ops) ++(define_mode_attr VStype_simple [(V2DF "vecfloat") ++ (V4SF "vecfloat") ++ (DF "fp")]) ++ ++(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d") ++ (V4SF "fp_addsub_s") ++ (DF "fp_addsub_d")]) ++ ++;; Appropriate type for multiply ops ++(define_mode_attr VStype_mul [(V2DF "vecfloat") ++ (V4SF "vecfloat") ++ (DF "dmul")]) ++ ++(define_mode_attr VSfptype_mul [(V2DF "fp_mul_d") ++ (V4SF "fp_mul_s") ++ (DF "fp_mul_d")]) ++ ++;; Appropriate type for divide ops. For now, just lump the vector divide with ++;; the scalar divides ++(define_mode_attr VStype_div [(V2DF "ddiv") ++ (V4SF "sdiv") ++ (DF "ddiv")]) ++ ++(define_mode_attr VSfptype_div [(V2DF "fp_div_d") ++ (V4SF "fp_div_s") ++ (DF "fp_div_d")]) ++ ++;; Appropriate type for sqrt ops. For now, just lump the vector sqrt with ++;; the scalar sqrt ++(define_mode_attr VStype_sqrt [(V2DF "dsqrt") ++ (V4SF "sdiv") ++ (DF "ddiv")]) ++ ++(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d") ++ (V4SF "fp_sqrt_s") ++ (DF "fp_sqrt_d")]) ++ ++;; Appropriate type for load + update ++(define_mode_attr VStype_load_update [(V16QI "vecload") ++ (V8HI "vecload") ++ (V4SI "vecload") ++ (V4SF "vecload") ++ (V2DI "vecload") ++ (V2DF "vecload") ++ (TI "vecload") ++ (DF "fpload")]) ++ ++;; Appropriate type for store + update ++(define_mode_attr VStype_store_update [(V16QI "vecstore") ++ (V8HI "vecstore") ++ (V4SI "vecstore") ++ (V4SF "vecstore") ++ (V2DI "vecstore") ++ (V2DF "vecstore") ++ (TI "vecstore") ++ (DF "fpstore")]) ++ ++;; Constants for creating unspecs +(define_constants -+ [(UNSPEC_VSX_CONCAT_V2DF 500)]) ++ [(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)]) + +;; VSX moves +(define_insn "*vsx_mov" -+ [(set (match_operand:VSX_L 0 "nonimmediate_operand" "=Z,,,?Z,?wa,?wa,*o,*r,*r,,?wa,v") -+ (match_operand:VSX_L 1 "input_operand" ",Z,,wa,Z,wa,r,o,r,j,j,W"))] ++ [(set (match_operand:VSX_L 0 "nonimmediate_operand" "=Z,,,?Z,?wa,?wa,*o,*r,*r,,?wa,v,wZ,v") ++ (match_operand:VSX_L 1 "input_operand" ",Z,,wa,Z,wa,r,o,r,j,j,W,v,wZ"))] + "VECTOR_MEM_VSX_P (mode) + && (register_operand (operands[0], mode) + || register_operand (operands[1], mode))" @@ -5787,7 +7637,7 @@ testsuite/ + + case 2: + case 5: -+ return "xvmov %x0,%x1"; ++ return "xxlor %x0,%x1,%x1"; + + case 6: + case 7: @@ -5801,11 +7651,17 @@ testsuite/ + case 11: + return output_vec_const_move (operands); + ++ case 12: ++ return "stvx %1,%y0"; ++ ++ case 13: ++ return "lvx %0,%y1"; ++ + default: + gcc_unreachable (); + } +} -+ [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,store,load,*,vecsimple,vecsimple,*")]) ++ [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")]) + +;; Load/store with update +;; Define insns that do load or store with update. Because VSX only has @@ -5817,575 +7673,592 @@ testsuite/ +;; tie and these are the pair most likely to be tieable (and the ones +;; that will benefit the most). + -+(define_insn "*vsx_load_update64" -+ [(set (match_operand:VSX_L 3 "vsx_register_operand" "=,?wa") -+ (mem:VSX_L (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") -+ (match_operand:DI 2 "gpc_reg_operand" "r,r")))) -+ (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") -+ (plus:DI (match_dup 1) -+ (match_dup 2)))] -+ "TARGET_64BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" -+ "lxux %x3,%0,%2" -+ [(set_attr "type" "vecload")]) -+ -+(define_insn "*vsx_load_update32" -+ [(set (match_operand:VSX_L 3 "vsx_register_operand" "=,?wa") -+ (mem:VSX_L (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") -+ (match_operand:SI 2 "gpc_reg_operand" "r,r")))) -+ (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") -+ (plus:SI (match_dup 1) -+ (match_dup 2)))] -+ "TARGET_32BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" -+ "lxux %x3,%0,%2" -+ [(set_attr "type" "vecload")]) -+ -+(define_insn "*vsx_store_update64" -+ [(set (mem:VSX_L (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") -+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))) -+ (match_operand:VSX_L 3 "gpc_reg_operand" ",?wa")) -+ (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") -+ (plus:DI (match_dup 1) -+ (match_dup 2)))] -+ "TARGET_64BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" -+ "stxux %x3,%0,%2" -+ [(set_attr "type" "vecstore")]) -+ -+(define_insn "*vsx_store_update32" -+ [(set (mem:VSX_L (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") -+ (match_operand:SI 2 "gpc_reg_operand" "r,r"))) -+ (match_operand:VSX_L 3 "gpc_reg_operand" ",?wa")) -+ (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") -+ (plus:SI (match_dup 1) -+ (match_dup 2)))] -+ "TARGET_32BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" -+ "stxux %x3,%0,%2" -+ [(set_attr "type" "vecstore")]) -+ -+(define_insn "*vsx_loaddf_update" -+ [(set (match_operand:DF 3 "vsx_register_operand" "=ws,?wa") -+ (mem:DF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") -+ (match_operand:P 2 "gpc_reg_operand" "r,r")))) ++(define_insn "*vsx_load_update_" ++ [(set (match_operand:VSX_U 3 "vsx_register_operand" "=,?wa") ++ (mem:VSX_U (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") ++ (match_operand:P 2 "gpc_reg_operand" "r,r")))) + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) + (match_dup 2)))] -+ "TARGET_BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (DFmode)" -+ "lxsdux %x3,%0,%2" -+ [(set_attr "type" "vecload")]) ++ " && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" ++ "lxux %x3,%0,%2" ++ [(set_attr "type" "")]) + -+(define_insn "*vsx_storedf_update" -+ [(set (mem:DF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") -+ (match_operand:P 2 "gpc_reg_operand" "r,r"))) -+ (match_operand:DF 3 "gpc_reg_operand" "ws,?wa")) ++(define_insn "*vsx_store_update_" ++ [(set (mem:VSX_U (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") ++ (match_operand:P 2 "gpc_reg_operand" "r,r"))) ++ (match_operand:VSX_U 3 "gpc_reg_operand" ",?wa")) + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) + (match_dup 2)))] -+ "TARGET_BIT && TARGET_UPDATE && VECTOR_MEM_VSX_P (DFmode)" -+ "stxsdux %x3,%0,%2" -+ [(set_attr "type" "vecstore")]) ++ " && TARGET_UPDATE && VECTOR_MEM_VSX_P (mode)" ++ "stxux %x3,%0,%2" ++ [(set_attr "type" "")]) + +;; We may need to have a varient on the pattern for use in the prologue +;; that doesn't depend on TARGET_UPDATE. + + -+;; VSX vector floating point arithmetic instructions ++;; VSX scalar and vector floating point arithmetic instructions +(define_insn "*vsx_add3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (plus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvadd %x0,%x1,%x2" -+ [(set_attr "type" "vecfloat")]) ++ "xadd %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_sub3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (minus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvsub %x0,%x1,%x2" -+ [(set_attr "type" "vecfloat")]) ++ "xsub %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_mul3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvmul %x0,%x1,%x2" -+ [(set_attr "type" "vecfloat")]) ++ "xmul %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_div3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (div:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvdiv %x0,%x1,%x2" -+ [(set_attr "type" "vecfdiv")]) ++ "xdiv %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fre2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "")] ++(define_insn "vsx_tdiv3" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")] ++ UNSPEC_VSX_XVTDIV))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xtdiv %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_insn "vsx_fre2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] + UNSPEC_FRES))] -+ "flag_finite_math_only && VECTOR_UNIT_VSX_P (mode)" -+ "xvre %x0,%x1" -+ [(set_attr "type" "fp")]) ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xre %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_neg2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (neg:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvneg %x0,%x1" -+ [(set_attr "type" "vecfloat")]) ++ "xneg %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_abs2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvabs %x0,%x1" -+ [(set_attr "type" "vecfloat")]) ++ "xabs %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_nabs2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (neg:VSX_F -+ (abs:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" ""))))] ++(define_insn "vsx_nabs2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (neg:VSX_B ++ (abs:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvnabs %x0,%x1" -+ [(set_attr "type" "vecfloat")]) ++ "xnabs %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_smax3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (smax:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++(define_insn "vsx_smax3" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvmax %x0,%x1,%x2" -+ [(set_attr "type" "veccmp")]) ++ "xmax %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_smin3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (smin:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvmin %x0,%x1,%x2" -+ [(set_attr "type" "veccmp")]) ++ "xmin %x0,%x1,%x2" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_sqrt2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (sqrt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvsqrt %x0,%x1" -+ [(set_attr "type" "vecfdiv")]) ++ "xsqrt %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_insn "vsx_rsqrte2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] ++ UNSPEC_VSX_XVRSQRTE))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xrsqrte %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_insn "vsx_tsqrt2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] ++ UNSPEC_VSX_XVTSQRT))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xtsqrt %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +;; Fused vector multiply/add instructions -+(define_insn "*vsx_fmadd4" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (plus:VSX_F -+ (mult:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" "%,") -+ (match_operand:VSX_F 2 "vsx_register_operand" ",0")) -+ (match_operand:VSX_F 3 "gpc_reg_operand" "0,")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD" -+ "@ -+ xvmadda %x0,%x1,%x2 -+ xvmaddm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) + -+(define_insn "*vsx_fmsub4" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (minus:VSX_F -+ (mult:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" "%,") -+ (match_operand:VSX_F 2 "vsx_register_operand" ",0")) -+ (match_operand:VSX_F 3 "vsx_register_operand" "0,")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD" -+ "@ -+ xvmsuba %x0,%x1,%x2 -+ xvmsubm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) ++;; Note we have a pattern for the multiply/add operations that uses unspec and ++;; does not check -mfused-madd to allow users to use these ops when they know ++;; they want the fused multiply/add. + -+(define_insn "*vsx_fnmadd4_1" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (neg:VSX_F -+ (plus:VSX_F -+ (mult:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" "%,") -+ (match_operand:VSX_F 2 "vsx_register_operand" ",0")) -+ (match_operand:VSX_F 3 "vsx_register_operand" "0,"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD ++(define_expand "vsx_fmadd4" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "") ++ (plus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "") ++ (match_operand:VSX_B 2 "vsx_register_operand" "")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++{ ++ if (!TARGET_FUSED_MADD) ++ { ++ emit_insn (gen_vsx_fmadd4_2 (operands[0], operands[1], operands[2], ++ operands[3])); ++ DONE; ++ } ++}) ++ ++(define_insn "*vsx_fmadd4_1" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (plus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD" ++ "@ ++ xmadda %x0,%x1,%x2 ++ xmaddm %x0,%x1,%x3 ++ xmadda %x0,%x1,%x2 ++ xmaddm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_insn "vsx_fmadd4_2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0") ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")] ++ UNSPEC_VSX_XVMADD))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "@ ++ xmadda %x0,%x1,%x2 ++ xmaddm %x0,%x1,%x3 ++ xmadda %x0,%x1,%x2 ++ xmaddm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_expand "vsx_fmsub4" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "") ++ (minus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "") ++ (match_operand:VSX_B 2 "vsx_register_operand" "")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++{ ++ if (!TARGET_FUSED_MADD) ++ { ++ emit_insn (gen_vsx_fmsub4_2 (operands[0], operands[1], operands[2], ++ operands[3])); ++ DONE; ++ } ++}) ++ ++(define_insn "*vsx_fmsub4_1" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (minus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD" ++ "@ ++ xmsuba %x0,%x1,%x2 ++ xmsubm %x0,%x1,%x3 ++ xmsuba %x0,%x1,%x2 ++ xmsubm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_insn "vsx_fmsub4_2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0") ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")] ++ UNSPEC_VSX_XVMSUB))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "@ ++ xmsuba %x0,%x1,%x2 ++ xmsubm %x0,%x1,%x3 ++ xmsuba %x0,%x1,%x2 ++ xmsubm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_expand "vsx_fnmadd4" ++ [(match_operand:VSX_B 0 "vsx_register_operand" "") ++ (match_operand:VSX_B 1 "vsx_register_operand" "") ++ (match_operand:VSX_B 2 "vsx_register_operand" "") ++ (match_operand:VSX_B 3 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (mode)" ++{ ++ if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) ++ { ++ emit_insn (gen_vsx_fnmadd4_1 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++ else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) ++ { ++ emit_insn (gen_vsx_fnmadd4_2 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++ else ++ { ++ emit_insn (gen_vsx_fnmadd4_3 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++}) ++ ++(define_insn "vsx_fnmadd4_1" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (neg:VSX_B ++ (plus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "@ -+ xvnmadda %x0,%x1,%x2 -+ xvnmaddm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3 ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fnmadd4_2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (minus:VSX_F -+ (mult:VSX_F -+ (neg:VSX_F -+ (match_operand:VSX_F 1 "gpc_reg_operand" "%,")) -+ (match_operand:VSX_F 2 "gpc_reg_operand" ",0")) -+ (match_operand:VSX_F 3 "vsx_register_operand" "0,")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD ++(define_insn "vsx_fnmadd4_2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (minus:VSX_B ++ (mult:VSX_B ++ (neg:VSX_B ++ (match_operand:VSX_B 1 "gpc_reg_operand" ",,wa,wa")) ++ (match_operand:VSX_B 2 "gpc_reg_operand" ",0,wa,0")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD + && !HONOR_SIGNED_ZEROS (DFmode)" + "@ -+ xvnmadda %x0,%x1,%x2 -+ xvnmaddm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3 ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fnmsub4_1" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (neg:VSX_F -+ (minus:VSX_F -+ (mult:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" "%,") -+ (match_operand:VSX_F 2 "vsx_register_operand" ",0")) -+ (match_operand:VSX_F 3 "vsx_register_operand" "0,"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD ++(define_insn "vsx_fnmadd4_3" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0") ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")] ++ UNSPEC_VSX_XVNMADD))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "@ ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3 ++ xnmadda %x0,%x1,%x2 ++ xnmaddm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++(define_expand "vsx_fnmsub4" ++ [(match_operand:VSX_B 0 "vsx_register_operand" "") ++ (match_operand:VSX_B 1 "vsx_register_operand" "") ++ (match_operand:VSX_B 2 "vsx_register_operand" "") ++ (match_operand:VSX_B 3 "vsx_register_operand" "")] ++ "VECTOR_UNIT_VSX_P (mode)" ++{ ++ if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) ++ { ++ emit_insn (gen_vsx_fnmsub4_1 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++ else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) ++ { ++ emit_insn (gen_vsx_fnmsub4_2 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++ else ++ { ++ emit_insn (gen_vsx_fnmsub4_3 (operands[0], operands[1], ++ operands[2], operands[3])); ++ DONE; ++ } ++}) ++ ++(define_insn "vsx_fnmsub4_1" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (neg:VSX_B ++ (minus:VSX_B ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")) ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "@ -+ xvnmsuba %x0,%x1,%x2 -+ xvnmsubm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3 ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fnmsub4_2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,") -+ (minus:VSX_F -+ (match_operand:VSX_F 3 "vsx_register_operand" "0,") -+ (mult:VSX_F -+ (match_operand:VSX_F 1 "vsx_register_operand" "%,") -+ (match_operand:VSX_F 2 "vsx_register_operand" ",0"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD ++(define_insn "vsx_fnmsub4_2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (minus:VSX_B ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa") ++ (mult:VSX_B ++ (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))))] ++ "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD + && !HONOR_SIGNED_ZEROS (DFmode)" + "@ -+ xvnmsuba %x0,%x1,%x2 -+ xvnmsubm %x0,%x1,%x3" -+ [(set_attr "type" "vecfloat")]) ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3 ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+;; Vector conditional expressions -+(define_insn "*vsx_eq" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++(define_insn "vsx_fnmsub4_3" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa") ++ (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0") ++ (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")] ++ UNSPEC_VSX_XVNMSUB))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "@ ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3 ++ xnmsuba %x0,%x1,%x2 ++ xnmsubm %x0,%x1,%x3" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) ++ ++;; Vector conditional expressions (no scalar version for these instructions) ++(define_insn "vsx_eq" ++ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa") ++ (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" + "xvcmpeq %x0,%x1,%x2" -+ [(set_attr "type" "veccmp")]) ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_gt" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++(define_insn "vsx_gt" ++ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa") ++ (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" + "xvcmpgt %x0,%x1,%x2" -+ [(set_attr "type" "veccmp")]) ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "*vsx_ge" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "") -+ (match_operand:VSX_F 2 "vsx_register_operand" "")))] ++ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa") ++ (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa") ++ (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" + "xvcmpge %x0,%x1,%x2" -+ [(set_attr "type" "veccmp")]) ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +(define_insn "vsx_vsel" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (if_then_else:VSX_F (ne (match_operand:VSX_F 1 "vsx_register_operand" "") ++ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa") ++ (if_then_else:VSX_F (ne (match_operand:VSX_F 1 "vsx_register_operand" ",wa") + (const_int 0)) -+ (match_operand:VSX_F 2 "vsx_register_operand" "") -+ (match_operand:VSX_F 3 "vsx_register_operand" "")))] ++ (match_operand:VSX_F 2 "vsx_register_operand" ",wa") ++ (match_operand:VSX_F 3 "vsx_register_operand" ",wa")))] + "VECTOR_UNIT_VSX_P (mode)" + "xxsel %x0,%x3,%x2,%x1" + [(set_attr "type" "vecperm")]) + +;; Copy sign -+(define_insn "*vsx_copysign3" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (if_then_else:VSX_F -+ (ge:VSX_F (match_operand:VSX_F 2 "vsx_register_operand" "") ++(define_insn "vsx_copysign3" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (if_then_else:VSX_B ++ (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" ",wa") + (const_int 0)) -+ (abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "")) -+ (neg:VSX_F (abs:VSX_F (match_dup 1)))))] ++ (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")) ++ (neg:VSX_B (abs:VSX_B (match_dup 1)))))] + "VECTOR_UNIT_VSX_P (mode)" -+ "xvcpsgn %x0,%x2,%x1" -+ [(set_attr "type" "vecsimple")]) -+ -+(define_insn "*vsx_ftrunc2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (fix:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "")))] -+ "VECTOR_UNIT_VSX_P (mode)" -+ "xvrpiz %x0,%x1" -+ [(set_attr "type" "vecperm")]) -+ -+(define_insn "*vsx_float2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (float:VSX_F (match_operand: 1 "vsx_register_operand" "")))] -+ "VECTOR_UNIT_VSX_P (mode)" -+ "xvcvsx %x0,%x1" -+ [(set_attr "type" "vecfloat")]) -+ -+(define_insn "*vsx_floatuns2" -+ [(set (match_operand:VSX_F 0 "vsx_register_operand" "=") -+ (unsigned_float:VSX_F (match_operand: 1 "vsx_register_operand" "")))] -+ "VECTOR_UNIT_VSX_P (mode)" -+ "xvcvux %x0,%x1" -+ [(set_attr "type" "vecfloat")]) -+ -+(define_insn "*vsx_fix_trunc2" -+ [(set (match_operand: 0 "vsx_register_operand" "=") -+ (fix: (match_operand:VSX_F 1 "vsx_register_operand" "")))] -+ "VECTOR_UNIT_VSX_P (mode)" -+ "xvcvsxs %x0,%x1" -+ [(set_attr "type" "vecfloat")]) -+ -+(define_insn "*vsx_fixuns_trunc2" -+ [(set (match_operand: 0 "vsx_register_operand" "=") -+ (unsigned_fix: (match_operand:VSX_F 1 "vsx_register_operand" "")))] -+ "VECTOR_UNIT_VSX_P (mode)" -+ "xvcvuxs %x0,%x1" -+ [(set_attr "type" "vecfloat")]) -+ -+ -+;; VSX scalar double precision floating point operations -+(define_insn"*vsx_adddf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (plus:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsadddp %x0,%x1,%x2" -+ [(set_attr "type" "fp") -+ (set_attr "fp_type" "fp_addsub_d")]) -+ -+(define_insn"*vsx_subdf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (minus:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xssubdp %x0,%x1,%x2" -+ [(set_attr "type" "fp") -+ (set_attr "fp_type" "fp_addsub_d")]) -+ -+(define_insn"*vsx_muldf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (mult:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsmuldp %x0,%x1,%x2" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_mul_d")]) -+ -+(define_insn"*vsx_divdf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (div:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsdivdp %x0,%x1,%x2" -+ [(set_attr "type" "ddiv")]) -+ -+(define_insn "*vsx_fredf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "ws")] -+ UNSPEC_FRES))] -+ "flag_finite_math_only && VECTOR_UNIT_VSX_P (DFmode)" -+ "xsredp %x0,%x1" -+ [(set_attr "type" "fp")]) -+ -+(define_insn "*vsx_sqrtdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (sqrt:DF (match_operand:DF 1 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xssqrtdp %x0,%x1" -+ [(set_attr "type" "dsqrt")]) -+ -+(define_insn"*vsx_negdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (neg:DF (match_operand:DF 1 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsnegdp %x0,%x1" -+ [(set_attr "type" "fp")]) -+ -+(define_insn"vsx_absdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (abs:DF (match_operand:DF 1 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsabsdp %x0,%x1" -+ [(set_attr "type" "fp")]) -+ -+(define_insn"*vsx_nabsdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (neg:DF (abs:DF (match_operand:DF 1 "vsx_register_operand" "ws"))))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsnabsdp %x0,%x1" -+ [(set_attr "type" "fp")]) -+ -+(define_insn "*vsx_smaxdf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (smax:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsmaxdp %x0,%x1,%x2" -+ [(set_attr "type" "fp")]) -+ -+ -+(define_insn "*vsx_smindf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (smin:DF (match_operand:DF 1 "vsx_register_operand" "ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsmindp %x0,%x1,%x2" -+ [(set_attr "type" "fp")]) -+ -+;; Fused vector multiply/add instructions -+(define_insn "*vsx_fmadddf4" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (plus:DF (mult:DF (match_operand:DF 1 "vsx_register_operand" "%ws,ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws,0")) -+ (match_operand:DF 3 "gpc_reg_operand" "0,ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD" -+ "@ -+ xsmaddadp %x0,%x1,%x2 -+ xsmaddmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) -+ -+(define_insn "*vsx_fmsubdf4" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (minus:DF (mult:DF (match_operand:DF 1 "vsx_register_operand" "%ws,ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws,0")) -+ (match_operand:DF 3 "vsx_register_operand" "0,ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD" -+ "@ -+ xsmsubadp %x0,%x1,%x2 -+ xsmsubmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) -+ -+(define_insn "*vsx_fnmadddf4_1" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (neg:DF -+ (plus:DF (mult:DF (match_operand:DF 1 "vsx_register_operand" "%ws,ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws,0")) -+ (match_operand:DF 3 "vsx_register_operand" "0,ws"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD -+ && HONOR_SIGNED_ZEROS (DFmode)" -+ "@ -+ xsnmaddadp %x0,%x1,%x2 -+ xsnmaddmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) -+ -+(define_insn "*vsx_fnmadddf4_2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (minus:DF (mult:DF (neg:DF -+ (match_operand:DF 1 "gpc_reg_operand" "%ws,ws")) -+ (match_operand:DF 2 "gpc_reg_operand" "ws,0")) -+ (match_operand:DF 3 "vsx_register_operand" "0,ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD -+ && !HONOR_SIGNED_ZEROS (DFmode)" -+ "@ -+ xsnmaddadp %x0,%x1,%x2 -+ xsnmaddmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) -+ -+(define_insn "*vsx_fnmsubdf4_1" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (neg:DF -+ (minus:DF -+ (mult:DF (match_operand:DF 1 "vsx_register_operand" "%ws,ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws,0")) -+ (match_operand:DF 3 "vsx_register_operand" "0,ws"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD -+ && HONOR_SIGNED_ZEROS (DFmode)" -+ "@ -+ xsnmsubadp %x0,%x1,%x2 -+ xsnmsubmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) -+ -+(define_insn "*vsx_fnmsubdf4_2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws") -+ (minus:DF -+ (match_operand:DF 3 "vsx_register_operand" "0,ws") -+ (mult:DF (match_operand:DF 1 "vsx_register_operand" "%ws,ws") -+ (match_operand:DF 2 "vsx_register_operand" "ws,0"))))] -+ "VECTOR_UNIT_VSX_P (DFmode) && TARGET_FUSED_MADD -+ && !HONOR_SIGNED_ZEROS (DFmode)" -+ "@ -+ xsnmsubadp %x0,%x1,%x2 -+ xsnmsubmdp %x0,%x1,%x3" -+ [(set_attr "type" "dmul") -+ (set_attr "fp_type" "fp_maddsub_d")]) ++ "xcpsgn %x0,%x2,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + +;; For the conversions, limit the register class for the integer value to be -+;; the fprs. For the unsigned tests, there isn't a generic double -> unsigned -+;; conversion in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against -+;; VSX. ++;; the fprs because we don't want to add the altivec registers to movdi/movsi. ++;; For the unsigned tests, there isn't a generic double -> unsigned conversion ++;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. ++(define_insn "vsx_ftrunc2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xrpiz %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_floatdidf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (float:DF (match_operand:DI 1 "vsx_register_operand" "!f#r")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xscvsxddp %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_float2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xcvsx %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_floatunsdidf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (unsigned_float:DF (match_operand:DI 1 "vsx_register_operand" "!f#r")))] -+ "TARGET_HARD_FLOAT && TARGET_VSX" -+ "xscvuxddp %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_floatuns2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unsigned_float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xcvux %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fix_truncdfdi2" -+ [(set (match_operand:DI 0 "vsx_register_operand" "=!f#r") -+ (fix:DI (match_operand:DF 1 "vsx_register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xscvdpsxds %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_fix_trunc2" ++ [(set (match_operand: 0 "vsx_register_operand" "=,?") ++ (fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xcvsxs %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_fixuns_truncdfdi2" -+ [(set (match_operand:DI 0 "vsx_register_operand" "=!f#r") -+ (unsigned_fix:DI (match_operand:DF 1 "vsx_register_operand" "ws")))] -+ "TARGET_HARD_FLOAT && TARGET_VSX" -+ "xscvdpuxds %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_fixuns_trunc2" ++ [(set (match_operand: 0 "vsx_register_operand" "=,?") ++ (unsigned_fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xcvuxs %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_btruncdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "ws")] -+ UNSPEC_FRIZ))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsrdpiz %x0,%x1" -+ [(set_attr "type" "fp")]) ++;; Math rounding functions ++(define_insn "vsx_btrunc2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] ++ UNSPEC_FRIZ))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xriz %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_floordf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "ws")] -+ UNSPEC_FRIM))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsrdpim %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_floor2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] ++ UNSPEC_FRIM))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xrim %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "*vsx_ceildf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "ws")] -+ UNSPEC_FRIP))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsrdpip %x0,%x1" -+ [(set_attr "type" "fp")]) ++(define_insn "vsx_ceil2" ++ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa") ++ (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")] ++ UNSPEC_FRIP))] ++ "VECTOR_UNIT_VSX_P (mode)" ++ "xrip %x0,%x1" ++ [(set_attr "type" "") ++ (set_attr "fp_type" "")]) + -+(define_insn "vsx_copysigndf3" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (if_then_else:DF (ge:DF (match_operand:DF 2 "vsx_register_operand" "ws") -+ (const_int 0)) -+ (abs:DF (match_operand:DF 1 "vsx_register_operand" "ws")) -+ (neg:DF (abs:DF (match_dup 1)))))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xscpsgndp %x0,%x2,%x1" -+ [(set_attr "type" "fp")]) ++ ++;; VSX convert to/from double vector + -+(define_insn "*vsx_ftruncdf2" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (fix:DF (match_operand:DF 1 "register_operand" "ws")))] -+ "VECTOR_UNIT_VSX_P (DFmode)" -+ "xsrdppiz %x0,%x1" ++;; 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))] ++ "VECTOR_UNIT_VSX_P (V2DFmode)" ++ "xvcvdpsxws %x0,%x1" ++ [(set_attr "type" "vecfloat")]) ++ ++(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))] ++ "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))] ++ "VECTOR_UNIT_VSX_P (V2DFmode)" ++ "xvcvspdp %x0,%x1" ++ [(set_attr "type" "vecfloat")]) ++ ++(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))] ++ "VECTOR_UNIT_VSX_P (V2DFmode)" ++ "xvcvsxwdp %x0,%x1" ++ [(set_attr "type" "vecfloat")]) ++ ++(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))] ++ "VECTOR_UNIT_VSX_P (V2DFmode)" ++ "xvcvuxwdp %x0,%x1" + [(set_attr "type" "vecfloat")]) + + @@ -6450,8 +8323,8 @@ testsuite/ +(define_insn "vsx_concat_v2df" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") + (unspec:V2DF -+ [(match_operand:DF 1 "vsx_register_operand" "f,wa") -+ (match_operand:DF 2 "vsx_register_operand" "f,wa")] ++ [(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)" + "xxpermdi %x0,%x1,%x2,0" @@ -6459,32 +8332,37 @@ testsuite/ + +;; Set a double into one element +(define_insn "vsx_set_v2df" -+ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd") ++ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") + (vec_merge:V2DF -+ (match_operand:V2DF 1 "vsx_register_operand" "wd") -+ (vec_duplicate:V2DF (match_operand:DF 2 "vsx_register_operand" "ws")) -+ (match_operand:QI 3 "u5bit_cint_operand" "i")))] ++ (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)" +{ -+ operands[3] = GEN_INT (INTVAL (operands[3]) & 1); -+ return \"xxpermdi %x0,%x1,%x2,%3\"; ++ if (INTVAL (operands[3]) == 0) ++ return \"xxpermdi %x0,%x1,%x2,1\"; ++ else if (INTVAL (operands[3]) == 1) ++ return \"xxpermdi %x0,%x2,%x1,0\"; ++ else ++ gcc_unreachable (); +} + [(set_attr "type" "vecperm")]) + +;; Extract a DF element from V2DF +(define_insn "vsx_extract_v2df" -+ [(set (match_operand:DF 0 "vsx_register_operand" "=ws") -+ (vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd") ++ [(set (match_operand:DF 0 "vsx_register_operand" "=ws,f,?wa") ++ (vec_select:DF (match_operand:V2DF 1 "vsx_register_operand" "wd,wd,wa") + (parallel -+ [(match_operand:QI 2 "u5bit_cint_operand" "i")])))] ++ [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ -+ operands[3] = GEN_INT (INTVAL (operands[2]) & 1); ++ gcc_assert (UINTVAL (operands[2]) <= 1); ++ operands[3] = GEN_INT (INTVAL (operands[2]) << 1); + return \"xxpermdi %x0,%x1,%x1,%3\"; +} + [(set_attr "type" "vecperm")]) + -+;; General V2DF permute ++;; General V2DF permute, extract_{high,low,even,odd} +(define_insn "vsx_xxpermdi" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd") + (vec_concat:V2DF @@ -6496,6 +8374,7 @@ testsuite/ + [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ ++ gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1)); + operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1) + | (INTVAL (operands[4]) & 1)); + return \"xxpermdi %x0,%x1,%x3,%5\"; @@ -6504,63 +8383,70 @@ testsuite/ + +;; V2DF splat +(define_insn "vsx_splatv2df" -+ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd") ++ [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa") + (vec_duplicate:V2DF -+ (match_operand:DF 1 "input_operand" "ws,Z")))] ++ (match_operand:DF 1 "input_operand" "ws,f,Z,wa,wa,Z")))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "@ + xxpermdi %x0,%x1,%x1,0 ++ xxpermdi %x0,%x1,%x1,0 ++ lxvdsx %x0,%y1 ++ xxpermdi %x0,%x1,%x1,0 ++ xxpermdi %x0,%x1,%x1,0 + lxvdsx %x0,%y1" -+ [(set_attr "type" "vecperm,vecload")]) ++ [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")]) + +;; V4SF splat +(define_insn "*vsx_xxspltw" -+ [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf") ++ [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa") + (vec_duplicate:V4SF -+ (vec_select:SF (match_operand:V4SF 1 "vsx_register_operand" "wf") ++ (vec_select:SF (match_operand:V4SF 1 "vsx_register_operand" "wf,wa") + (parallel -+ [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] ++ [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))] + "VECTOR_UNIT_VSX_P (V4SFmode)" + "xxspltw %x0,%x1,%2" + [(set_attr "type" "vecperm")]) + +;; V4SF interleave -+(define_insn "*vsx_xxmrghw" -+ [(set (match_operand:V4SF 0 "register_operand" "=v") -+ (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v") -+ (parallel [(const_int 0) -+ (const_int 2) -+ (const_int 1) -+ (const_int 3)])) -+ (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v") -+ (parallel [(const_int 2) -+ (const_int 0) -+ (const_int 3) -+ (const_int 1)])) -+ (const_int 5)))] -+ "VECTOR_UNIT_VSX_P (V4SFmode)" -+ "xxmrghw %x0,%x1,%x2" -+ [(set_attr "type" "vecperm")]) -+ -+(define_insn "*vsx_xxmrglw" -+ [(set (match_operand:V4SF 0 "register_operand" "=v") ++(define_insn "vsx_xxmrghw" ++ [(set (match_operand:V4SF 0 "register_operand" "=wf,?wa") + (vec_merge:V4SF -+ (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v") -+ (parallel [(const_int 2) -+ (const_int 0) -+ (const_int 3) -+ (const_int 1)])) -+ (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v") ++ (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)])) ++ (const_int 5)))] ++ "VECTOR_UNIT_VSX_P (V4SFmode)" ++ "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") ++ (parallel [(const_int 2) ++ (const_int 0) ++ (const_int 3) ++ (const_int 1)])) ++ (vec_select:V4SF ++ (match_operand:V4SF 2 "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)" + "xxmrglw %x0,%x1,%x2" + [(set_attr "type" "vecperm")]) ---- gcc/config/rs6000/rs6000.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/rs6000.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for IBM RS/6000. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, @@ -6616,22 +8502,25 @@ testsuite/ #endif #ifndef CC1_CPU_SPEC -@@ -240,6 +248,14 @@ extern const char *host_detect_local_cpu - #define TARGET_DFP 0 +@@ -233,11 +241,12 @@ extern const char *host_detect_local_cpu + #define TARGET_MFPGPR 0 #endif +-/* Define TARGET_DFP if the target assembler does not support decimal +- floating point instructions. */ +-#ifndef HAVE_AS_DFP +-#undef TARGET_DFP +-#define TARGET_DFP 0 +/* Define TARGET_POPCNTD if the target assembler does not support the + popcount word and double word instructions. */ + +#ifndef HAVE_AS_POPCNTD +#undef TARGET_POPCNTD +#define TARGET_POPCNTD 0 -+#endif -+ - #ifndef TARGET_SECURE_PLT - #define TARGET_SECURE_PLT 0 #endif -@@ -295,6 +311,7 @@ enum processor_type + + #ifndef TARGET_SECURE_PLT +@@ -295,6 +304,7 @@ enum processor_type PROCESSOR_POWER4, PROCESSOR_POWER5, PROCESSOR_POWER6, @@ -6639,21 +8528,23 @@ testsuite/ PROCESSOR_CELL }; -@@ -388,9 +405,13 @@ extern struct rs6000_cpu_select rs6000_s +@@ -388,9 +398,15 @@ extern struct rs6000_cpu_select rs6000_s extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */ extern int rs6000_debug_stack; /* debug stack applications */ extern int rs6000_debug_arg; /* debug argument handling */ +extern int rs6000_debug_reg; /* debug register handling */ +extern int rs6000_debug_addr; /* debug memory addressing */ ++extern int rs6000_debug_cost; /* debug rtx_costs */ #define TARGET_DEBUG_STACK rs6000_debug_stack #define TARGET_DEBUG_ARG rs6000_debug_arg +#define TARGET_DEBUG_REG rs6000_debug_reg +#define TARGET_DEBUG_ADDR rs6000_debug_addr ++#define TARGET_DEBUG_COST rs6000_debug_cost extern const char *rs6000_traceback_name; /* Type of traceback table. */ -@@ -401,13 +422,65 @@ extern int rs6000_ieeequad; +@@ -401,13 +417,65 @@ extern int rs6000_ieeequad; extern int rs6000_altivec_abi; extern int rs6000_spe_abi; extern int rs6000_spe; @@ -6720,7 +8611,7 @@ testsuite/ /* Alignment options for fields in structures for sub-targets following AIX-like ABI. ALIGN_POWER word-aligns FP doubles (default AIX ABI). -@@ -432,7 +505,7 @@ extern int rs6000_xilinx_fpu; +@@ -432,7 +500,7 @@ extern int rs6000_xilinx_fpu; #define TARGET_SPE_ABI 0 #define TARGET_SPE 0 #define TARGET_E500 0 @@ -6729,7 +8620,7 @@ testsuite/ #define TARGET_FPRS 1 #define TARGET_E500_SINGLE 0 #define TARGET_E500_DOUBLE 0 -@@ -530,6 +603,7 @@ extern int rs6000_xilinx_fpu; +@@ -530,6 +598,7 @@ extern int rs6000_xilinx_fpu; #endif #define UNITS_PER_FP_WORD 8 #define UNITS_PER_ALTIVEC_WORD 16 @@ -6737,7 +8628,7 @@ testsuite/ #define UNITS_PER_SPE_WORD 8 #define UNITS_PER_PAIRED_WORD 8 -@@ -600,8 +674,9 @@ extern int rs6000_xilinx_fpu; +@@ -600,8 +669,9 @@ extern int rs6000_xilinx_fpu; #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64) /* Boundary (in *bits*) on which stack pointer should be aligned. */ @@ -6749,7 +8640,7 @@ testsuite/ /* Allocation boundary (in *bits*) for the code of a function. */ #define FUNCTION_BOUNDARY 32 -@@ -613,10 +688,11 @@ extern int rs6000_xilinx_fpu; +@@ -613,10 +683,11 @@ extern int rs6000_xilinx_fpu; local store. TYPE is the data type, and ALIGN is the alignment that the object would ordinarily have. */ #define LOCAL_ALIGNMENT(TYPE, ALIGN) \ @@ -6764,7 +8655,7 @@ testsuite/ && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \ && TREE_CODE (TYPE) == VECTOR_TYPE \ && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) ? 64 : ALIGN) -@@ -674,15 +750,17 @@ extern int rs6000_xilinx_fpu; +@@ -674,15 +745,17 @@ extern int rs6000_xilinx_fpu; /* Define this macro to be the value 1 if unaligned accesses have a cost many times greater than aligned accesses, for example if they are emulated in a trap handler. */ @@ -6785,7 +8676,7 @@ testsuite/ /* Standard register usage. */ -@@ -909,16 +987,60 @@ extern int rs6000_xilinx_fpu; +@@ -909,16 +982,60 @@ extern int rs6000_xilinx_fpu; /* True if register is an AltiVec register. */ #define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO) @@ -6847,7 +8738,7 @@ testsuite/ #define ALTIVEC_VECTOR_MODE(MODE) \ ((MODE) == V16QImode \ || (MODE) == V8HImode \ -@@ -934,10 +1056,12 @@ extern int rs6000_xilinx_fpu; +@@ -934,10 +1051,12 @@ extern int rs6000_xilinx_fpu; #define PAIRED_VECTOR_MODE(MODE) \ ((MODE) == V2SFmode) @@ -6864,7 +8755,7 @@ testsuite/ /* Value is TRUE if hard register REGNO can hold a value of machine-mode MODE. */ -@@ -965,6 +1089,10 @@ extern int rs6000_xilinx_fpu; +@@ -965,6 +1084,10 @@ extern int rs6000_xilinx_fpu; ? ALTIVEC_VECTOR_MODE (MODE2) \ : ALTIVEC_VECTOR_MODE (MODE2) \ ? ALTIVEC_VECTOR_MODE (MODE1) \ @@ -6875,7 +8766,7 @@ testsuite/ : 1) /* Post-reload, we can't use any new AltiVec registers, as we already -@@ -1056,9 +1184,10 @@ extern int rs6000_xilinx_fpu; +@@ -1056,9 +1179,10 @@ extern int rs6000_xilinx_fpu; For any two classes, it is very desirable that there be another class that represents their union. */ @@ -6889,7 +8780,7 @@ testsuite/ However, r0 is special in that it cannot be used as a base register. So make a class for registers valid as base registers. -@@ -1073,6 +1202,7 @@ enum reg_class +@@ -1073,6 +1197,7 @@ enum reg_class GENERAL_REGS, FLOAT_REGS, ALTIVEC_REGS, @@ -6897,7 +8788,7 @@ testsuite/ VRSAVE_REGS, VSCR_REGS, SPE_ACC_REGS, -@@ -1103,6 +1233,7 @@ enum reg_class +@@ -1103,6 +1228,7 @@ enum reg_class "GENERAL_REGS", \ "FLOAT_REGS", \ "ALTIVEC_REGS", \ @@ -6905,7 +8796,7 @@ testsuite/ "VRSAVE_REGS", \ "VSCR_REGS", \ "SPE_ACC_REGS", \ -@@ -1132,6 +1263,7 @@ enum reg_class +@@ -1132,6 +1258,7 @@ enum reg_class { 0xffffffff, 0x00000000, 0x00000008, 0x00020000 }, /* GENERAL_REGS */ \ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \ { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */ \ @@ -6913,25 +8804,43 @@ testsuite/ { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \ -@@ -1179,8 +1311,8 @@ enum reg_class - : (REGNO) == CR0_REGNO ? CR0_REGS \ - : CR_REGNO_P (REGNO) ? CR_REGS \ - : (REGNO) == MQ_REGNO ? MQ_REGS \ +@@ -1171,29 +1298,29 @@ enum reg_class + reg number REGNO. This could be a conditional expression + or could index an array. */ + +-#define REGNO_REG_CLASS(REGNO) \ +- ((REGNO) == 0 ? GENERAL_REGS \ +- : (REGNO) < 32 ? BASE_REGS \ +- : FP_REGNO_P (REGNO) ? FLOAT_REGS \ +- : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \ +- : (REGNO) == CR0_REGNO ? CR0_REGS \ +- : CR_REGNO_P (REGNO) ? CR_REGS \ +- : (REGNO) == MQ_REGNO ? MQ_REGS \ - : (REGNO) == LR_REGNO ? LINK_REGS \ - : (REGNO) == CTR_REGNO ? CTR_REGS \ -+ : (REGNO) == LR_REGNO ? LINK_REGS \ -+ : (REGNO) == CTR_REGNO ? CTR_REGS \ - : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \ - : (REGNO) == XER_REGNO ? XER_REGS \ - : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \ -@@ -1190,10 +1322,18 @@ enum reg_class - : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS \ - : NO_REGS) - +- : (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \ +- : (REGNO) == XER_REGNO ? XER_REGS \ +- : (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \ +- : (REGNO) == VSCR_REGNO ? VRSAVE_REGS \ +- : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS \ +- : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS \ +- : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS \ +- : NO_REGS) ++extern enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; ++ ++#if ENABLE_CHECKING ++#define REGNO_REG_CLASS(REGNO) \ ++ (gcc_assert (IN_RANGE ((REGNO), 0, FIRST_PSEUDO_REGISTER-1)), \ ++ rs6000_regno_regclass[(REGNO)]) ++ ++#else ++#define REGNO_REG_CLASS(REGNO) rs6000_regno_regclass[(REGNO)] ++#endif ++ +/* VSX register classes. */ +extern enum reg_class rs6000_vector_reg_class[]; +extern enum reg_class rs6000_vsx_reg_class; -+ + /* The class value for index registers, and the one for base regs. */ #define INDEX_REG_CLASS GENERAL_REGS #define BASE_REG_CLASS BASE_REGS @@ -6943,7 +8852,7 @@ testsuite/ /* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. In general this is just CLASS; but on some machines -@@ -1213,13 +1353,7 @@ enum reg_class +@@ -1213,13 +1340,7 @@ enum reg_class */ #define PREFERRED_RELOAD_CLASS(X,CLASS) \ @@ -6958,7 +8867,7 @@ testsuite/ /* Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE. If it can be done directly, -@@ -1234,18 +1368,7 @@ enum reg_class +@@ -1234,18 +1355,7 @@ enum reg_class are available.*/ #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ @@ -6978,7 +8887,7 @@ testsuite/ /* For cpus that cannot load/store SDmode values from the 64-bit FP registers without using a full 64-bit load/store, we need -@@ -1257,32 +1380,15 @@ enum reg_class +@@ -1257,32 +1367,15 @@ enum reg_class /* Return the maximum number of consecutive registers needed to represent mode MODE in a register of class CLASS. @@ -7016,7 +8925,7 @@ testsuite/ /* Stack layout; function entry, exit and calling. */ -@@ -1343,8 +1449,8 @@ extern enum rs6000_abi rs6000_current_ab +@@ -1343,8 +1436,8 @@ extern enum rs6000_abi rs6000_current_ab #define STARTING_FRAME_OFFSET \ (FRAME_GROWS_DOWNWARD \ ? 0 \ @@ -7027,7 +8936,7 @@ testsuite/ + RS6000_SAVE_AREA)) /* Offset from the stack pointer register to an item dynamically -@@ -1354,8 +1460,8 @@ extern enum rs6000_abi rs6000_current_ab +@@ -1354,8 +1447,8 @@ extern enum rs6000_abi rs6000_current_ab length of the outgoing arguments. The default is correct for most machines. See `function.c' for details. */ #define STACK_DYNAMIC_OFFSET(FUNDECL) \ @@ -7038,7 +8947,7 @@ testsuite/ + (STACK_POINTER_OFFSET)) /* If we generate an insn to push BYTES bytes, -@@ -1605,7 +1711,7 @@ typedef struct rs6000_args +@@ -1605,7 +1698,7 @@ typedef struct rs6000_args #define EPILOGUE_USES(REGNO) \ ((reload_completed && (REGNO) == LR_REGNO) \ || (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \ @@ -7047,7 +8956,7 @@ testsuite/ && TARGET_AIX \ && (REGNO) == 2)) -@@ -2316,7 +2422,24 @@ extern char rs6000_reg_names[][8]; /* re +@@ -2316,7 +2409,24 @@ extern char rs6000_reg_names[][8]; /* re /* no additional names for: mq, lr, ctr, ap */ \ {"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \ {"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \ @@ -7073,7 +8982,7 @@ testsuite/ /* Text to write out after a CALL that may be replaced by glue code by the loader. This depends on the AIX version. */ -@@ -2480,10 +2603,14 @@ enum rs6000_builtins +@@ -2480,10 +2590,14 @@ enum rs6000_builtins ALTIVEC_BUILTIN_VSEL_4SF, ALTIVEC_BUILTIN_VSEL_8HI, ALTIVEC_BUILTIN_VSEL_16QI, @@ -7088,7 +8997,15 @@ testsuite/ ALTIVEC_BUILTIN_VPKUHUM, ALTIVEC_BUILTIN_VPKUWUM, ALTIVEC_BUILTIN_VPKPX, -@@ -3110,6 +3237,163 @@ enum rs6000_builtins +@@ -2839,6 +2953,7 @@ enum rs6000_builtins + ALTIVEC_BUILTIN_VEC_PROMOTE, + ALTIVEC_BUILTIN_VEC_INSERT, + ALTIVEC_BUILTIN_VEC_SPLATS, ++ + ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_SPLATS, + + /* SPE builtins. */ +@@ -3110,6 +3225,163 @@ enum rs6000_builtins RS6000_BUILTIN_RECIPF, RS6000_BUILTIN_RSQRTF, @@ -7177,34 +9094,24 @@ testsuite/ + VSX_BUILTIN_XVCVUXWSP, + VSX_BUILTIN_XVDIVDP, + VSX_BUILTIN_XVDIVSP, -+ VSX_BUILTIN_XVMADDADP, -+ VSX_BUILTIN_XVMADDASP, -+ VSX_BUILTIN_XVMADDMDP, -+ VSX_BUILTIN_XVMADDMSP, ++ VSX_BUILTIN_XVMADDDP, ++ VSX_BUILTIN_XVMADDSP, + VSX_BUILTIN_XVMAXDP, + VSX_BUILTIN_XVMAXSP, + VSX_BUILTIN_XVMINDP, + VSX_BUILTIN_XVMINSP, -+ VSX_BUILTIN_XVMOVDP, -+ VSX_BUILTIN_XVMOVSP, -+ VSX_BUILTIN_XVMSUBADP, -+ VSX_BUILTIN_XVMSUBASP, -+ VSX_BUILTIN_XVMSUBMDP, -+ VSX_BUILTIN_XVMSUBMSP, ++ VSX_BUILTIN_XVMSUBDP, ++ VSX_BUILTIN_XVMSUBSP, + VSX_BUILTIN_XVMULDP, + VSX_BUILTIN_XVMULSP, + VSX_BUILTIN_XVNABSDP, + VSX_BUILTIN_XVNABSSP, + VSX_BUILTIN_XVNEGDP, + VSX_BUILTIN_XVNEGSP, -+ VSX_BUILTIN_XVNMADDADP, -+ VSX_BUILTIN_XVNMADDASP, -+ VSX_BUILTIN_XVNMADDMDP, -+ VSX_BUILTIN_XVNMADDMSP, -+ VSX_BUILTIN_XVNMSUBADP, -+ VSX_BUILTIN_XVNMSUBASP, -+ VSX_BUILTIN_XVNMSUBMDP, -+ VSX_BUILTIN_XVNMSUBMSP, ++ VSX_BUILTIN_XVNMADDDP, ++ VSX_BUILTIN_XVNMADDSP, ++ VSX_BUILTIN_XVNMSUBDP, ++ VSX_BUILTIN_XVNMSUBSP, + VSX_BUILTIN_XVRDPI, + VSX_BUILTIN_XVRDPIC, + VSX_BUILTIN_XVRDPIM, @@ -7243,7 +9150,17 @@ testsuite/ + VSX_BUILTIN_XXSPLTW, + VSX_BUILTIN_XXSWAPD, + -+ /* Combine VSX/Altivec builtins. */ ++ /* VSX overloaded builtins, add the overloaded functions not present in ++ Altivec. */ ++ VSX_BUILTIN_VEC_MUL, ++ VSX_BUILTIN_OVERLOADED_FIRST = VSX_BUILTIN_VEC_MUL, ++ VSX_BUILTIN_VEC_MSUB, ++ VSX_BUILTIN_VEC_NMADD, ++ VSX_BUITLIN_VEC_NMSUB, ++ VSX_BUILTIN_VEC_DIV, ++ VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_DIV, ++ ++ /* Combined VSX/Altivec builtins. */ + VECTOR_BUILTIN_FLOAT_V4SI_V4SF, + VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF, + VECTOR_BUILTIN_FIX_V4SF_V4SI, @@ -7252,7 +9169,7 @@ testsuite/ RS6000_BUILTIN_COUNT }; -@@ -3123,6 +3407,8 @@ enum rs6000_builtin_type_index +@@ -3123,6 +3395,8 @@ enum rs6000_builtin_type_index RS6000_BTI_V16QI, RS6000_BTI_V2SI, RS6000_BTI_V2SF, @@ -7261,7 +9178,7 @@ testsuite/ RS6000_BTI_V4HI, RS6000_BTI_V4SI, RS6000_BTI_V4SF, -@@ -3146,7 +3432,10 @@ enum rs6000_builtin_type_index +@@ -3146,7 +3420,10 @@ enum rs6000_builtin_type_index RS6000_BTI_UINTHI, /* unsigned_intHI_type_node */ RS6000_BTI_INTSI, /* intSI_type_node */ RS6000_BTI_UINTSI, /* unsigned_intSI_type_node */ @@ -7272,7 +9189,7 @@ testsuite/ RS6000_BTI_void, /* void_type_node */ RS6000_BTI_MAX }; -@@ -3157,6 +3446,8 @@ enum rs6000_builtin_type_index +@@ -3157,6 +3434,8 @@ enum rs6000_builtin_type_index #define opaque_p_V2SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_p_V2SI]) #define opaque_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V4SI]) #define V16QI_type_node (rs6000_builtin_types[RS6000_BTI_V16QI]) @@ -7281,7 +9198,7 @@ testsuite/ #define V2SI_type_node (rs6000_builtin_types[RS6000_BTI_V2SI]) #define V2SF_type_node (rs6000_builtin_types[RS6000_BTI_V2SF]) #define V4HI_type_node (rs6000_builtin_types[RS6000_BTI_V4HI]) -@@ -3183,7 +3474,10 @@ enum rs6000_builtin_type_index +@@ -3183,7 +3462,10 @@ enum rs6000_builtin_type_index #define uintHI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTHI]) #define intSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTSI]) #define uintSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTSI]) @@ -7292,8 +9209,8 @@ testsuite/ #define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void]) extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX]; ---- gcc/config/rs6000/altivec.md (.../trunk) (revision 144557) -+++ gcc/config/rs6000/altivec.md (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/altivec.md (.../trunk) (revision 145777) ++++ gcc/config/rs6000/altivec.md (.../branches/ibm/power7-meissner) (revision 146027) @@ -21,18 +21,7 @@ (define_constants @@ -7398,8 +9315,9 @@ testsuite/ } } - [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")]) -- --(define_split ++ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) + + (define_split - [(set (match_operand:V4SI 0 "nonimmediate_operand" "") - (match_operand:V4SI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed @@ -7416,9 +9334,8 @@ testsuite/ - && gpr_or_gpr_p (operands[0], operands[1])" - [(pc)] -{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) -+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) - - (define_split +- +-(define_split - [(set (match_operand:V16QI 0 "nonimmediate_operand" "") - (match_operand:V16QI 1 "input_operand" ""))] - "TARGET_ALTIVEC && reload_completed @@ -8088,22 +10005,7 @@ testsuite/ (define_insn "altivec_vsldoi_" [(set (match_operand:V 0 "register_operand" "=v") (unspec:V [(match_operand:V 1 "register_operand" "v") -@@ -1878,6 +1570,14 @@ (define_expand "build_vector_mask_for_lo - gcc_assert (GET_CODE (operands[1]) == MEM); - - addr = XEXP (operands[1], 0); -+ if (VECTOR_MEM_VSX_P (GET_MODE (operands[1]))) -+ { -+ /* VSX doesn't and off the bottom address bits, and memory -+ operations are aligned to the natural data type. */ -+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); -+ DONE; -+ } -+ - temp = gen_reg_rtx (GET_MODE (addr)); - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_NEG (GET_MODE (addr), addr))); -@@ -1959,95 +1659,6 @@ (define_insn "*altivec_stvesfx" +@@ -1959,95 +1651,6 @@ (define_insn "*altivec_stvesfx" "stvewx %1,%y0" [(set_attr "type" "vecstore")]) @@ -8199,7 +10101,7 @@ testsuite/ ;; Generate ;; vspltis? SCRATCH0,0 ;; vsubu?m SCRATCH2,SCRATCH1,%1 -@@ -2069,7 +1680,7 @@ (define_expand "abs2" +@@ -2069,7 +1672,7 @@ (define_expand "abs2" ;; vspltisw SCRATCH1,-1 ;; vslw SCRATCH2,SCRATCH1,SCRATCH1 ;; vandc %0,%1,SCRATCH2 @@ -8208,7 +10110,7 @@ testsuite/ [(set (match_dup 2) (vec_duplicate:V4SI (const_int -1))) (set (match_dup 3) -@@ -2132,7 +1743,7 @@ (define_expand "vec_shl_" +@@ -2132,7 +1735,7 @@ (define_expand "vec_shl_" DONE; }") @@ -8217,7 +10119,7 @@ testsuite/ ;; amounts that can be expressed as byte shifts (divisible by 8). ;; General shift amounts can be supported using vsro + vsr. We're ;; not expecting to see these yet (the vectorizer currently -@@ -2665,7 +2276,7 @@ (define_expand "vec_pack_trunc_v4si" +@@ -2665,7 +2268,7 @@ (define_expand "vec_pack_trunc_v4si" DONE; }") @@ -8226,7 +10128,7 @@ testsuite/ [(use (match_operand:V4SF 0 "register_operand" "")) (use (match_operand:V4SF 1 "register_operand" ""))] "TARGET_ALTIVEC" -@@ -2994,29 +2605,6 @@ (define_expand "vec_extract_oddv16qi" +@@ -2994,29 +2597,6 @@ (define_expand "vec_extract_oddv16qi" emit_insn (gen_vpkuhum_nomode (operands[0], operands[1], operands[2])); DONE; }") @@ -8256,8 +10158,8 @@ testsuite/ (define_expand "vec_interleave_high" [(set (match_operand:VI 0 "register_operand" "") ---- gcc/config/rs6000/aix61.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/aix61.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/aix61.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/aix61.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -57,20 +57,24 @@ do { \ #undef ASM_SPEC #define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" @@ -8285,9 +10187,9 @@ testsuite/ %{mcpu=powerpc: -mppc} \ %{mcpu=rs64a: -mppc} \ %{mcpu=603: -m603} \ ---- gcc/config/rs6000/rs6000.md (.../trunk) (revision 144557) -+++ gcc/config/rs6000/rs6000.md (.../branches/ibm/power7-meissner) (revision 144730) -@@ -138,7 +138,7 @@ (define_attr "length" "" +--- gcc/config/rs6000/rs6000.md (.../trunk) (revision 145777) ++++ gcc/config/rs6000/rs6000.md (.../branches/ibm/power7-meissner) (revision 146027) +@@ -138,7 +138,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. @@ -8296,7 +10198,7 @@ testsuite/ (const (symbol_ref "rs6000_cpu_attr"))) -@@ -167,6 +167,7 @@ (define_attr "cell_micro" "not,condition +@@ -167,6 +167,7 @@ (include "power4.md") (include "power5.md") (include "power6.md") @@ -8304,17 +10206,27 @@ testsuite/ (include "cell.md") (include "xfpu.md") -@@ -218,6 +219,9 @@ (define_mode_attr wd [(QI "b") (HI "h") +@@ -218,6 +219,19 @@ ; DImode bits (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) +;; ISEL/ISEL64 target selection +(define_mode_attr sel [(SI "") (DI "64")]) ++ ++;; Suffix for reload patterns ++(define_mode_attr ptrsize [(SI "32bit") ++ (DI "64bit")]) ++ ++(define_mode_attr tptrsize [(SI "TARGET_32BIT") ++ (DI "TARGET_64BIT")]) ++ ++(define_mode_attr mptrsize [(SI "si") ++ (DI "di")]) + ;; Start with fixed-point load and store insns. Here we put only the more ;; complex forms. Basic data transfer is done later. -@@ -520,7 +524,7 @@ (define_insn "" +@@ -520,7 +534,7 @@ "@ {andil.|andi.} %2,%1,0xff #" @@ -8323,7 +10235,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -546,7 +550,7 @@ (define_insn "" +@@ -546,7 +560,7 @@ "@ {andil.|andi.} %0,%1,0xff #" @@ -8332,7 +10244,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -687,7 +691,7 @@ (define_insn "" +@@ -687,7 +701,7 @@ "@ {andil.|andi.} %2,%1,0xff #" @@ -8341,7 +10253,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -713,7 +717,7 @@ (define_insn "" +@@ -713,7 +727,7 @@ "@ {andil.|andi.} %0,%1,0xff #" @@ -8350,7 +10262,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -856,7 +860,7 @@ (define_insn "" +@@ -856,7 +870,7 @@ "@ {andil.|andi.} %2,%1,0xffff #" @@ -8359,7 +10271,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -882,7 +886,7 @@ (define_insn "" +@@ -882,7 +896,7 @@ "@ {andil.|andi.} %0,%1,0xffff #" @@ -8368,7 +10280,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -1670,7 +1674,7 @@ (define_insn "" +@@ -1670,7 +1684,7 @@ "@ nor. %2,%1,%1 #" @@ -8377,7 +10289,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -1696,7 +1700,7 @@ (define_insn "" +@@ -1696,7 +1710,7 @@ "@ nor. %0,%1,%1 #" @@ -8386,7 +10298,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -2221,10 +2225,22 @@ (define_insn "popcntb2" +@@ -2221,10 +2235,22 @@ "TARGET_POPCNTB" "popcntb %0,%1") @@ -8410,7 +10322,7 @@ testsuite/ { rs6000_emit_popcount (operands[0], operands[1]); DONE; -@@ -2852,7 +2868,7 @@ (define_insn "andsi3_mc" +@@ -2852,7 +2878,7 @@ {rlinm|rlwinm} %0,%1,0,%m2,%M2 {andil.|andi.} %0,%1,%b2 {andiu.|andis.} %0,%1,%u2" @@ -8419,7 +10331,7 @@ testsuite/ (define_insn "andsi3_nomc" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") -@@ -2895,7 +2911,8 @@ (define_insn "*andsi3_internal2_mc" +@@ -2895,7 +2921,8 @@ # # #" @@ -8429,7 +10341,7 @@ testsuite/ (set_attr "length" "4,4,4,4,8,8,8,8")]) (define_insn "*andsi3_internal3_mc" -@@ -2915,7 +2932,8 @@ (define_insn "*andsi3_internal3_mc" +@@ -2915,7 +2942,8 @@ # # #" @@ -8439,7 +10351,7 @@ testsuite/ (set_attr "length" "8,4,4,4,8,8,8,8")]) (define_split -@@ -2974,7 +2992,8 @@ (define_insn "*andsi3_internal4" +@@ -2974,7 +3002,8 @@ # # #" @@ -8449,17 +10361,17 @@ testsuite/ (set_attr "length" "4,4,4,4,8,8,8,8")]) (define_insn "*andsi3_internal5_mc" -@@ -2996,7 +3015,8 @@ (define_insn "*andsi3_internal5_mc" +@@ -2996,7 +3025,8 @@ # # #" - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") + [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\ -+ compare,compare,compare") ++ compare,compare,compare") (set_attr "length" "8,4,4,4,8,8,8,8")]) (define_split -@@ -3127,7 +3147,7 @@ (define_insn "*boolsi3_internal2" +@@ -3127,7 +3157,7 @@ "@ %q4. %3,%1,%2 #" @@ -8468,7 +10380,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -3156,7 +3176,7 @@ (define_insn "*boolsi3_internal3" +@@ -3156,7 +3186,7 @@ "@ %q4. %0,%1,%2 #" @@ -8477,7 +10389,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -3281,7 +3301,7 @@ (define_insn "*boolccsi3_internal2" +@@ -3281,7 +3311,7 @@ "@ %q4. %3,%1,%2 #" @@ -8486,7 +10398,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -3310,7 +3330,7 @@ (define_insn "*boolccsi3_internal3" +@@ -3310,7 +3340,7 @@ "@ %q4. %0,%1,%2 #" @@ -8495,7 +10407,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -5303,7 +5323,7 @@ (define_insn "fres" +@@ -5303,7 +5333,7 @@ "fres %0,%1" [(set_attr "type" "fp")]) @@ -8504,7 +10416,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5314,7 +5334,7 @@ (define_insn "" +@@ -5314,7 +5344,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8513,7 +10425,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5323,7 +5343,7 @@ (define_insn "" +@@ -5323,7 +5353,7 @@ "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -8522,7 +10434,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5334,7 +5354,7 @@ (define_insn "" +@@ -5334,7 +5364,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8531,7 +10443,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5343,7 +5363,7 @@ (define_insn "" +@@ -5343,7 +5373,7 @@ "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -8540,7 +10452,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5354,7 +5374,7 @@ (define_insn "" +@@ -5354,7 +5384,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8549,7 +10461,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")) (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5365,7 +5385,7 @@ (define_insn "" +@@ -5365,7 +5395,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8558,7 +10470,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5374,7 +5394,7 @@ (define_insn "" +@@ -5374,7 +5404,7 @@ "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -8567,7 +10479,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")) (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5384,7 +5404,7 @@ (define_insn "" +@@ -5384,7 +5414,7 @@ "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -8576,7 +10488,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5395,7 +5415,7 @@ (define_insn "" +@@ -5395,7 +5425,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8585,7 +10497,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") -@@ -5406,7 +5426,7 @@ (define_insn "" +@@ -5406,7 +5436,7 @@ [(set_attr "type" "fp") (set_attr "fp_type" "fp_maddsub_s")]) @@ -8594,7 +10506,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")) -@@ -5415,7 +5435,7 @@ (define_insn "" +@@ -5415,7 +5445,7 @@ "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -8603,7 +10515,7 @@ testsuite/ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") -@@ -5496,9 +5516,18 @@ (define_expand "copysigndf3" +@@ -5496,9 +5526,18 @@ (match_dup 5)) (match_dup 3) (match_dup 4)))] @@ -8624,7 +10536,7 @@ testsuite/ operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (DFmode); operands[5] = CONST0_RTX (DFmode); -@@ -5542,12 +5571,12 @@ (define_split +@@ -5542,12 +5581,12 @@ DONE; }") @@ -8643,7 +10555,7 @@ testsuite/ " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) -@@ -5564,28 +5593,28 @@ (define_expand "movsicc" +@@ -5564,28 +5603,28 @@ ;; leave out the mode in operand 4 and use one pattern, but reload can ;; change the mode underneath our feet and then gets confused trying ;; to reload the value. @@ -8684,7 +10596,7 @@ testsuite/ "* { return output_isel (operands); }" [(set_attr "length" "4")]) -@@ -5633,7 +5662,8 @@ (define_expand "negdf2" +@@ -5633,7 +5672,8 @@ (define_insn "*negdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] @@ -8694,7 +10606,7 @@ testsuite/ "fneg %0,%1" [(set_attr "type" "fp")]) -@@ -5646,14 +5676,16 @@ (define_expand "absdf2" +@@ -5646,14 +5686,16 @@ (define_insn "*absdf2_fpr" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] @@ -8713,7 +10625,7 @@ testsuite/ "fnabs %0,%1" [(set_attr "type" "fp")]) -@@ -5668,7 +5700,8 @@ (define_insn "*adddf3_fpr" +@@ -5668,7 +5710,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] @@ -8723,7 +10635,7 @@ testsuite/ "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_d")]) -@@ -5684,7 +5717,8 @@ (define_insn "*subdf3_fpr" +@@ -5684,7 +5727,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] @@ -8733,7 +10645,7 @@ testsuite/ "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp") (set_attr "fp_type" "fp_addsub_d")]) -@@ -5700,7 +5734,8 @@ (define_insn "*muldf3_fpr" +@@ -5700,7 +5744,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f") (match_operand:DF 2 "gpc_reg_operand" "f")))] @@ -8743,7 +10655,7 @@ testsuite/ "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_mul_d")]) -@@ -5718,7 +5753,8 @@ (define_insn "*divdf3_fpr" +@@ -5718,7 +5763,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (div:DF (match_operand:DF 1 "gpc_reg_operand" "f") (match_operand:DF 2 "gpc_reg_operand" "f")))] @@ -8753,7 +10665,7 @@ testsuite/ "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) -@@ -5734,73 +5770,81 @@ (define_expand "recipdf3" +@@ -5734,73 +5780,81 @@ DONE; }) @@ -8849,7 +10761,7 @@ testsuite/ "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul") (set_attr "fp_type" "fp_maddsub_d")]) -@@ -5809,7 +5853,8 @@ (define_insn "sqrtdf2" +@@ -5809,7 +5863,8 @@ [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS @@ -8859,7 +10771,7 @@ testsuite/ "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) -@@ -5898,6 +5943,18 @@ (define_expand "fix_truncsfsi2" +@@ -5898,6 +5953,18 @@ "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" "") @@ -8878,7 +10790,7 @@ testsuite/ ; For each of these conversions, there is a define_expand, a define_insn ; with a '#' template, and a define_split (with C code). The idea is ; to allow constant folding with the template of the define_insn, -@@ -6139,10 +6196,17 @@ (define_insn "fctiwz" +@@ -6139,24 +6206,38 @@ "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) @@ -8897,7 +10809,11 @@ testsuite/ "friz %0,%1" [(set_attr "type" "fp")]) -@@ -6153,10 +6217,17 @@ (define_insn "btruncsf2" + (define_insn "btruncsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] +- "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " ++ "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" "friz %0,%1" [(set_attr "type" "fp")]) @@ -8917,7 +10833,7 @@ testsuite/ "frip %0,%1" [(set_attr "type" "fp")]) -@@ -6167,10 +6238,17 @@ (define_insn "ceilsf2" +@@ -6167,10 +6248,17 @@ "frip %0,%1" [(set_attr "type" "fp")]) @@ -8937,7 +10853,7 @@ testsuite/ "frim %0,%1" [(set_attr "type" "fp")]) -@@ -6181,6 +6259,7 @@ (define_insn "floorsf2" +@@ -6181,6 +6269,7 @@ "frim %0,%1" [(set_attr "type" "fp")]) @@ -8945,7 +10861,7 @@ testsuite/ (define_insn "rounddf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))] -@@ -6195,6 +6274,12 @@ (define_insn "roundsf2" +@@ -6195,6 +6284,12 @@ "frin %0,%1" [(set_attr "type" "fp")]) @@ -8958,7 +10874,7 @@ testsuite/ ; An UNSPEC is used so we don't have to support SImode in FP registers. (define_insn "stfiwx" [(set (match_operand:SI 0 "memory_operand" "=Z") -@@ -6210,17 +6295,40 @@ (define_expand "floatsisf2" +@@ -6210,17 +6305,40 @@ "TARGET_HARD_FLOAT && !TARGET_FPRS" "") @@ -9003,7 +10919,7 @@ testsuite/ "fctidz %0,%1" [(set_attr "type" "fp")]) -@@ -7609,7 +7717,7 @@ (define_insn "anddi3_mc" +@@ -7609,7 +7727,7 @@ andi. %0,%1,%b2 andis. %0,%1,%u2 #" @@ -9012,7 +10928,7 @@ testsuite/ (set_attr "length" "4,4,4,4,4,8")]) (define_insn "anddi3_nomc" -@@ -7667,7 +7775,9 @@ (define_insn "*anddi3_internal2_mc" +@@ -7667,7 +7785,9 @@ # # #" @@ -9023,7 +10939,7 @@ testsuite/ (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) (define_split -@@ -7718,7 +7828,9 @@ (define_insn "*anddi3_internal3_mc" +@@ -7718,7 +7838,9 @@ # # #" @@ -9034,7 +10950,7 @@ testsuite/ (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) (define_split -@@ -7858,7 +7970,7 @@ (define_insn "*booldi3_internal2" +@@ -7858,7 +7980,7 @@ "@ %q4. %3,%1,%2 #" @@ -9043,7 +10959,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -7887,7 +7999,7 @@ (define_insn "*booldi3_internal3" +@@ -7887,7 +8009,7 @@ "@ %q4. %0,%1,%2 #" @@ -9052,7 +10968,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -7958,7 +8070,7 @@ (define_insn "*boolcdi3_internal2" +@@ -7958,7 +8080,7 @@ "@ %q4. %3,%2,%1 #" @@ -9061,7 +10977,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -7987,7 +8099,7 @@ (define_insn "*boolcdi3_internal3" +@@ -7987,7 +8109,7 @@ "@ %q4. %0,%2,%1 #" @@ -9070,7 +10986,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -8024,7 +8136,7 @@ (define_insn "*boolccdi3_internal2" +@@ -8024,7 +8146,7 @@ "@ %q4. %3,%1,%2 #" @@ -9079,7 +10995,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -8053,7 +8165,7 @@ (define_insn "*boolccdi3_internal3" +@@ -8053,7 +8175,7 @@ "@ %q4. %0,%1,%2 #" @@ -9088,7 +11004,7 @@ testsuite/ (set_attr "length" "4,8")]) (define_split -@@ -8070,6 +8182,51 @@ (define_split +@@ -8070,6 +8192,51 @@ (compare:CC (match_dup 0) (const_int 0)))] "") @@ -9140,7 +11056,7 @@ testsuite/ ;; Now define ways of moving data around. -@@ -8473,8 +8630,8 @@ (define_split +@@ -8473,8 +8640,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdf_hardfloat32" @@ -9151,14 +11067,14 @@ testsuite/ "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" -@@ -8553,19 +8710,30 @@ (define_insn "*movdf_hardfloat32" +@@ -8553,19 +8720,30 @@ return \"\"; } case 3: - return \"fmr %0,%1\"; case 4: - return \"lfd%U1%X1 %0,%1\"; -+ return \"xscpsgndp %x0,%x1,%x1\"; ++ return \"xxlor %x0,%x1,%x1\"; case 5: - return \"stfd%U0%X0 %1,%0\"; case 6: @@ -9187,7 +11103,7 @@ testsuite/ (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") -@@ -8613,19 +8781,26 @@ (define_insn "*movdf_softfloat32" +@@ -8613,19 +8791,26 @@ ; ld/std require word-aligned displacements -> 'Y' constraint. ; List Y->r and r->Y before r->r for reload. (define_insn "*movdf_hardfloat64_mfpgpr" @@ -9204,8 +11120,8 @@ testsuite/ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 -+ xscpsgndp %x0,%x1,%x1 -+ xscpsgndp %x0,%x1,%x1 ++ xxlor %x0,%x1,%x1 ++ xxlor %x0,%x1,%x1 + lxsd%U1x %x0,%y1 + lxsd%U1x %x0,%y1 + stxsd%U0x %x1,%y0 @@ -9217,7 +11133,7 @@ testsuite/ mt%0 %1 mf%1 %0 {cror 0,0,0|nop} -@@ -8634,33 +8809,40 @@ (define_insn "*movdf_hardfloat64_mfpgpr" +@@ -8634,33 +8819,40 @@ # mftgpr %0,%1 mffgpr %0,%1" @@ -9242,8 +11158,8 @@ testsuite/ std%U0%X0 %1,%0 ld%U1%X1 %0,%1 mr %0,%1 -+ xscpsgndp %x0,%x1,%x1 -+ xscpsgndp %x0,%x1,%x1 ++ xxlor %x0,%x1,%x1 ++ xxlor %x0,%x1,%x1 + lxsd%U1x %x0,%y1 + lxsd%U1x %x0,%y1 + stxsd%U0x %x1,%y0 @@ -9265,7 +11181,7 @@ testsuite/ (define_insn "*movdf_softfloat64" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") -@@ -9237,15 +9419,16 @@ (define_insn "*movti_string" +@@ -9237,15 +9429,16 @@ (define_insn "*movti_ppc64" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r") (match_operand:TI 1 "input_operand" "r,r,m"))] @@ -9285,7 +11201,7 @@ testsuite/ [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5))] " -@@ -9271,7 +9454,7 @@ (define_split +@@ -9271,7 +9464,7 @@ (define_split [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "input_operand" ""))] @@ -9294,7 +11210,7 @@ testsuite/ && gpr_or_gpr_p (operands[0], operands[1])" [(pc)] { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) -@@ -14891,6 +15074,8 @@ (define_insn "prefetch" +@@ -14891,6 +15084,8 @@ (include "sync.md") @@ -9303,8 +11219,8 @@ testsuite/ (include "altivec.md") (include "spe.md") (include "dfp.md") ---- gcc/config/rs6000/e500.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/e500.h (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/e500.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/e500.h (.../branches/ibm/power7-meissner) (revision 146027) @@ -37,6 +37,8 @@ { \ if (TARGET_ALTIVEC) \ @@ -9314,8 +11230,8 @@ testsuite/ if (TARGET_64BIT) \ error ("64-bit E500 not supported"); \ if (TARGET_HARD_FLOAT && TARGET_FPRS) \ ---- gcc/config/rs6000/driver-rs6000.c (.../trunk) (revision 144557) -+++ gcc/config/rs6000/driver-rs6000.c (.../branches/ibm/power7-meissner) (revision 144730) +--- gcc/config/rs6000/driver-rs6000.c (.../trunk) (revision 145777) ++++ gcc/config/rs6000/driver-rs6000.c (.../branches/ibm/power7-meissner) (revision 146027) @@ -343,11 +343,115 @@ detect_processor_aix (void) #endif /* _AIX */ @@ -9496,9 +11412,9 @@ testsuite/ return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL); } ---- gcc/config/rs6000/sysv4.h (.../trunk) (revision 144557) -+++ gcc/config/rs6000/sysv4.h (.../branches/ibm/power7-meissner) (revision 144730) -@@ -119,9 +119,9 @@ do { \ +--- gcc/config/rs6000/sysv4.h (.../trunk) (revision 145777) ++++ gcc/config/rs6000/sysv4.h (.../branches/ibm/power7-meissner) (revision 146027) +@@ -120,9 +120,9 @@ do { \ else if (!strcmp (rs6000_abi_name, "i960-old")) \ { \ rs6000_current_abi = ABI_V4; \ diff --git a/gcc44-pr39543.patch b/gcc44-pr39543.patch index 518f2cc..e84c6b5 100644 --- a/gcc44-pr39543.patch +++ b/gcc44-pr39543.patch @@ -1,4 +1,4 @@ -2009-03-27 Jakub Jelinek +2009-04-10 Jakub Jelinek PR rtl-optimization/39543 * fwprop.c (forward_propagate_asm): New function. @@ -9,8 +9,8 @@ * gcc.target/i386/pr39543-2.c: New test. * gcc.target/i386/pr39543-3.c: New test. ---- gcc/fwprop.c.jj 2009-03-27 07:55:33.000000000 +0100 -+++ gcc/fwprop.c 2009-03-27 10:00:48.000000000 +0100 +--- 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. @@ -18,7 +18,7 @@ Contributed by Paolo Bonzini and Steven Bosscher. This file is part of GCC. -@@ -852,6 +852,73 @@ forward_propagate_subreg (df_ref use, rt +@@ -852,6 +852,80 @@ forward_propagate_subreg (df_ref use, rt return false; } @@ -50,20 +50,27 @@ + asm_operands = use_pat; + break; + case SET: -+ 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); ++ 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) + { -+ 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); ++ 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) @@ -92,7 +99,7 @@ /* Try to replace USE with SRC (defined in DEF_INSN) and simplify the result. */ -@@ -863,12 +930,16 @@ forward_propagate_and_simplify (df_ref u +@@ -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; @@ -111,7 +118,7 @@ return false; /* If def and use are subreg, check if they match. */ -@@ -900,7 +971,7 @@ forward_propagate_and_simplify (df_ref u +@@ -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); @@ -120,7 +127,7 @@ { rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX); rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set); -@@ -911,6 +982,9 @@ forward_propagate_and_simplify (df_ref u +@@ -911,6 +989,9 @@ forward_propagate_and_simplify (df_ref u return false; } @@ -130,8 +137,8 @@ /* Else try simplifying. */ if (DF_REF_TYPE (use) == DF_REF_REG_MEM_STORE) ---- gcc/testsuite/gcc.target/i386/pr39543-1.c.jj 2009-03-25 16:40:18.000000000 +0100 -+++ gcc/testsuite/gcc.target/i386/pr39543-1.c 2009-03-25 16:40:50.000000000 +0100 +--- 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 } */ @@ -185,8 +192,8 @@ +{ + bar (s0); +} ---- gcc/testsuite/gcc.target/i386/pr39543-2.c.jj 2009-03-25 16:40:18.000000000 +0100 -+++ gcc/testsuite/gcc.target/i386/pr39543-2.c 2009-03-25 16:40:38.000000000 +0100 +--- 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 } */ @@ -239,8 +246,8 @@ +{ + bar (s0); +} ---- gcc/testsuite/gcc.target/i386/pr39543-3.c.jj 2009-03-25 16:41:29.000000000 +0100 -+++ gcc/testsuite/gcc.target/i386/pr39543-3.c 2009-03-25 16:41:19.000000000 +0100 +--- 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 } */ diff --git a/sources b/sources index 556d54b..b14756b 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ 2659f09c2e43ef8b7d4406321753f1b2 fastjar-0.97.tar.gz -e45f1b49ad6bc7e78ef8887cab726943 gcc-4.4.0-20090409.tar.bz2 +004cfd0a49b225032953517a827da968 gcc-4.4.0-20090414.tar.bz2