]> code.ossystems Code Review - meta-freescale.git/commitdiff
integrate fsl toolchain patches
authorZhenhua Luo <b19537@freescale.com>
Fri, 9 Mar 2012 10:57:35 +0000 (10:57 +0000)
committerMatthew McClintock <msm@freescale.com>
Tue, 13 Mar 2012 17:41:42 +0000 (12:41 -0500)
    binutils:
        bin.e500mc_nop.patch
        bin.e5500.patch
        bin.e6500-2.patch
    eglibc:
        generate-supported.mk
        glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch
        glibc.fixgcc4.6.patch
        glibc.fix_prof.patch
        glibc.fix_sqrt.patch
        glibc.readv_proto.patch
        glibc.undefined_static.patch
    gcc:
        gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch
        gcc.fix_longversionstring.patch
        gcc.rm_slow_tests.patch
        gcc.fix_mingw32.patch
        gcc.fix_cloogstatic2.patch
        gcc.fix_build-with-cxx.patch
        gcc.e6500-FSF46.patch
        gcc.ld_unaligned-460.patch
        gcc.local_unaligned_altivec.patch
        gcc.soft_float-460.patch
        gcc.case_values.patch
        gcc.builtin_isel.patch
        gcc.experimental_move.patch
        gcc.widen_types-46.patch
        gcc.extelim-v3.patch
        gcc.e5500_mfocr.patch
        gcc.opt-array-offset.patch
        gcc.load_on_store_bypass-462.patch
        gcc.fix_constvector.patch
        gcc.fix_MTWX51204-dwarf-vector-reg.patch
        gcc.fix_ira-loop-pressure.patch
        optional_libstdc.patch
        gcc.remove_CCUNSmode_reference.patch
        gcc.check_path_validity.patch
        gcc.fix_header_issue.patch
        gcc.fix_SSIZE_MAX_undefine_issue.patch
    gettext:
        gettext.fix_testcase.patch

Signed-off-by: Zhenhua Luo <b19537@freescale.com>
58 files changed:
meta-fsl-ppc/recipes-append/gettext/files/gettext.fix_testcase.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-append/gettext/gettext_0.18.1.1.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/binutils-cross-canadian_2.21.1a.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/binutils-cross_2.21.1a.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/binutils-crosssdk_2.21.1a.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/binutils-fsl.inc [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/binutils_2.21.1a.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/files/bin.e500mc_nop.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/files/bin.e5500.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/binutils/files/bin.e6500-2.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/eglibc-fsl.inc [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/eglibc-initial_2.13.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/eglibc-locale_2.13.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/eglibc_2.13.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/etc/ld.so.conf [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/generate-supported.mk [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_prof.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_sqrt.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fixgcc4.6.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.readv_proto.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.undefined_static.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.builtin_isel.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.case_values.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.check_path_validity.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e5500_mfocr.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e6500-FSF46.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.experimental_move.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.extelim-v3.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_MTWX51204-dwarf-vector-reg.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_SSIZE_MAX_undefine_issue.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_build-with-cxx.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_cloogstatic2.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_constvector.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_header_issue.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_ira-loop-pressure.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_longversionstring.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_mingw32.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.ld_unaligned-460.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.load_on_store_bypass-462.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.local_unaligned_altivec.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.opt-array-offset.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.remove_CCUNSmode_reference.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.rm_slow_tests.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.soft_float-460.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/gcc.widen_types-46.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/files/optional_libstdc.patch [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-canadian_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-initial_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-intermediate_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-cross_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-initial_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-intermediate_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-fsl.inc [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc-runtime_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/gcc_4.6.bbappend [new file with mode: 0644]
meta-fsl-ppc/recipes-devtools/gcc/libgcc_4.6.bbappend [new file with mode: 0644]

diff --git a/meta-fsl-ppc/recipes-append/gettext/files/gettext.fix_testcase.patch b/meta-fsl-ppc/recipes-append/gettext/files/gettext.fix_testcase.patch
new file mode 100644 (file)
index 0000000..135f267
--- /dev/null
@@ -0,0 +1,13 @@
+--- gettext-0.16.1/gettext-runtime/tests/test-lock.c-orig      2011-07-22 12:51:14.734334073 -0500
++++ gettext-0.16.1/gettext-runtime/tests/test-lock.c   2011-07-22 12:43:59.962333864 -0500
+@@ -106,7 +106,9 @@
+ }
+ static inline void * gl_thread_self (void)
+ {
+-  return (void *) pthread_self ();
++  pthread_t x;
++  x =  pthread_self ();
++  return (void *)&x;
+ }
+ #endif
+ #if TEST_PTH_THREADS
diff --git a/meta-fsl-ppc/recipes-append/gettext/gettext_0.18.1.1.bbappend b/meta-fsl-ppc/recipes-append/gettext/gettext_0.18.1.1.bbappend
new file mode 100644 (file)
index 0000000..937be22
--- /dev/null
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://gettext.fix_testcase.patch"
+
+PR .= "+${DISTRO}.0"
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross-canadian_2.21.1a.bbappend b/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross-canadian_2.21.1a.bbappend
new file mode 100644 (file)
index 0000000..d46b87a
--- /dev/null
@@ -0,0 +1 @@
+require binutils-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross_2.21.1a.bbappend b/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross_2.21.1a.bbappend
new file mode 100644 (file)
index 0000000..d46b87a
--- /dev/null
@@ -0,0 +1 @@
+require binutils-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/binutils-crosssdk_2.21.1a.bbappend b/meta-fsl-ppc/recipes-devtools/binutils/binutils-crosssdk_2.21.1a.bbappend
new file mode 100644 (file)
index 0000000..d46b87a
--- /dev/null
@@ -0,0 +1 @@
+require binutils-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/binutils-fsl.inc b/meta-fsl-ppc/recipes-devtools/binutils/binutils-fsl.inc
new file mode 100644 (file)
index 0000000..e425d42
--- /dev/null
@@ -0,0 +1,10 @@
+SRC_URI = "\
+               ${GNU_MIRROR}/binutils/binutils-${PV}.tar.bz2 \
+               file://bin.e5500.patch \
+               file://bin.e6500-2.patch \
+               file://bin.e500mc_nop.patch \
+               "
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR .= "+${DISTRO}.0"
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/binutils_2.21.1a.bbappend b/meta-fsl-ppc/recipes-devtools/binutils/binutils_2.21.1a.bbappend
new file mode 100644 (file)
index 0000000..d46b87a
--- /dev/null
@@ -0,0 +1 @@
+require binutils-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e500mc_nop.patch b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e500mc_nop.patch
new file mode 100644 (file)
index 0000000..9c9d52c
--- /dev/null
@@ -0,0 +1,114 @@
+Generate the preferred NOP: ori r0, r0, 0 in the place of ori r2, r2, 0
+and add the nop test cases in gas for e500mc64, e5500 and e6500.
+
+diff -ruN binutils-4.6.0-orig/gas/config/tc-ppc.c binutils-4.6.0-new/gas/config/tc-ppc.c
+--- binutils-4.6.0-orig/gas/config/tc-ppc.c    2011-08-18 16:02:21.847979825 -0500
++++ binutils-4.6.0-new/gas/config/tc-ppc.c     2011-08-19 10:09:19.888849978 -0500
+@@ -5815,8 +5817,14 @@
+           }
+         if ((ppc_cpu & PPC_OPCODE_POWER7) != 0)
+-          /* power7 group terminating nop: "ori 2,2,0".  */
+-          md_number_to_chars (dest, 0x60420000, 4);
++          {
++            if (ppc_cpu & PPC_OPCODE_E500MC)
++              /* e500mc group terminating nop: "ori 0,0,0".  */
++              md_number_to_chars (dest, 0x60000000, 4);
++            else
++              /* power7 group terminating nop: "ori 2,2,0".  */
++              md_number_to_chars (dest, 0x60420000, 4);
++          }
+         else
+           /* power6 group terminating nop: "ori 1,1,0".  */
+           md_number_to_chars (dest, 0x60210000, 4);
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e500mc64_nop.d binutils-4.6.0-new/gas/testsuite/gas/ppc/e500mc64_nop.d
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e500mc64_nop.d   1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e500mc64_nop.d    2011-08-19 10:16:29.561849966 -0500
+@@ -0,0 +1,13 @@
++#as: -mppc -me500mc64
++#objdump: -dr -Me500mc64
++#name: Power E500MC64 nop tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0: 60 00 00 00     nop
++   4: 60 00 00 00     nop
++   8: 60 00 00 00     nop
++   c: 60 00 00 00     nop
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e500mc64_nop.s binutils-4.6.0-new/gas/testsuite/gas/ppc/e500mc64_nop.s
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e500mc64_nop.s   1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e500mc64_nop.s    2011-08-19 10:16:29.561849966 -0500
+@@ -0,0 +1,5 @@
++# Power E500MC64 nop tests
++      .section  ".text"
++start:
++      nop
++      .p2align 4,,15
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e5500_nop.d binutils-4.6.0-new/gas/testsuite/gas/ppc/e5500_nop.d
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e5500_nop.d      1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e5500_nop.d       2011-08-19 10:16:29.561849966 -0500
+@@ -0,0 +1,13 @@
++#as: -mppc -me5500
++#objdump: -dr -Me5500
++#name: Power E5500 nop tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0: 60 00 00 00     nop
++   4: 60 00 00 00     nop
++   8: 60 00 00 00     nop
++   c: 60 00 00 00     nop
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e5500_nop.s binutils-4.6.0-new/gas/testsuite/gas/ppc/e5500_nop.s
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e5500_nop.s      1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e5500_nop.s       2011-08-19 10:16:29.561849966 -0500
+@@ -0,0 +1,5 @@
++# Power E5500 nop tests
++      .section  ".text"
++start:
++      nop
++      .p2align 4,,15
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e6500_nop.d binutils-4.6.0-new/gas/testsuite/gas/ppc/e6500_nop.d
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e6500_nop.d      1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e6500_nop.d       2011-08-19 10:16:29.561849966 -0500
+@@ -0,0 +1,13 @@
++#as: -mppc -me6500
++#objdump: -dr -Me6500
++#name: Power E6500 nop tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0: 60 00 00 00     nop
++   4: 60 00 00 00     nop
++   8: 60 00 00 00     nop
++   c: 60 00 00 00     nop
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/e6500_nop.s binutils-4.6.0-new/gas/testsuite/gas/ppc/e6500_nop.s
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/e6500_nop.s      1969-12-31 18:00:00.000000000 -0600
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/e6500_nop.s       2011-08-19 10:16:29.562849956 -0500
+@@ -0,0 +1,5 @@
++# Power E6500 nop tests
++      .section  ".text"
++start:
++      nop
++      .p2align 4,,15
+diff -ruN binutils-4.6.0-orig/gas/testsuite/gas/ppc/ppc.exp binutils-4.6.0-new/gas/testsuite/gas/ppc/ppc.exp
+--- binutils-4.6.0-orig/gas/testsuite/gas/ppc/ppc.exp  2011-08-19 10:15:29.445978575 -0500
++++ binutils-4.6.0-new/gas/testsuite/gas/ppc/ppc.exp   2011-08-19 10:16:17.827852501 -0500
+@@ -43,6 +43,9 @@
+       run_dump_test "ppc750ps"
+       run_dump_test "e500mc"
+       run_dump_test "e6500"
++      run_dump_test "e500mc64_nop"
++      run_dump_test "e5500_nop"
++      run_dump_test "e6500_nop"
+       run_dump_test "a2"
+       run_dump_test "cell"
+       run_dump_test "common"
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e5500.patch b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e5500.patch
new file mode 100644 (file)
index 0000000..800590c
--- /dev/null
@@ -0,0 +1,102 @@
+bin.e5500
+
+Implements target e5500 and -me5500, etc..
+
+diff -r -u binutils-2.21-20110211-orig/bfd/archures.c binutils-2.21-20110211/bfd/archures.c
+--- binutils-2.21-20110211-orig/bfd/archures.c 2010-12-30 18:33:31.000000000 -0600
++++ binutils-2.21-20110211/bfd/archures.c      2011-02-14 13:17:00.528340236 -0600
+@@ -234,6 +234,7 @@
+ .#define bfd_mach_ppc_e500      500
+ .#define bfd_mach_ppc_e500mc    5001
+ .#define bfd_mach_ppc_e500mc64  5005
++.#define bfd_mach_ppc_e5500     5006
+ .#define bfd_mach_ppc_titan     83
+ .  bfd_arch_rs6000,    {* IBM RS/6000 *}
+ .#define bfd_mach_rs6k                6000
+diff -r -u binutils-2.21-20110211-orig/bfd/bfd-in2.h binutils-2.21-20110211/bfd/bfd-in2.h
+--- binutils-2.21-20110211-orig/bfd/bfd-in2.h  2011-02-11 10:57:58.000000000 -0600
++++ binutils-2.21-20110211/bfd/bfd-in2.h       2011-02-14 13:19:57.365092179 -0600
+@@ -1921,6 +1921,7 @@
+ #define bfd_mach_ppc_e500      500
+ #define bfd_mach_ppc_e500mc    5001
+ #define bfd_mach_ppc_e500mc64  5005
++#define bfd_mach_ppc_e5500     5006
+ #define bfd_mach_ppc_titan     83
+   bfd_arch_rs6000,    /* IBM RS/6000 */
+ #define bfd_mach_rs6k          6000
+diff -r -u binutils-2.21-20110211-orig/bfd/cpu-powerpc.c binutils-2.21-20110211/bfd/cpu-powerpc.c
+--- binutils-2.21-20110211-orig/bfd/cpu-powerpc.c      2010-02-07 19:59:34.000000000 -0600
++++ binutils-2.21-20110211/bfd/cpu-powerpc.c   2011-02-14 13:21:48.802403135 -0600
+@@ -352,6 +352,20 @@
+     FALSE, /* not the default */
+     powerpc_compatible,
+     bfd_default_scan,
++    &bfd_powerpc_archs[19]
++  },
++  {
++    64, /* 64 bits in a word */
++    64, /* 64 bits in an address */
++    8,  /* 8 bits in a byte */
++    bfd_arch_powerpc,
++    bfd_mach_ppc_e5500,
++    "powerpc",
++    "powerpc:e5500",
++    3,
++    FALSE, /* not the default */
++    powerpc_compatible,
++    bfd_default_scan,
+     0
+   }
+ };
+diff -r -u binutils-2.21-20110211-orig/gas/config/tc-ppc.c binutils-2.21-20110211/gas/config/tc-ppc.c
+--- binutils-2.21-20110211-orig/gas/config/tc-ppc.c    2011-02-11 10:58:01.000000000 -0600
++++ binutils-2.21-20110211/gas/config/tc-ppc.c 2011-02-14 13:23:39.478340515 -0600
+@@ -1235,6 +1235,7 @@
+ -me500, -me500x2        generate code for Motorola e500 core complex\n\
+ -me500mc,               generate code for Freescale e500mc core complex\n\
+ -me500mc64,             generate code for Freescale e500mc64 core complex\n\
++-me5500,                generate code for Freescale e5500 core complex\n\
+ -mspe                   generate code for Motorola SPE instructions\n\
+ -mtitan                 generate code for AppliedMicro Titan core complex\n\
+ -mregnames              Allow symbolic names for registers\n\
+diff -r -u binutils-2.21-20110211-orig/gas/doc/as.texinfo binutils-2.21-20110211/gas/doc/as.texinfo
+--- binutils-2.21-20110211-orig/gas/doc/as.texinfo     2011-02-11 10:58:01.000000000 -0600
++++ binutils-2.21-20110211/gas/doc/as.texinfo  2011-02-14 13:26:01.383403323 -0600
+@@ -431,7 +431,7 @@
+    [@b{-a32}|@b{-a64}]
+    [@b{-mpwrx}|@b{-mpwr2}|@b{-mpwr}|@b{-m601}|@b{-mppc}|@b{-mppc32}|@b{-m603}|@b{-m604}|@b{-m403}|@b{-m405}|
+     @b{-m440}|@b{-m464}|@b{-m476}|@b{-m7400}|@b{-m7410}|@b{-m7450}|@b{-m7455}|@b{-m750cl}|@b{-mppc64}|
+-    @b{-m620}|@b{-me500}|@b{-e500x2}|@b{-me500mc}|@b{-me500mc64}|@b{-mppc64bridge}|@b{-mbooke}|
++    @b{-m620}|@b{-me500}|@b{-e500x2}|@b{-me500mc}|@b{-me500mc64}|@b{-me5500}|@b{-mppc64bridge}|@b{-mbooke}|
+     @b{-mpower4}|@b{-mpr4}|@b{-mpower5}|@b{-mpwr5}|@b{-mpwr5x}|@b{-mpower6}|@b{-mpwr6}|
+     @b{-mpower7}|@b{-mpw7}|@b{-ma2}|@b{-mcell}|@b{-mspe}|@b{-mtitan}|@b{-me300}|@b{-mcom}]
+    [@b{-many}] [@b{-maltivec}|@b{-mvsx}]
+diff -r -u binutils-2.21-20110211-orig/gas/doc/c-ppc.texi binutils-2.21-20110211/gas/doc/c-ppc.texi
+--- binutils-2.21-20110211-orig/gas/doc/c-ppc.texi     2011-02-11 10:58:04.000000000 -0600
++++ binutils-2.21-20110211/gas/doc/c-ppc.texi  2011-02-14 13:26:31.140090956 -0600
+@@ -88,6 +88,9 @@
+ @item -me500mc64
+ Generate code for Freescale e500mc64 core complex.
++@item -me5500
++Generate code for Freescale e5500 core complex.
++
+ @item -mspe
+ Generate code for Motorola SPE instructions.
+diff -r -u binutils-2.21-20110211-orig/opcodes/ppc-dis.c binutils-2.21-20110211/opcodes/ppc-dis.c
+--- binutils-2.21-20110211-orig/opcodes/ppc-dis.c      2010-07-03 03:27:23.000000000 -0500
++++ binutils-2.21-20110211/opcodes/ppc-dis.c   2011-02-14 13:28:54.384090879 -0600
+@@ -114,6 +114,12 @@
+               | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
+               | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
+     0 },
++  { "e5500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
++              | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
++              | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
++              | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
++              | PPC_OPCODE_POWER7),
++    0 },
+   { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+               | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+               | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
diff --git a/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e6500-2.patch b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e6500-2.patch
new file mode 100644 (file)
index 0000000..e863323
--- /dev/null
@@ -0,0 +1,674 @@
+bin.e6500-2
+Implements target e6500 and -me6500, etc..
+
+Also enables some cell instructions but using different opcodes. (This
+should be temporary until new mnemonics are chosen. Likely to be
+defined only when ISA 2.07 comes out)
+
+Also implements new altivec instructions, and a few other e6500
+instructions like miso, and sync with two arguments.
+
+diff -ruN binutils-2.21-20110211-e5500/bfd/archures.c binutils-2.21-20110211-e6500/bfd/archures.c
+--- binutils-2.21-20110211-e5500/bfd/archures.c        2011-05-03 16:04:03.828069461 -0500
++++ binutils-2.21-20110211-e6500/bfd/archures.c        2011-05-03 16:04:15.253938636 -0500
+@@ -235,6 +235,7 @@
+ .#define bfd_mach_ppc_e500mc    5001
+ .#define bfd_mach_ppc_e500mc64  5005
+ .#define bfd_mach_ppc_e5500     5006
++.#define bfd_mach_ppc_e6500     5007
+ .#define bfd_mach_ppc_titan     83
+ .  bfd_arch_rs6000,    {* IBM RS/6000 *}
+ .#define bfd_mach_rs6k                6000
+diff -ruN binutils-2.21-20110211-e5500/bfd/bfd-in2.h binutils-2.21-20110211-e6500/bfd/bfd-in2.h
+--- binutils-2.21-20110211-e5500/bfd/bfd-in2.h 2011-05-03 16:04:03.836064584 -0500
++++ binutils-2.21-20110211-e6500/bfd/bfd-in2.h 2011-05-03 16:04:15.260938268 -0500
+@@ -1922,6 +1922,7 @@
+ #define bfd_mach_ppc_e500mc    5001
+ #define bfd_mach_ppc_e500mc64  5005
+ #define bfd_mach_ppc_e5500     5006
++#define bfd_mach_ppc_e6500     5007
+ #define bfd_mach_ppc_titan     83
+   bfd_arch_rs6000,    /* IBM RS/6000 */
+ #define bfd_mach_rs6k          6000
+diff -ruN binutils-2.21-20110211-e5500/bfd/cpu-powerpc.c binutils-2.21-20110211-e6500/bfd/cpu-powerpc.c
+--- binutils-2.21-20110211-e5500/bfd/cpu-powerpc.c     2011-05-03 16:04:03.839066505 -0500
++++ binutils-2.21-20110211-e6500/bfd/cpu-powerpc.c     2011-05-03 16:04:15.272066052 -0500
+@@ -366,6 +366,20 @@
+     FALSE, /* not the default */
+     powerpc_compatible,
+     bfd_default_scan,
++    &bfd_powerpc_archs[20]
++  },
++  {
++    64, /* 64 bits in a word */
++    64, /* 64 bits in an address */
++    8,  /* 8 bits in a byte */
++    bfd_arch_powerpc,
++    bfd_mach_ppc_e6500,
++    "powerpc",
++    "powerpc:e6500",
++    3,
++    FALSE, /* not the default */
++    powerpc_compatible,
++    bfd_default_scan,
+     0
+   }
+ };
+diff -ruN binutils-2.21-20110211-e5500/gas/config/tc-ppc.c binutils-2.21-20110211-e6500/gas/config/tc-ppc.c
+--- binutils-2.21-20110211-e5500/gas/config/tc-ppc.c   2011-05-03 16:04:03.847063157 -0500
++++ binutils-2.21-20110211-e6500/gas/config/tc-ppc.c   2011-05-03 16:04:15.279062744 -0500
+@@ -1236,6 +1236,7 @@
+ -me500mc,               generate code for Freescale e500mc core complex\n\
+ -me500mc64,             generate code for Freescale e500mc64 core complex\n\
+ -me5500,                generate code for Freescale e5500 core complex\n\
++-me6500,                generate code for Freescale e6500 core complex\n\
+ -mspe                   generate code for Motorola SPE instructions\n\
+ -mtitan                 generate code for AppliedMicro Titan core complex\n\
+ -mregnames              Allow symbolic names for registers\n\
+diff -ruN binutils-2.21-20110211-e5500/gas/doc/as.texinfo binutils-2.21-20110211-e6500/gas/doc/as.texinfo
+--- binutils-2.21-20110211-e5500/gas/doc/as.texinfo    2011-05-03 16:04:03.857062970 -0500
++++ binutils-2.21-20110211-e6500/gas/doc/as.texinfo    2011-05-03 16:04:15.289062767 -0500
+@@ -431,8 +431,8 @@
+    [@b{-a32}|@b{-a64}]
+    [@b{-mpwrx}|@b{-mpwr2}|@b{-mpwr}|@b{-m601}|@b{-mppc}|@b{-mppc32}|@b{-m603}|@b{-m604}|@b{-m403}|@b{-m405}|
+     @b{-m440}|@b{-m464}|@b{-m476}|@b{-m7400}|@b{-m7410}|@b{-m7450}|@b{-m7455}|@b{-m750cl}|@b{-mppc64}|
+-    @b{-m620}|@b{-me500}|@b{-e500x2}|@b{-me500mc}|@b{-me500mc64}|@b{-me5500}|@b{-mppc64bridge}|@b{-mbooke}|
+-    @b{-mpower4}|@b{-mpr4}|@b{-mpower5}|@b{-mpwr5}|@b{-mpwr5x}|@b{-mpower6}|@b{-mpwr6}|
++    @b{-m620}|@b{-me500}|@b{-e500x2}|@b{-me500mc}|@b{-me500mc64}|@b{-me5500}|@b{-me6500}|@b{-mppc64bridge}|
++    @b{-mbooke}|@b{-mpower4}|@b{-mpr4}|@b{-mpower5}|@b{-mpwr5}|@b{-mpwr5x}|@b{-mpower6}|@b{-mpwr6}|
+     @b{-mpower7}|@b{-mpw7}|@b{-ma2}|@b{-mcell}|@b{-mspe}|@b{-mtitan}|@b{-me300}|@b{-mcom}]
+    [@b{-many}] [@b{-maltivec}|@b{-mvsx}]
+    [@b{-mregnames}|@b{-mno-regnames}]
+diff -ruN binutils-2.21-20110211-e5500/gas/doc/c-ppc.texi binutils-2.21-20110211-e6500/gas/doc/c-ppc.texi
+--- binutils-2.21-20110211-e5500/gas/doc/c-ppc.texi    2011-05-03 16:04:03.859065711 -0500
++++ binutils-2.21-20110211-e6500/gas/doc/c-ppc.texi    2011-05-03 16:04:15.291064458 -0500
+@@ -91,6 +91,9 @@
+ @item -me5500
+ Generate code for Freescale e5500 core complex.
++@item -me6500
++Generate code for Freescale e6500 core complex.
++
+ @item -mspe
+ Generate code for Motorola SPE instructions.
+diff -ruN binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/e6500.d binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/e6500.d
+--- binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/e6500.d 1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/e6500.d 2011-05-03 17:04:13.611815418 -0500
+@@ -0,0 +1,75 @@
++#as: -mppc -me6500
++#objdump: -dr -Me6500
++#name: Power E6500 tests
++
++.*: +file format elf(32)?(64)?-powerpc.*
++
++Disassembly of section \.text:
++
++0+00 <start>:
++   0: 10 01 10 c0     vabsdub v0,v1,v2
++   4: 10 01 11 00     vabsduh v0,v1,v2
++   8: 10 01 11 40     vabsduw v0,v1,v2
++   c: 7c 01 10 dc     mvidsplt v0,r1,r2
++  10: 7c 01 11 1c     mviwsplt v0,r1,r2
++  14: 7c 00 12 0a     lvexbx  v0,0,r2
++  18: 7c 01 12 0a     lvexbx  v0,r1,r2
++  1c: 7c 00 12 4a     lvexhx  v0,0,r2
++  20: 7c 01 12 4a     lvexhx  v0,r1,r2
++  24: 7c 00 12 8a     lvexwx  v0,0,r2
++  28: 7c 01 12 8a     lvexwx  v0,r1,r2
++  2c: 7c 00 13 0a     stvexbx v0,0,r2
++  30: 7c 01 13 0a     stvexbx v0,r1,r2
++  34: 7c 00 13 4a     stvexhx v0,0,r2
++  38: 7c 01 13 4a     stvexhx v0,r1,r2
++  3c: 7c 00 13 8a     stvexwx v0,0,r2
++  40: 7c 01 13 8a     stvexwx v0,r1,r2
++  44: 7c 00 12 4e     lvepx   v0,0,r2
++  48: 7c 01 12 4e     lvepx   v0,r1,r2
++  4c: 7c 00 12 0e     lvepxl  v0,0,r2
++  50: 7c 01 12 0e     lvepxl  v0,r1,r2
++  54: 7c 00 16 4e     stvepx  v0,0,r2
++  58: 7c 01 16 4e     stvepx  v0,r1,r2
++  5c: 7c 00 16 0e     stvepxl v0,0,r2
++  60: 7c 01 16 0e     stvepxl v0,r1,r2
++  64: 7c 00 14 8a     lvlx    v0,0,r2
++  68: 7c 01 14 8a     lvlx    v0,r1,r2
++  6c: 7c 00 16 8a     lvlxl   v0,0,r2
++  70: 7c 01 16 8a     lvlxl   v0,r1,r2
++  74: 7c 00 14 4a     lvrx    v0,0,r2
++  78: 7c 01 14 4a     lvrx    v0,r1,r2
++  7c: 7c 00 16 4a     lvrxl   v0,0,r2
++  80: 7c 01 16 4a     lvrxl   v0,r1,r2
++  84: 7c 00 15 8a     stvlx   v0,0,r2
++  88: 7c 01 15 8a     stvlx   v0,r1,r2
++  8c: 7c 00 17 8a     stvlxl  v0,0,r2
++  90: 7c 01 17 8a     stvlxl  v0,r1,r2
++  94: 7c 00 15 4a     stvrx   v0,0,r2
++  98: 7c 01 15 4a     stvrx   v0,r1,r2
++  9c: 7c 00 17 4a     stvrxl  v0,0,r2
++  a0: 7c 01 17 4a     stvrxl  v0,r1,r2
++  a4: 7c 00 14 ca     lvswx   v0,0,r2
++  a8: 7c 01 14 ca     lvswx   v0,r1,r2
++  ac: 7c 00 16 ca     lvswxl  v0,0,r2
++  b0: 7c 01 16 ca     lvswxl  v0,r1,r2
++  b4: 7c 00 15 ca     stvswx  v0,0,r2
++  b8: 7c 01 15 ca     stvswx  v0,r1,r2
++  bc: 7c 00 17 ca     stvswxl v0,0,r2
++  c0: 7c 01 17 ca     stvswxl v0,r1,r2
++  c4: 7c 00 16 0a     lvsm    v0,0,r2
++  c8: 7c 01 16 0a     lvsm    v0,r1,r2
++  cc: 7f 5a d3 78     miso
++  d0: 7c 00 04 ac     sync    
++  d4: 7c 00 04 ac     sync    
++  d8: 7c 20 04 ac     lwsync
++  dc: 7c 00 04 ac     sync    
++  e0: 7c 07 04 ac     sync    0,7
++  e4: 7c 28 04 ac     sync    1,8
++  e8: 7c 00 00 c3     dni     0,0
++  ec: 7f ff 00 c3     dni     31,31
++  f0: 7c 40 0b 4d     dcblq.  2,0,r1
++  f4: 7c 43 0b 4d     dcblq.  2,r3,r1
++  f8: 7c 40 09 8d     icblq.  2,0,r1
++  fc: 7c 43 09 8d     icblq.  2,r3,r1
++ 100: 7c 10 02 dc     mftmr   r0,16
++ 104: 7c 10 03 dc     mttmr   16,r0
+diff -ruN binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/e6500.s binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/e6500.s
+--- binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/e6500.s 1969-12-31 18:00:00.000000000 -0600
++++ binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/e6500.s 2011-05-03 16:35:30.724819687 -0500
+@@ -0,0 +1,69 @@
++# Power E6500 tests
++      .section ".text"
++start:
++      vabsdub 0, 1, 2
++      vabsduh 0, 1, 2
++      vabsduw 0, 1, 2
++      mvidsplt 0, 1, 2
++      mviwsplt 0, 1, 2
++      lvexbx  0, 0, 2
++      lvexbx  0, 1, 2
++      lvexhx  0, 0, 2
++      lvexhx  0, 1, 2
++      lvexwx  0, 0, 2
++      lvexwx  0, 1, 2
++      stvexbx 0, 0, 2
++      stvexbx 0, 1, 2
++      stvexhx 0, 0, 2
++      stvexhx 0, 1, 2
++      stvexwx 0, 0, 2
++      stvexwx 0, 1, 2
++      lvepx   0, 0, 2
++      lvepx   0, 1, 2
++      lvepxl  0, 0, 2
++      lvepxl  0, 1, 2
++      stvepx  0, 0, 2
++      stvepx  0, 1, 2
++      stvepxl 0, 0, 2
++      stvepxl 0, 1, 2
++      lvlx    0, 0, 2
++      lvlx    0, 1, 2
++      lvlxl   0, 0, 2
++      lvlxl   0, 1, 2
++      lvrx    0, 0, 2
++      lvrx    0, 1, 2
++      lvrxl   0, 0, 2
++      lvrxl   0, 1, 2
++      stvlx   0, 0, 2
++      stvlx   0, 1, 2
++      stvlxl  0, 0, 2
++      stvlxl  0, 1, 2
++      stvrx   0, 0, 2
++      stvrx   0, 1, 2
++      stvrxl  0, 0, 2
++      stvrxl  0, 1, 2
++      lvswx   0, 0, 2
++      lvswx   0, 1, 2
++      lvswxl  0, 0, 2
++      lvswxl  0, 1, 2
++      stvswx  0, 0, 2
++      stvswx  0, 1, 2
++      stvswxl 0, 0, 2
++      stvswxl 0, 1, 2
++      lvsm    0, 0, 2
++      lvsm    0, 1, 2
++      miso
++      sync
++      sync    0,0
++      sync    1,0
++      sync    2,0
++      sync    3,7
++      sync    3,8
++      dni     0,0
++      dni     31,31
++      dcblq.  2,0,1
++      dcblq.  2,3,1
++      icblq.  2,0,1
++      icblq.  2,3,1
++      mftmr   0,16
++      mttmr   16,0
+diff -ruN binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/ppc.exp binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/ppc.exp
+--- binutils-2.21-20110211-e5500/gas/testsuite/gas/ppc/ppc.exp 2010-02-07 19:59:38.000000000 -0600
++++ binutils-2.21-20110211-e6500/gas/testsuite/gas/ppc/ppc.exp 2011-05-03 16:04:15.297067070 -0500
+@@ -42,6 +42,7 @@
+       run_list_test "range" "-a32"
+       run_dump_test "ppc750ps"
+       run_dump_test "e500mc"
++      run_dump_test "e6500"
+       run_dump_test "a2"
+       run_dump_test "cell"
+       run_dump_test "common"
+diff -ruN binutils-2.21-20110211-e5500/include/opcode/ppc.h binutils-2.21-20110211-e6500/include/opcode/ppc.h
+--- binutils-2.21-20110211-e5500/include/opcode/ppc.h  2010-07-03 01:51:53.000000000 -0500
++++ binutils-2.21-20110211-e6500/include/opcode/ppc.h  2011-05-03 16:04:15.298069340 -0500
+@@ -174,6 +174,15 @@
+ /* Opcode which is supported by the e500 family */
+ #define PPC_OPCODE_E500              0x100000000ull
++/* Opcode is supported by Extended Altivec Vector Unit */
++#define PPC_OPCODE_ALTIVEC2    0x200000000ull
++
++/* Opcode is supported by Power E6500 */
++#define PPC_OPCODE_E6500       0x400000000ull
++
++/* Opcode is supported by Thread management APU */
++#define PPC_OPCODE_TMR         0x800000000ull
++
+ /* A macro to extract the major opcode from an instruction.  */
+ #define PPC_OP(i) (((i) >> 26) & 0x3f)
\f
+diff -ruN binutils-2.21-20110211-e5500/opcodes/ppc-dis.c binutils-2.21-20110211-e6500/opcodes/ppc-dis.c
+--- binutils-2.21-20110211-e5500/opcodes/ppc-dis.c     2011-05-03 16:04:03.862065832 -0500
++++ binutils-2.21-20110211-e6500/opcodes/ppc-dis.c     2011-05-03 16:04:15.300067851 -0500
+@@ -120,6 +120,12 @@
+               | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+               | PPC_OPCODE_POWER7),
+     0 },
++  { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
++              | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
++              | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
++              | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4
++              | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
++    0 },
+   { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+               | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+               | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+diff -ruN binutils-2.21-20110211-e5500/opcodes/ppc-opc.c binutils-2.21-20110211-e6500/opcodes/ppc-opc.c
+--- binutils-2.21-20110211-e5500/opcodes/ppc-opc.c     2011-02-11 10:58:12.000000000 -0600
++++ binutils-2.21-20110211-e6500/opcodes/ppc-opc.c     2011-05-03 17:22:20.260813917 -0500
+@@ -53,6 +53,7 @@
+ static long extract_boe (unsigned long, ppc_cpu_t, int *);
+ static unsigned long insert_fxm (unsigned long, long, ppc_cpu_t, const char **);
+ static long extract_fxm (unsigned long, ppc_cpu_t, int *);
++static unsigned long insert_ls (unsigned long, long, ppc_cpu_t, const char **);
+ static unsigned long insert_mbe (unsigned long, long, ppc_cpu_t, const char **);
+ static long extract_mbe (unsigned long, ppc_cpu_t, int *);
+ static unsigned long insert_mb6 (unsigned long, long, ppc_cpu_t, const char **);
+@@ -450,6 +451,7 @@
+      lower 5 bits are stored in the upper 5 and vice- versa.  */
+ #define SPR SISIGNOPT + 1
+ #define PMR SPR
++#define TMR SPR
+ #define SPR_MASK (0x3ff << 11)
+   { 0x3ff, 11, insert_spr, extract_spr, 0 },
+@@ -472,8 +474,12 @@
+ #define T STRM
+   { 0x3, 21, NULL, NULL, 0 },
++  /* The ESYNC field in an X (sync) form instruction.  */
++#define ESYNC STRM + 1
++  { 0xf, 16, insert_ls, NULL, PPC_OPERAND_OPTIONAL },
++
+   /* The SV field in a POWER SC form instruction.  */
+-#define SV STRM + 1
++#define SV ESYNC + 1
+   { 0x3fff, 2, NULL, NULL, 0 },
+   /* The TBR field in an XFX form instruction.  This is like the SPR
+@@ -515,6 +521,7 @@
+   /* The UIMM field in a VX form instruction.  */
+ #define UIMM SIMM + 1
++#define DCTL UIMM
+   { 0x1f, 16, NULL, NULL, 0 },
+   /* The SHB field in a VA form instruction.  */
+@@ -996,6 +1003,32 @@
+   return mask;
+ }
++/* The LS field in a sync instruction that accepts 2 operands
++   Values 2 and 3 are reserved,
++     must be treated as 0 for future compatibility
++   Values 0 and 1 can be accepted, if field ESYNC is zero
++   Otherwise L = complement of ESYNC-bit2 (1<<18) */
++
++static unsigned long
++insert_ls (unsigned long insn,
++         long value,
++         ppc_cpu_t dialect ATTRIBUTE_UNUSED,
++         const char **errmsg ATTRIBUTE_UNUSED)
++{
++  unsigned long ls;
++
++  ls = (insn >> 21) & 0x03;
++  if (value == 0)
++    {
++      if (ls > 1)
++      return insn & ~(0x3 << 21);
++      return insn;
++    }
++  if ((value & 0x2) != 0)
++    return (insn & ~(0x3 << 21)) | ((value & 0xf) << 16);
++  return (insn & ~(0x3 << 21)) | (0x1 << 21) | ((value & 0xf) << 16);
++}
++
+ /* The MB and ME fields in an M form instruction expressed as a single
+    operand which is itself a bitmask.  The extraction function always
+    marks it as invalid, since we never want to recognize an
+@@ -1728,6 +1761,9 @@
+ /* An X form sync instruction with everything filled in except the LS field.  */
+ #define XSYNC_MASK (0xff9fffff)
++/* An X form sync instruction with everything filled in except the L and E fields.  */
++#define XSYNCLE_MASK (0xff90ffff)
++
+ /* An X_MASK, but with the EH bit clear.  */
+ #define XEH_MASK (X_MASK & ~((unsigned long )1))
+@@ -1922,6 +1958,7 @@
+ #define PPC860        PPC
+ #define PPCPS PPC_OPCODE_PPCPS
+ #define PPCVEC        PPC_OPCODE_ALTIVEC
++#define PPCVEC2       PPC_OPCODE_ALTIVEC2
+ #define PPCVSX        PPC_OPCODE_VSX
+ #define POWER PPC_OPCODE_POWER
+ #define POWER2        PPC_OPCODE_POWER | PPC_OPCODE_POWER2
+@@ -1940,6 +1977,7 @@
+ #define PPCEFS        PPC_OPCODE_EFS
+ #define PPCBRLK PPC_OPCODE_BRLOCK
+ #define PPCPMR        PPC_OPCODE_PMR
++#define PPCTMR  PPC_OPCODE_TMR
+ #define PPCCHLK PPC_OPCODE_CACHELCK
+ #define PPCRFMCI      PPC_OPCODE_RFMCI
+ #define E500MC  PPC_OPCODE_E500MC
+@@ -1947,6 +1985,7 @@
+ #define TITAN   PPC_OPCODE_TITAN  
+ #define MULHW   PPC_OPCODE_405 | PPC_OPCODE_440 | TITAN
+ #define E500  PPC_OPCODE_E500
++#define E6500 PPC_OPCODE_E6500
\f
+ /* The opcode table.
+@@ -2112,12 +2151,14 @@
+ {"machhwsu",  XO (4,  76,0,0),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"machhwsu.", XO (4,  76,0,1),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"ps_cmpo1",  X  (4,  96), X_MASK|(3<<21), PPCPS,     PPCNONE,        {BF, FRA, FRB}},
++{"vabsdub",   VX (4, 192),    VX_MASK,     PPCVEC2,   PPCNONE,        {VD, VA, VB}},
+ {"vcmpeqfp",  VXR(4, 198,0),  VXR_MASK,    PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"vpkuwus",   VX (4, 206),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"machhws",   XO (4, 108,0,0),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"machhws.",  XO (4, 108,0,1),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"nmachhws",  XO (4, 110,0,0),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"nmachhws.", XO (4, 110,0,1),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
++{"vabsduh",   VX (4, 256),    VX_MASK,     PPCVEC2,   PPCNONE,        {VD, VA, VB}},
+ {"vmaxsb",    VX (4, 258),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"vslb",      VX (4, 260),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"vmulosb",   VX (4, 264),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+@@ -2130,6 +2171,7 @@
+ {"mulchwu.",  XRC(4, 136,1),  X_MASK,      MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"macchwu",   XO (4, 140,0,0),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
+ {"macchwu.",  XO (4, 140,0,1),XO_MASK,     MULHW,     PPCNONE,        {RT, RA, RB}},
++{"vabsduw",   VX (4, 320),    VX_MASK,     PPCVEC2,   PPCNONE,        {VD, VA, VB}},
+ {"vmaxsh",    VX (4, 322),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"vslh",      VX (4, 324),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+ {"vmulosh",   VX (4, 328),    VX_MASK,     PPCVEC,    PPCNONE,        {VD, VA, VB}},
+@@ -3613,6 +3655,8 @@
+ {"lbepx",     X(31,95),       X_MASK,   E500MC|PPCA2, PPCNONE,        {RT, RA, RB}},
++{"dni",               XRC(31,97,1),   XRB_MASK,    E6500,     PPCNONE,        {DUI, DCTL}},
++
+ {"lvx",               X(31,103),      X_MASK,      PPCVEC,    PPCNONE,        {VD, RA, RB}},
+ {"lqfcmx",    APU(31,103,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+@@ -3622,6 +3666,8 @@
+ {"mul",               XO(31,107,0,0), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+ {"mul.",      XO(31,107,0,1), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
++{"mvidsplt",  X(31,110),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA, RB}},
++
+ {"mtsrdin",   X(31,114),      XRA_MASK,    PPC64,     PPCNONE,        {RS, RB}},
+ {"lharx",     X(31,116),      XEH_MASK,    POWER7,    PPCNONE,        {RT, RA0, RB, EH}},
+@@ -3656,6 +3702,8 @@
+ {"adde.",     XO(31,138,0,1), XO_MASK,     PPCCOM,    PPCNONE,        {RT, RA, RB}},
+ {"ae.",               XO(31,138,0,1), XO_MASK,     PWRCOM,    PPCNONE,        {RT, RA, RB}},
++{"mviwsplt",  X(31,142),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA, RB}},
++
+ {"dcbtstlse", X(31,142),      X_MASK,      PPCCHLK,   PPCNONE,        {CT, RA, RB}},
+ {"mtcr",      XFXM(31,144,0xff,0), XRARB_MASK, COM,   PPCNONE,        {RS}},
+@@ -3711,6 +3759,8 @@
+ {"prtyd",     X(31,186),      XRB_MASK, POWER6|PPCA2, PPCNONE,        {RA, RS}},
++{"icblq.",    XRC(31,198,1),  X_MASK,      E6500,     PPCNONE,        {CT, RA0, RB}},
++
+ {"stvewx",    X(31,199),      X_MASK,      PPCVEC,    PPCNONE,        {VS, RA, RB}},
+ {"stwfcmx",   APU(31,199,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+@@ -3788,8 +3838,12 @@
+ {"mfdcrx",    X(31,259),      X_MASK, BOOKE|PPCA2|PPC476, TITAN,      {RS, RA}},
+ {"mfdcrx.",   XRC(31,259,1),  X_MASK,      PPCA2,     PPCNONE,        {RS, RA}},
++{"lvexbx",    X(31,261),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"icbt",      X(31,262),      XRT_MASK,    PPC403,    PPCNONE,        {RA, RB}},
++{"lvepxl",    X(31,263),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"ldfcmx",    APU(31,263,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+ {"doz",               XO(31,264,0,0), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+ {"doz.",      XO(31,264,0,1), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+@@ -3823,6 +3877,9 @@
+ {"mfdcrux",   X(31,291),      X_MASK,      PPC464,    PPCNONE,        {RS, RA}},
++{"lvexhx",    X(31,293),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++{"lvepx",     X(31,295),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"tlbie",     X(31,306),      XRTLRA_MASK, PPC,       TITAN,          {RB, L}},
+ {"tlbi",      X(31,306),      XRT_MASK,    POWER,     PPCNONE,        {RA0, RB}},
+@@ -3874,6 +3931,8 @@
+ {"mfdcr",     X(31,323), X_MASK, PPC403|BOOKE|PPCA2|PPC476, TITAN,    {RT, SPR}},
+ {"mfdcr.",    XRC(31,323,1),  X_MASK,      PPCA2,     PPCNONE,        {RT, SPR}},
++{"lvexwx",    X(31,325),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"dcread",    X(31,326),      X_MASK,  PPC476|TITAN,  PPCNONE,        {RT, RA, RB}},
+ {"div",               XO(31,331,0,0), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+@@ -3882,6 +3941,7 @@
+ {"lxvdsx",    X(31,332),      XX1_MASK,    PPCVSX,    PPCNONE,        {XT6, RA, RB}},
+ {"mfpmr",     X(31,334),      X_MASK, PPCPMR|PPCE300, PPCNONE,        {RT, PMR}},
++{"mftmr",     X(31,366),      X_MASK, PPCTMR|E6500,   PPCNONE,        {RT, TMR}},
+ {"mfmq",      XSPR(31,339,  0), XSPR_MASK, M601,      PPCNONE,        {RT}},
+ {"mfxer",     XSPR(31,339,  1), XSPR_MASK, COM,       PPCNONE,        {RT}},
+@@ -4112,6 +4172,8 @@
+ {"mtdcrx",    X(31,387),      X_MASK, BOOKE|PPCA2|PPC476, TITAN,      {RA, RS}},
+ {"mtdcrx.",   XRC(31,387,1),  X_MASK,      PPCA2,     PPCNONE,        {RA, RS}},
++{"stvexbx",   X(31,389),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"dcblc",     X(31,390),      X_MASK, PPCCHLK|PPC476|TITAN, PPCNONE,  {CT, RA, RB}},
+ {"stdfcmx",   APU(31,391,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+@@ -4136,6 +4198,10 @@
+ {"mtdcrux",   X(31,419),      X_MASK,      PPC464,    PPCNONE,        {RA, RS}},
++{"stvexhx",   X(31,421),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
++{"dcblq.",    XRC(31,422,1),  X_MASK,      E6500,     PPCNONE,        {CT, RA0, RB}},
++
+ {"divde",     XO(31,425,0,0), XO_MASK,  POWER7|PPCA2, PPCNONE,        {RT, RA, RB}},
+ {"divde.",    XO(31,425,0,1), XO_MASK,  POWER7|PPCA2, PPCNONE,        {RT, RA, RB}},
+ {"divwe",     XO(31,427,0,0), XO_MASK,  POWER7|PPCA2, PPCNONE,        {RT, RA, RB}},
+@@ -4149,6 +4215,8 @@
+ {"mdors",     0x7f9ce378,     0xffffffff,  E500MC,    PPCNONE,        {0}},
++{"miso",      0x7f5ad378,     0xffffffff,  E6500,     PPCNONE,        {0}},
++
+ {"mr",                XRC(31,444,0),  X_MASK,      COM,       PPCNONE,        {RA, RS, RBS}},
+ {"or",                XRC(31,444,0),  X_MASK,      COM,       PPCNONE,        {RA, RS, RB}},
+ {"mr.",               XRC(31,444,1),  X_MASK,      COM,       PPCNONE,        {RA, RS, RBS}},
+@@ -4191,6 +4259,8 @@
+ {"mtdcr",     X(31,451), X_MASK, PPC403|BOOKE|PPCA2|PPC476, TITAN,    {SPR, RS}},
+ {"mtdcr.",    XRC(31,451,1), X_MASK,       PPCA2,     PPCNONE,        {SPR, RS}},
++{"stvexwx",   X(31,453),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"dccci",     X(31,454), XRT_MASK, PPC403|PPC440|TITAN|PPCA2, PPCNONE, {RAOPT, RBOPT}},
+ {"dci",               X(31,454),      XRARB_MASK, PPCA2|PPC476, PPCNONE,      {CT}},
+@@ -4201,6 +4271,7 @@
+ {"divwu.",    XO(31,459,0,1), XO_MASK,     PPC,       PPCNONE,        {RT, RA, RB}},
+ {"mtpmr",     X(31,462),      X_MASK, PPCPMR|PPCE300, PPCNONE,        {PMR, RS}},
++{"mttmr",     X(31,494),      X_MASK, PPCTMR|E6500,   PPCNONE,        {TMR, RS}},
+ {"mtmq",      XSPR(31,467,  0), XSPR_MASK, M601,      PPCNONE,        {RS}},
+ {"mtxer",     XSPR(31,467,  1), XSPR_MASK, COM,       PPCNONE,        {RS}},
+@@ -4445,6 +4516,8 @@
+ {"lhdx",      X(31,547),      X_MASK,      E500MC,    PPCNONE,        {RT, RA, RB}},
++{"lvrx",      X(31,549),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"bbelr",     X(31,550),      X_MASK,      PPCBRLK,   PPCNONE,        {0}},
+ {"lvrx",      X(31,551),      X_MASK,      CELL,      PPCNONE,        {VD, RA0, RB}},
+@@ -4461,6 +4534,8 @@
+ {"lwdx",      X(31,579),      X_MASK,      E500MC,    PPCNONE,        {RT, RA, RB}},
++{"lvlx",      X(31,581),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"lwfcmux",   APU(31,583,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+ {"lxsdx",     X(31,588),      XX1_MASK,    PPCVSX,    PPCNONE,        {XT6, RA, RB}},
+@@ -4472,9 +4547,10 @@
+ {"lwsync",    XSYNC(31,598,1), 0xffffffff, PPC,       E500,           {0}},
+ {"ptesync",   XSYNC(31,598,2), 0xffffffff, PPC64,     PPCNONE,        {0}},
++{"sync",      X(31,598),      XSYNCLE_MASK,E6500,     PPCNONE,        {LS, ESYNC}},
+ {"sync",      X(31,598),      XSYNC_MASK,  PPCCOM,    BOOKE|PPC476,   {LS}},
+ {"msync",     X(31,598),      0xffffffff, BOOKE|PPCA2|PPC476, PPCNONE, {0}},
+-{"sync",      X(31,598),      0xffffffff, BOOKE|PPC476, PPCNONE, {0}},
++{"sync",      X(31,598),      0xffffffff, BOOKE|PPC476, E6500,        {0}},
+ {"lwsync",    X(31,598),      0xffffffff, E500,       PPCNONE,        {0}},
+ {"dcs",               X(31,598),      0xffffffff,  PWRCOM,    PPCNONE,        {0}},
+@@ -4485,6 +4561,8 @@
+ {"lddx",      X(31,611),      X_MASK,      E500MC,    PPCNONE,        {RT, RA, RB}},
++{"lvswx",     X(31,613),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"lqfcmux",   APU(31,615,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+ {"nego",      XO(31,104,1,0), XORB_MASK,   COM,       PPCNONE,        {RT, RA}},
+@@ -4534,6 +4612,8 @@
+ {"sthdx",     X(31,675),      X_MASK,      E500MC,    PPCNONE,        {RS, RA, RB}},
++{"stvrx",     X(31,677),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"stvrx",     X(31,679),      X_MASK,      CELL,      PPCNONE,        {VS, RA0, RB}},
+ {"sthfcmux",  APU(31,679,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+@@ -4546,6 +4626,8 @@
+ {"stwdx",     X(31,707),      X_MASK,      E500MC,    PPCNONE,        {RS, RA, RB}},
++{"stvlx",     X(31,709),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"stwfcmux",  APU(31,711,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+ {"stxsdx",    X(31,716),      XX1_MASK,    PPCVSX,    PPCNONE,        {XS6, RA, RB}},
+@@ -4578,6 +4660,8 @@
+ {"stddx",     X(31,739),      X_MASK,      E500MC,    PPCNONE,        {RS, RA, RB}},
++{"stvswx",    X(31,741),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"stqfcmux",  APU(31,743,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+ {"subfmeo",   XO(31,232,1,0), XORB_MASK,   PPCCOM,    PPCNONE,        {RT, RA}},
+@@ -4606,6 +4690,8 @@
+ {"srliq",     XRC(31,760,0),  X_MASK,      M601,      PPCNONE,        {RA, RS, SH}},
+ {"srliq.",    XRC(31,760,1),  X_MASK,      M601,      PPCNONE,        {RA, RS, SH}},
++{"lvsm",      X(31,773),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++{"stvepxl",   X(31,775),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
+ {"lvlxl",     X(31,775),      X_MASK,      CELL,      PPCNONE,        {VD, RA0, RB}},
+ {"ldfcmux",   APU(31,775,0),  APU_MASK,    PPC405,    PPCNONE,        {FCRT, RA, RB}},
+@@ -4638,6 +4724,8 @@
+ {"lfddx",     X(31,803),      X_MASK,      E500MC,    PPCNONE,        {FRT, RA, RB}},
++{"lvrxl",     X(31,805),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++{"stvepx",    X(31,807),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
+ {"lvrxl",     X(31,807),      X_MASK,      CELL,      PPCNONE,        {VD, RA0, RB}},
+ {"rac",               X(31,818),      X_MASK,      M601,      PPCNONE,        {RT, RA, RB}},
+@@ -4658,6 +4746,8 @@
+ {"sradi",     XS(31,413,0),   XS_MASK,     PPC64,     PPCNONE,        {RA, RS, SH6}},
+ {"sradi.",    XS(31,413,1),   XS_MASK,     PPC64,     PPCNONE,        {RA, RS, SH6}},
++{"lvlxl",     X(31,837),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"divo",      XO(31,331,1,0), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+ {"divo.",     XO(31,331,1,1), XO_MASK,     M601,      PPCNONE,        {RT, RA, RB}},
+@@ -4676,6 +4766,8 @@
+ {"lfiwax",    X(31,855),      X_MASK, POWER6|PPCA2|PPC476, PPCNONE,   {FRT, RA0, RB}},
++{"lvswxl",    X(31,869),      X_MASK,      PPCVEC2,   PPCNONE,        {VD, RA0, RB}},
++
+ {"abso",      XO(31,360,1,0), XORB_MASK,   M601,      PPCNONE,        {RT, RA}},
+ {"abso.",     XO(31,360,1,1), XORB_MASK,   M601,      PPCNONE,        {RT, RA}},
+@@ -4721,6 +4813,8 @@
+ {"stfddx",    X(31,931),      X_MASK,      E500MC,    PPCNONE,        {FRS, RA, RB}},
++{"stvrxl",    X(31,933),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"wclrone",   XOPL2(31,934,2),XRT_MASK,    PPCA2,     PPCNONE,        {RA0, RB}},
+ {"wclrall",   X(31,934),      XRARB_MASK,  PPCA2,     PPCNONE,        {L}},
+ {"wclr",      X(31,934),      X_MASK,      PPCA2,     PPCNONE,        {L, RA0, RB}},
+@@ -4749,6 +4843,8 @@
+ {"extsb",     XRC(31,954,0),  XRB_MASK,    PPC,       PPCNONE,        {RA, RS}},
+ {"extsb.",    XRC(31,954,1),  XRB_MASK,    PPC,       PPCNONE,        {RA, RS}},
++{"stvlxl",    X(31,965),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"iccci",     X(31,966), XRT_MASK, PPC403|PPC440|TITAN|PPCA2, PPCNONE, {RAOPT, RBOPT}},
+ {"ici",               X(31,966),      XRARB_MASK,  PPCA2|PPC476, PPCNONE,     {CT}},
+@@ -4776,6 +4872,8 @@
+ {"icbiep",    XRT(31,991,0),  XRT_MASK, E500MC|PPCA2, PPCNONE,        {RA, RB}},
++{"stvswxl",   X(31,997),      X_MASK,      PPCVEC2,   PPCNONE,        {VS, RA0, RB}},
++
+ {"icread",    X(31,998), XRT_MASK, PPC403|PPC440|PPC476|TITAN, PPCNONE, {RA, RB}},
+ {"nabso",     XO(31,488,1,0), XORB_MASK,   M601,      PPCNONE,        {RT, RA}},
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-fsl.inc b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-fsl.inc
new file mode 100644 (file)
index 0000000..f754011
--- /dev/null
@@ -0,0 +1,14 @@
+SRC_URI = "svn://www.eglibc.org/svn/branches/;module=${EGLIBC_BRANCH};proto=http \
+               file://glibc.undefined_static.patch \
+               file://glibc.fixgcc4.6.patch \
+               file://glibc.readv_proto.patch \
+               file://glibc.fix_sqrt.patch \
+               file://glibc.fix_prof.patch \
+               file://glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch \
+               file://etc/ld.so.conf \
+               file://generate-supported.mk \
+"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR .= "+${DISTRO}.0"
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-initial_2.13.bbappend b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-initial_2.13.bbappend
new file mode 100644 (file)
index 0000000..4f61361
--- /dev/null
@@ -0,0 +1 @@
+require eglibc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-locale_2.13.bbappend b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-locale_2.13.bbappend
new file mode 100644 (file)
index 0000000..4f61361
--- /dev/null
@@ -0,0 +1 @@
+require eglibc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/eglibc_2.13.bbappend b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc_2.13.bbappend
new file mode 100644 (file)
index 0000000..4f61361
--- /dev/null
@@ -0,0 +1 @@
+require eglibc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/etc/ld.so.conf b/meta-fsl-ppc/recipes-devtools/eglibc/files/etc/ld.so.conf
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/generate-supported.mk b/meta-fsl-ppc/recipes-devtools/eglibc/files/generate-supported.mk
new file mode 100644 (file)
index 0000000..d2a28c2
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/make
+
+include $(IN)
+
+all:
+       rm -f $(OUT)
+       touch $(OUT)
+       for locale in $(SUPPORTED-LOCALES); do \
+               [ $$locale = true ] && continue; \
+               echo $$locale | sed 's,/, ,' >> $(OUT); \
+       done
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch
new file mode 100644 (file)
index 0000000..6feb76e
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/configure        2012-03-05 07:00:49.600200254 -0600
++++ b/configure        2012-03-05 07:01:13.249394037 -0600
+@@ -4581,7 +4581,7 @@
+ if test -z "$submachine_used" && test -n "$submachine"; then
+   { { $as_echo "$as_me:$LINENO: error: The $submachine subspecies of $host_cpu is not supported." >&5
+ $as_echo "$as_me: error: The $submachine subspecies of $host_cpu is not supported." >&2;}
+-   { (exit 1); exit 1; }; }
++  }
+ fi
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_prof.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_prof.patch
new file mode 100644 (file)
index 0000000..966e9e3
--- /dev/null
@@ -0,0 +1,38 @@
+diff -ruN libc-orig/elf/dl-runtime.c libc-e5500/elf/dl-runtime.c
+--- libc-orig/elf/dl-runtime.c 2011-12-08 04:25:09.201995061 -0600
++++ libc-e5500/elf/dl-runtime.c        2011-12-08 04:26:12.760996794 -0600
+@@ -156,7 +156,7 @@
+ }
+ #endif
+-#if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
++#if !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
+ DL_FIXUP_VALUE_TYPE
+ __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
+ _dl_profile_fixup (
+@@ -425,7 +425,7 @@
+   return value;
+ }
+-#endif /* PROF && ELF_MACHINE_NO_PLT */
++#endif /* ELF_MACHINE_NO_PLT */
+ #include <stdio.h>
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/dl-trampoline.S libc-e5500/sysdeps/powerpc/powerpc32/dl-trampoline.S
+--- libc-orig/sysdeps/powerpc/powerpc32/dl-trampoline.S        2011-12-08 04:25:12.103998210 -0600
++++ libc-e5500/sysdeps/powerpc/powerpc32/dl-trampoline.S       2011-12-08 04:26:19.310748350 -0600
+@@ -71,7 +71,6 @@
+       cfi_endproc
+       .size    _dl_runtime_resolve,.-_dl_runtime_resolve
+-#ifndef PROF
+       .align 2
+       .globl _dl_prof_resolve
+       .type _dl_prof_resolve,@function
+@@ -183,4 +182,4 @@
+       bctr
+       cfi_endproc
+       .size    _dl_prof_resolve,.-_dl_prof_resolve
+-#endif
++
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_sqrt.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_sqrt.patch
new file mode 100644 (file)
index 0000000..a648b4f
--- /dev/null
@@ -0,0 +1,500 @@
+Implements sqrt with fsqrte.
+Adds functions for 603e (also used for e300c3, e600 and e500mc)
+Adds functions for e5500 in 64 bit mode (also used for e6500)
+
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c libc-e5500/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c      1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrt.c     2011-05-18 13:00:40.423986787 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++      feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c libc-e5500/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c     1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/powerpc/powerpc32/603e/fpu/e_sqrtf.c    2011-05-18 13:00:40.423986787 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++      feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c libc-e5500/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c     1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrt.c    2011-05-18 11:15:22.467987000 -0500
+@@ -0,0 +1,134 @@
++/* Double-precision floating point square root.
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float two108 = 3.245185536584267269e+32;
++static const float twom54 = 5.551115123125782702e-17;
++static const float half = 0.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the actual square root and half of its reciprocal
++   simultaneously.  */
++
++#ifdef __STDC__
++double
++__ieee754_sqrt (double b)
++#else
++double
++__ieee754_sqrt (b)
++     double b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++      double y, g, h, d, r;
++      ieee_double_shape_type u;
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          u.value = b;
++
++          relax_fenv_state ();
++
++          __asm__ ("frsqrte %[estimate], %[x]\n"
++                   : [estimate] "=f" (y) : [x] "f" (b));
++
++          /* Following Muller et al, page 168, equation 5.20.
++
++             h goes to 1/(2*sqrt(b))
++             g goes to sqrt(b).
++
++             We need three iterations to get within 1ulp.  */
++
++          /* Indicate that these can be performed prior to the branch.  GCC
++             insists on sinking them below the branch, however; it seems like
++             they'd be better before the branch so that we can cover any latency
++             from storing the argument and loading its high word.  Oh well.  */
++
++          g = b * y;
++          h = 0.5 * y;
++  
++          /* Handle small numbers by scaling.  */
++          if (__builtin_expect ((u.parts.msw & 0x7ff00000) <= 0x02000000, 0))
++            return __ieee754_sqrt (b * two108) * twom54;
++
++#define FMADD(a_, c_, b_)                                               \
++          ({ double __r;                                                \
++          __asm__ ("fmadd %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++#define FNMSUB(a_, c_, b_)                                          \
++          ({ double __r;                                                \
++          __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                     \
++                   : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++          __r;})
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          r = FNMSUB (g, h, half);
++          g = FMADD (g, r, g);
++          h = FMADD (h, r, h);
++
++          /* g is now +/- 1ulp, or exactly equal to, the square root of b.  */
++
++          /* Final refinement.  */
++          d = FNMSUB (g, g, b);
++
++          fesetenv_register (fe);
++          return FMADD (d, h, g);
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++      feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_wash (b);
++}
+diff -ruN libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c libc-e5500/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c
+--- libc-orig/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c    1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/powerpc/powerpc64/e5500/fpu/e_sqrtf.c   2011-05-18 11:15:22.467987000 -0500
+@@ -0,0 +1,101 @@
++/* Single-precision floating point square root.
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <math.h>
++#include <math_private.h>
++#include <fenv_libc.h>
++#include <inttypes.h>
++
++#include <sysdep.h>
++#include <ldsodefs.h>
++
++static const ieee_float_shape_type a_nan = {.word = 0x7fc00000 };
++static const ieee_float_shape_type a_inf = {.word = 0x7f800000 };
++static const float threehalf = 1.5;
++
++/* The method is based on the descriptions in:
++
++   _The Handbook of Floating-Pointer Arithmetic_ by Muller et al., chapter 5;
++   _IA-64 and Elementary Functions: Speed and Precision_ by Markstein, chapter 9
++
++   We find the reciprocal square root and use that to compute the actual
++   square root.  */
++
++#ifdef __STDC__
++float
++__ieee754_sqrtf (float b)
++#else
++float
++__ieee754_sqrtf (b)
++     float b;
++#endif
++{
++  if (__builtin_expect (b > 0, 1))
++    {
++#define FMSUB(a_, c_, b_)                                               \
++      ({ double __r;                                                    \
++        __asm__ ("fmsub %[r], %[a], %[c], %[b]\n"                       \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++#define FNMSUB(a_, c_, b_)                                              \
++      ({ double __r;                                                    \
++        __asm__ ("fnmsub %[r], %[a], %[c], %[b]\n"                      \
++                 : [r] "=f" (__r) : [a] "f" (a_), [c] "f" (c_), [b] "f" (b_)); \
++        __r;})
++
++      if (__builtin_expect (b != a_inf.value, 1))
++        {
++          double y, x;
++          fenv_t fe;
++
++          fe = fegetenv_register ();
++
++          relax_fenv_state ();
++
++          /* Compute y = 1.5 * b - b.  Uses fewer constants than y = 0.5 * b.  */
++          y = FMSUB (threehalf, b, b);
++
++          /* Initial estimate.  */
++          __asm__ ("frsqrte %[x], %[b]\n" : [x] "=f" (x) : [b] "f" (b));
++
++          /* Iterate.  x_{n+1} = x_n * (1.5 - y * (x_n * x_n)).  */
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++          x = x * FNMSUB (y, x * x, threehalf);
++
++          /* All done.  */
++          fesetenv_register (fe);
++          return x * b;
++        }
++    }
++  else if (b < 0)
++    {
++      /* For some reason, some PowerPC32 processors don't implement
++         FE_INVALID_SQRT.  */
++#ifdef FE_INVALID_SQRT
++      feraiseexcept (FE_INVALID_SQRT);
++
++      fenv_union_t u = { .fenv = fegetenv_register () };
++      if ((u.l[1] & FE_INVALID) == 0)
++#endif
++      feraiseexcept (FE_INVALID);
++      b = a_nan.value;
++    }
++  return f_washf (b);
++}
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies libc-e5500/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies       1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/unix/sysv/linux/powerpc/powerpc32/603e/fpu/Implies      2011-05-18 13:01:33.987988922 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc32/603e/fpu
+diff -ruN libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies libc-e5500/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies
+--- libc-orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies      1969-12-31 18:00:00.000000000 -0600
++++ libc-e5500/sysdeps/unix/sysv/linux/powerpc/powerpc64/e5500/fpu/Implies     2011-05-18 11:15:22.412987000 -0500
+@@ -0,0 +1 @@
++powerpc/powerpc64/e5500/fpu
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fixgcc4.6.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fixgcc4.6.patch
new file mode 100644 (file)
index 0000000..4288769
--- /dev/null
@@ -0,0 +1,29 @@
+glibc.fixgcc4.6
+
+Glibc build scripts relies on information given by "gcc -v --help".
+With gcc-4.6 and latter, this information is not printed with "--help"
+anymore, but with "--target-help". This patch should be used until
+glibs sources catches up with gcc.
+
+--- libc/configure.in-orig     2010-06-07 11:11:01.000000000 -0500
++++ libc/configure.in  2010-06-07 11:11:28.000000000 -0500
+@@ -1620,7 +1620,7 @@
+       AC_CACHE_CHECK(for -z relro option,
+                    libc_cv_z_relro, [dnl
+   libc_cv_z_relro=no
+-  if AC_TRY_COMMAND([${CC-cc} -v --help 2>&1|grep "z relro" 1>&AS_MESSAGE_LOG_FD])
++  if AC_TRY_COMMAND([${CC-cc} -v --target-help 2>&1|grep "z relro" 1>&AS_MESSAGE_LOG_FD])
+   then
+     if AC_TRY_COMMAND([${CC-cc} -Wl,--verbose 2>&1|grep DATA_SEGMENT_RELRO_END 1>&AS_MESSAGE_LOG_FD])
+     then
+--- libc/configure-orig        2010-06-07 11:11:13.000000000 -0500
++++ libc/configure     2010-06-07 11:12:00.000000000 -0500
+@@ -6670,7 +6670,7 @@
+   $as_echo_n "(cached) " >&6
+ else
+     libc_cv_z_relro=no
+-  if { ac_try='${CC-cc} -v --help 2>&1|grep "z relro" 1>&5'
++  if { ac_try='${CC-cc} -v --target-help 2>&1|grep "z relro" 1>&5'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.readv_proto.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.readv_proto.patch
new file mode 100644 (file)
index 0000000..fbeee69
--- /dev/null
@@ -0,0 +1,99 @@
+glibc.readv_proto
+
+Unfortunate choice of variable names. Causes syntax errors on Altivec
+enabled targets.
+
+diff -u libc-orig/sysdeps/unix/sysv/linux/readv.c libc/sysdeps/unix/sysv/linux/readv.c
+--- libc-orig/sysdeps/unix/sysv/linux/readv.c  2011-05-11 11:01:36.625600000 -0500
++++ libc/sysdeps/unix/sysv/linux/readv.c       2011-05-11 11:03:19.443599768 -0500
+@@ -40,20 +40,20 @@
+ ssize_t
+-__libc_readv (fd, vector, count)
++__libc_readv (fd, vec_tor, count)
+      int fd;
+-     const struct iovec *vector;
++     const struct iovec *vec_tor;
+      int count;
+ {
+   ssize_t result;
+   if (SINGLE_THREAD_P)
+-    result = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vector, count), count);
++    result = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vec_tor, count), count);
+   else
+     {
+       int oldtype = LIBC_CANCEL_ASYNC ();
+-      result = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vector, count), count);
++      result = INLINE_SYSCALL (readv, 3, fd, CHECK_N (vec_tor, count), count);
+       LIBC_CANCEL_RESET (oldtype);
+     }
+@@ -64,7 +64,7 @@
+   if (result >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
+     return result;
+-  return __atomic_readv_replacement (fd, vector, count);
++  return __atomic_readv_replacement (fd, vec_tor, count);
+ #endif
+ }
+ strong_alias (__libc_readv, __readv)
+diff -u libc-orig/sysdeps/unix/sysv/linux/writev.c libc/sysdeps/unix/sysv/linux/writev.c
+--- libc-orig/sysdeps/unix/sysv/linux/writev.c 2011-05-11 11:01:36.577599548 -0500
++++ libc/sysdeps/unix/sysv/linux/writev.c      2011-05-11 11:03:33.994599785 -0500
+@@ -40,20 +40,20 @@
+ ssize_t
+-__libc_writev (fd, vector, count)
++__libc_writev (fd, vec_tor, count)
+      int fd;
+-     const struct iovec *vector;
++     const struct iovec *vec_tor;
+      int count;
+ {
+   ssize_t result;
+   if (SINGLE_THREAD_P)
+-    result = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector, count), count);
++    result = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vec_tor, count), count);
+   else
+     {
+       int oldtype = LIBC_CANCEL_ASYNC ();
+-      result = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vector, count), count);
++      result = INLINE_SYSCALL (writev, 3, fd, CHECK_N (vec_tor, count), count);
+       LIBC_CANCEL_RESET (oldtype);
+     }
+@@ -64,7 +64,7 @@
+   if (result >= 0 || errno != EINVAL || count <= UIO_FASTIOV)
+     return result;
+-  return __atomic_writev_replacement (fd, vector, count);
++  return __atomic_writev_replacement (fd, vec_tor, count);
+ #endif
+ }
+ strong_alias (__libc_writev, __writev)
+diff -u libc-orig/include/sys/uio.h libc/include/sys/uio.h
+--- libc-orig/include/sys/uio.h        2011-05-11 11:07:53.953602501 -0500
++++ libc/include/sys/uio.h     2011-05-11 11:08:25.117599576 -0500
+@@ -2,12 +2,12 @@
+ #include <misc/sys/uio.h>
+ /* Now define the internal interfaces.  */
+-extern ssize_t __readv (int __fd, __const struct iovec *__vector,
++extern ssize_t __readv (int __fd, __const struct iovec *__vec_tor,
+                       int __count);
+-extern ssize_t __libc_readv (int __fd, __const struct iovec *__vector,
++extern ssize_t __libc_readv (int __fd, __const struct iovec *__vec_tor,
+                            int __count);
+-extern ssize_t __writev (int __fd, __const struct iovec *__vector,
++extern ssize_t __writev (int __fd, __const struct iovec *__vec_tor,
+                        int __count);
+-extern ssize_t __libc_writev (int __fd, __const struct iovec *__vector,
++extern ssize_t __libc_writev (int __fd, __const struct iovec *__vec_tor,
+                             int __count);
+ #endif
diff --git a/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.undefined_static.patch b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.undefined_static.patch
new file mode 100644 (file)
index 0000000..aba5285
--- /dev/null
@@ -0,0 +1,37 @@
+glibc.undefined_static
+
+This works around an old binutils bug, which would delete static
+constants out of the code, thus causing undefined symbols. Not sure if
+this patch is still needed.
+
+diff -rc libc-orig/stdio-common/psiginfo-define.h libc-new/stdio-common/psiginfo-define.h
+*** libc-orig/stdio-common/psiginfo-define.h   2009-04-09 08:12:53.000000000 -0500
+--- libc-new/stdio-common/psiginfo-define.h    2009-04-09 08:20:36.000000000 -0500
+***************
+*** 1,4 ****
+! static const union C(codestrs_t_, NOW) {
+    struct {
+  #define P(n, s) char MF(__LINE__)[sizeof (s)];
+  #include "psiginfo-data.h"
+--- 1,4 ----
+! const union C(codestrs_t_, NOW) {
+    struct {
+  #define P(n, s) char MF(__LINE__)[sizeof (s)];
+  #include "psiginfo-data.h"
+***************
+*** 8,14 ****
+  #define P(n, s) s,
+  #include "psiginfo-data.h"
+    } };
+! static const uint8_t C(codes_, NOW)[] = {
+  #define P(n, s) [(n) - 1] = offsetof (union C(codestrs_t_, NOW), MF(__LINE__)),
+  #include "psiginfo-data.h"
+  };
+--- 8,14 ----
+  #define P(n, s) s,
+  #include "psiginfo-data.h"
+    } };
+! const uint8_t C(codes_, NOW)[] = {
+  #define P(n, s) [(n) - 1] = offsetof (union C(codestrs_t_, NOW), MF(__LINE__)),
+  #include "psiginfo-data.h"
+  };
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.builtin_isel.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.builtin_isel.patch
new file mode 100644 (file)
index 0000000..10e5999
--- /dev/null
@@ -0,0 +1,1059 @@
+diff -ruN gcc-4.6.0-orig/gcc/config/rs6000/rs6000-builtin.def gcc-4.6.0-new/gcc/config/rs6000/rs6000-builtin.def
+--- gcc-4.6.0-orig/gcc/config/rs6000/rs6000-builtin.def        2011-02-21 15:38:21.000000000 -0600
++++ gcc-4.6.0-new/gcc/config/rs6000/rs6000-builtin.def 2011-07-25 12:32:26.626006000 -0500
+@@ -750,6 +750,71 @@
+ RS6000_BUILTIN(SPE_BUILTIN_MFSPEFSCR,                 RS6000_BTC_MISC)
+ RS6000_BUILTIN(SPE_BUILTIN_BRINC,                     RS6000_BTC_MISC)
++/* ISEL builtins.  */
++/* Generic versions that get resolved to specific builtins.  */
++RS6000_BUILTIN(RS6000_BUILTIN_ISELEQ,                  RS6000_BTC_PURE)
++RS6000_BUILTIN_EQUATE(ISEL_BUILTIN_OVERLOADED_FIRST,
++                     RS6000_BUILTIN_ISELEQ)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELGT,                  RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELLT,                  RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELGTU,                 RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELLTU,                 RS6000_BTC_PURE)
++/* Same deal, but for 64-bit comparisons.  */
++RS6000_BUILTIN(RS6000_BUILTIN_ISELEQD,                 RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELGTD,                 RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELLTD,                 RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELGTDU,                        RS6000_BTC_PURE)
++RS6000_BUILTIN(RS6000_BUILTIN_ISELLTDU,                        RS6000_BTC_PURE)
++RS6000_BUILTIN_EQUATE(ISEL_BUILTIN_OVERLOADED_LAST,
++                     RS6000_BUILTIN_ISELLTDU)
++
++/* Each set of arguments is polymorphic in selected arguments and return
++   value.  */
++#undef RS6000_ISEL_BASE
++#define RS6000_ISEL_BASE(ARG, PRED, CMP)                                       \
++  RS6000_BUILTIN(RS6000_BUILTIN_ISEL_##PRED##CMP##_##ARG##_SS, RS6000_BTC_PURE) \
++  RS6000_BUILTIN(RS6000_BUILTIN_ISEL_##PRED##CMP##_##ARG##_PP, RS6000_BTC_PURE) \
++  RS6000_BUILTIN(RS6000_BUILTIN_ISEL_##PRED##CMP##_##ARG##_UU, RS6000_BTC_PURE)
++#undef RS6000_ISEL_PTR_ARG
++#define RS6000_ISEL_PTR_ARG(PRED, CMP) RS6000_ISEL_BASE(PP, PRED, CMP)
++#undef RS6000_ISEL_SIGNED_ARG
++#define RS6000_ISEL_SIGNED_ARG(PRED, CMP) RS6000_ISEL_BASE(SS, PRED, CMP)
++#undef RS6000_ISEL_UNSIGNED_ARG
++#define RS6000_ISEL_UNSIGNED_ARG(PRED, CMP) RS6000_ISEL_BASE(UU, PRED, CMP)
++
++#undef RS6000_ISEL_EQ
++#define RS6000_ISEL_EQ(CMP)                    \
++  RS6000_ISEL_PTR_ARG(EQ, CMP)                 \
++  RS6000_ISEL_SIGNED_ARG(EQ, CMP)              \
++  RS6000_ISEL_UNSIGNED_ARG(EQ, CMP)
++
++#undef RS6000_ISEL_LT
++#define RS6000_ISEL_LT(CMP) RS6000_ISEL_SIGNED_ARG(LT, CMP)
++
++#undef RS6000_ISEL_GT
++#define RS6000_ISEL_GT(CMP) RS6000_ISEL_SIGNED_ARG(GT, CMP)
++
++#undef RS6000_ISEL_LTU
++#define RS6000_ISEL_LTU(CMP)                   \
++  RS6000_ISEL_PTR_ARG(LTU, CMP)                        \
++  RS6000_ISEL_UNSIGNED_ARG(LTU, CMP)
++
++#undef RS6000_ISEL_GTU
++#define RS6000_ISEL_GTU(CMP)                   \
++  RS6000_ISEL_PTR_ARG(GTU, CMP)                        \
++  RS6000_ISEL_UNSIGNED_ARG(GTU, CMP)
++
++RS6000_ISEL_EQ(CMPW)
++RS6000_ISEL_LT(CMPW)
++RS6000_ISEL_GT(CMPW)
++RS6000_ISEL_LTU(CMPW)
++RS6000_ISEL_GTU(CMPW)
++RS6000_ISEL_EQ(CMPD)
++RS6000_ISEL_LT(CMPD)
++RS6000_ISEL_GT(CMPD)
++RS6000_ISEL_LTU(CMPD)
++RS6000_ISEL_GTU(CMPD)
++
+ /* PAIRED builtins.  */
+ RS6000_BUILTIN(PAIRED_BUILTIN_DIVV2SF3,                       RS6000_BTC_MISC)
+ RS6000_BUILTIN(PAIRED_BUILTIN_ABSV2SF2,                       RS6000_BTC_MISC)
+diff -ruN gcc-4.6.0-orig/gcc/config/rs6000/rs6000.c gcc-4.6.0-new/gcc/config/rs6000/rs6000.c
+--- gcc-4.6.0-orig/gcc/config/rs6000/rs6000.c  2011-03-15 07:57:37.000000000 -0500
++++ gcc-4.6.0-new/gcc/config/rs6000/rs6000.c   2011-07-25 13:19:52.415921000 -0500
+@@ -12402,6 +12402,289 @@
+   return target;
+ }
++/* isel builtins are a bit funny, because we want the user to be able to do:
++
++   char *p, *q, *r;
++   int x, y, z;
++   unsigned int a, b, c;
++   ...
++   p = __builtin_iseleq (i, j, q, r);
++   x = __builtin_iseleq (i, j, y, z);
++   a = __builtin_iseleq (i, j, b, c);
++
++   and, of course, i and j may be of several different types depending on the
++   condition.
++
++   We handle this by having generic builtins that
++   TARGET_RESOLVE_OVERLOADED_BUILTIN takes and turns into calls to our
++   specific builtins.  */
++
++/* Macros to help constructing the isel_builtin_desc arrays.
++   These closely mirror the macros in rs6000-builtins.def.  */
++/* HACK: Use VOIDmode here as a constant approximation to Pmode and fix
++   at runtime.  We can't use Pmode because in biarch its definition is
++   not constant.  */
++#define ISEL_Pmode VOIDmode
++#define ISEL_BASE(FLAGS, ARG, RESULT, PRED, CMP, MODE, RMODE)          \
++  { NULL, FLAGS, RS6000_BUILTIN_ISEL_##PRED##CMP##_##ARG##_##RESULT,   \
++      PRED, MODE, RMODE },
++#define ISEL_P_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_PTR, ARG, PP, PRED,         \
++            CMP, MODE, ISEL_Pmode)
++#define ISEL_S_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_SIGNED, ARG, SS, PRED,              \
++            CMP, MODE, RMODE)
++#define ISEL_U_RESULT(FLAGS, ARG, PRED, CMP, MODE, RMODE)              \
++  ISEL_BASE (FLAGS | ISEL_FLAG_SEL_UNSIGNED, ARG, UU, PRED,            \
++            CMP, MODE, RMODE)
++
++#define ISEL_EXPAND_ARG(FLAG, ARG, PRED, CMP, MODE, RMODE)             \
++  ISEL_P_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)            \
++  ISEL_S_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)            \
++  ISEL_U_RESULT (FLAG, ARG, PRED, CMP, MODE, RMODE)
++#define ISEL_PTR_ARG(PRED, CMP, MODE)                          \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_PTR, PP, PRED, CMP, ISEL_Pmode, MODE)
++#define ISEL_SIGNED_ARG(PRED, CMP, MODE)                       \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_SIGNED, SS, PRED, CMP, MODE, MODE)
++#define ISEL_UNSIGNED_ARG(PRED, CMP, MODE)                     \
++  ISEL_EXPAND_ARG (ISEL_FLAG_CMP_UNSIGNED, UU, PRED, CMP, MODE, MODE)
++
++#define ISEL_EQ(CMP, MODE)                                     \
++  ISEL_PTR_ARG (EQ, CMP, MODE)                                 \
++  ISEL_SIGNED_ARG (EQ, CMP, MODE)                              \
++  ISEL_UNSIGNED_ARG (EQ, CMP, MODE)
++#define ISEL_LT(CMP, MODE) ISEL_SIGNED_ARG (LT, CMP, MODE)
++#define ISEL_GT(CMP, MODE) ISEL_SIGNED_ARG (GT, CMP, MODE)
++#define ISEL_LTU(CMP, MODE)                                    \
++  ISEL_PTR_ARG (LTU, CMP, MODE)                                        \
++  ISEL_UNSIGNED_ARG (LTU, CMP, MODE)
++#define ISEL_GTU(CMP, MODE)                                    \
++  ISEL_PTR_ARG (GTU, CMP, MODE)                                        \
++  ISEL_UNSIGNED_ARG (GTU, CMP, MODE)
++
++const struct isel_builtin_desc builtin_iselw[32] = {
++  ISEL_EQ (CMPW, SImode)
++  ISEL_LT (CMPW, SImode)
++  ISEL_GT (CMPW, SImode)
++  ISEL_LTU (CMPW, SImode)
++  ISEL_GTU (CMPW, SImode)
++  { "__builtin_iseleq", 0, RS6000_BUILTIN_ISELEQ, EQ, SImode, SImode },
++  { "__builtin_isellt", 0, RS6000_BUILTIN_ISELLT, LT, SImode, SImode },
++  { "__builtin_iselgt", 0, RS6000_BUILTIN_ISELGT, GT, SImode, SImode },
++  { "__builtin_iselltu", 0, RS6000_BUILTIN_ISELLTU, LTU, SImode, SImode },
++  { "__builtin_iselgtu", 0, RS6000_BUILTIN_ISELGTU, GTU, SImode, SImode }
++};
++
++const struct isel_builtin_desc builtin_iseld[32] = {
++  ISEL_EQ (CMPD, DImode)
++  ISEL_LT (CMPD, DImode)
++  ISEL_GT (CMPD, DImode)
++  ISEL_LTU (CMPD, DImode)
++  ISEL_GTU (CMPD, DImode)
++  { "__builtin_isel64eq", 0, RS6000_BUILTIN_ISELEQD, EQ, DImode, DImode },
++  { "__builtin_isel64lt", 0, RS6000_BUILTIN_ISELLTD, LT, DImode, DImode },
++  { "__builtin_isel64gt", 0, RS6000_BUILTIN_ISELGTD, GT, DImode, DImode },
++  { "__builtin_isel64ltu", 0, RS6000_BUILTIN_ISELLTDU, LTU, DImode, DImode },
++  { "__builtin_isel64gtu", 0, RS6000_BUILTIN_ISELGTDU, GTU, DImode, DImode }
++};
++
++/* Return the mode which DESC uses for comparisons.  */
++
++static enum machine_mode
++isel_cmp_mode (const struct isel_builtin_desc *desc)
++{
++  enum machine_mode mode = (enum machine_mode) desc->cmp_mode;
++
++  return (mode == VOIDmode ? Pmode : mode);
++}
++
++/* Return the mode in which DESC selects arguments.  */
++
++static enum machine_mode
++isel_sel_mode (const struct isel_builtin_desc *desc)
++{
++  enum machine_mode mode = (enum machine_mode) desc->sel_mode;
++
++  return (mode == VOIDmode ? Pmode : mode);
++}
++
++/* Return a tree describing the arguments for DESC according to CMPP:
++   true for comparison arguments, false for select arguments.  */
++
++static tree
++isel_argtype (const struct isel_builtin_desc *desc, bool cmpp)
++{
++  switch (desc->arg_flags & (cmpp
++                            ? ISEL_FLAG_CMP_MASK
++                            : ISEL_FLAG_SEL_MASK))
++    {
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      return ptr_type_node;
++    case ISEL_FLAG_CMP_SIGNED:
++      return (isel_cmp_mode (desc) == SImode
++             ? integer_type_node
++             : long_integer_type_node);
++    case ISEL_FLAG_SEL_SIGNED:
++      return (isel_sel_mode (desc) == SImode
++             ? integer_type_node
++             : long_integer_type_node);
++    case ISEL_FLAG_CMP_UNSIGNED:
++      return (isel_cmp_mode (desc) == SImode
++             ? unsigned_type_node
++             : long_unsigned_type_node);
++    case ISEL_FLAG_SEL_UNSIGNED:
++    default:
++      return (isel_sel_mode (desc) == SImode
++             ? unsigned_type_node
++             : long_unsigned_type_node);
++    }
++}
++
++/* Return a mnemonic string describing the argument or result of FLAGS
++   depending on CMPP.  */
++
++static const char *
++isel_strdesc (int flags, bool cmpp)
++{
++  switch (flags & (cmpp ? ISEL_FLAG_CMP_MASK : ISEL_FLAG_SEL_MASK))
++    {
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      return "p";
++    case ISEL_FLAG_CMP_SIGNED:
++    case ISEL_FLAG_SEL_SIGNED:
++      return "s";
++    case ISEL_FLAG_CMP_UNSIGNED:
++    case ISEL_FLAG_SEL_UNSIGNED:
++      return "u";
++    default:
++      gcc_unreachable ();
++    }
++}
++
++/* Initialize N_DESC isel builtins from DESC.  SIGNED_TYPE holds the
++   basic type for signed variants of isel, UNSIGNED_TYPE the type for
++   unsigned variants.  */
++
++static void
++rs6000_init_isel_builtins (const struct isel_builtin_desc *desc, int n_descs)
++{
++  int i;
++  const char *is64 = (desc == &builtin_iselw[0] ? "32" : "64");
++
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++      tree cmptype, seltype, ftype;
++
++      cmptype = isel_argtype (d, true);
++      seltype = isel_argtype (d, false);
++
++      ftype = build_function_type_list (seltype, cmptype, cmptype,
++                                       seltype, seltype, NULL_TREE);
++
++      if (d->name)
++       def_builtin (MASK_ISEL, d->name, ftype, d->code);
++      else
++       {
++         char builtin_name[40];
++
++         sprintf (builtin_name, "__builtin_isel%s%s%s%s%s%s",
++                  is64,
++                  GET_RTX_NAME (d->cmp_code),
++                  GET_MODE_NAME (isel_cmp_mode (d)),
++                  isel_strdesc (d->arg_flags, true),
++                  isel_strdesc (d->arg_flags, false),
++                  GET_MODE_NAME (isel_sel_mode (d)));
++
++         def_builtin (MASK_ISEL, ggc_strdup (builtin_name), ftype, d->code);
++       }
++    }
++}
++
++static rtx
++rs6000_expand_isel_builtin (const struct isel_builtin_desc *desc,
++                           int n_descs, tree exp, rtx target, int fcode)
++{
++  int i;
++
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++
++      if (fcode == (int) d->code)
++       {
++         int opidx;
++         unsigned int j;
++         rtx cmp;
++         rtx operands[4];
++         enum insn_code icode;
++         enum machine_mode opmode;
++         enum machine_mode cmpmode = isel_cmp_mode (d);
++         enum machine_mode selmode = isel_sel_mode (d);
++
++         /* Determine underlying isel insn.  */
++         switch (d->cmp_code)
++           {
++           case GTU:
++           case LTU:
++             icode = (Pmode == SImode
++                      ? CODE_FOR_isel_unsigned_si
++                      : CODE_FOR_isel_unsigned_di);
++             break;
++           default:
++             icode = (Pmode == SImode
++                      ? CODE_FOR_isel_signed_si
++                      : CODE_FOR_isel_signed_di);
++             break;
++           }
++
++         for (j = 0; j < ARRAY_SIZE (operands); j++)
++           {
++             tree arg = CALL_EXPR_ARG (exp, j);
++
++             /* If we got invalid arguments, bail out before generating
++                bad rtl.  */
++             if (arg == error_mark_node)
++               return const0_rtx;
++
++             operands[j] = expand_normal (arg);
++
++             /* Validate.  */
++             /* HACK: The isel pattern doesn't actually consume all the
++                operands to the builtin; it only consumes 2 and 3.  The
++                other two will be handed off to a compare
++                insn. Unfortunately, said insn is not named, so we
++                can't directly access its insn_data here.  Fake it by
++                validating operands 0 and 1 with the isel pattern; that
++                should be good enough.  */
++             opidx = (j < 2 ? 2 : j);
++             opmode = (j < 2 ? cmpmode : selmode);
++             if (! (*insn_data[icode].operand[opidx].predicate) (operands[j],
++                                                                 opmode))
++               operands[j] = copy_to_mode_reg (opmode, operands[j]);
++           }
++
++         /* Validate target.  */
++         if (target == NULL_RTX
++             || GET_MODE (target) != selmode
++             || ! (*insn_data[icode].operand[0].predicate) (target, selmode))
++           target = gen_reg_rtx (selmode);
++
++         /* Generate comparison.  */
++         cmp = gen_rtx_fmt_ee ((enum rtx_code)d->cmp_code, cmpmode,
++                               operands[0], operands[1]);
++
++         rs6000_emit_int_cmove (target, cmp, operands[2], operands[3]);
++
++         return target;
++       }
++    }
++
++  return NULL_RTX;
++}
++
+ /* Expand an expression EXP that calls a built-in function,
+    with result going to TARGET if that's convenient
+    (and in mode MODE if that's convenient).
+@@ -12520,6 +12803,24 @@
+       if (success)
+       return ret;
+     }  
++  if (TARGET_ISEL)
++    {
++      ret = rs6000_expand_isel_builtin (builtin_iselw,
++                                       ARRAY_SIZE (builtin_iselw),
++                                       exp, target, fcode);
++
++      if (ret != NULL_RTX)
++       return ret;
++    }
++  if (TARGET_ISEL64)
++    {
++      ret = rs6000_expand_isel_builtin (builtin_iseld,
++                                       ARRAY_SIZE (builtin_iseld),
++                                       exp, target, fcode);
++
++      if (ret != NULL_RTX)
++       return ret;
++    }
+   gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
+@@ -12738,6 +13039,10 @@
+     spe_init_builtins ();
+   if (TARGET_ALTIVEC)
+     altivec_init_builtins ();
++  if (TARGET_ISEL)
++    rs6000_init_isel_builtins (builtin_iselw, ARRAY_SIZE (builtin_iselw));
++  if (TARGET_ISEL64)
++    rs6000_init_isel_builtins (builtin_iseld, ARRAY_SIZE (builtin_iseld));
+   if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
+     rs6000_common_init_builtins ();
+   if (TARGET_FRE)
+diff -ruN gcc-4.6.0-orig/gcc/config/rs6000/rs6000-c.c gcc-4.6.0-new/gcc/config/rs6000/rs6000-c.c
+--- gcc-4.6.0-orig/gcc/config/rs6000/rs6000-c.c        2011-02-02 23:42:19.000000000 -0600
++++ gcc-4.6.0-new/gcc/config/rs6000/rs6000-c.c 2011-07-25 16:07:14.616209000 -0500
+@@ -3439,7 +3439,7 @@
+ /* Implementation of the resolve_overloaded_builtin target hook, to
+    support Altivec's overloaded builtins.  */
+-tree
++static tree
+ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
+                                   void *passed_arglist)
+ {
+@@ -3770,3 +3770,148 @@
+   error ("invalid parameter combination for AltiVec intrinsic");
+   return error_mark_node;
+ }
++
++/* Return true if the pair of arguments in ARGS is acceptable according
++   to DECLTYPES and FLAGS.  CMPP determines whether this is for the
++   comparison arguments.  */
++
++static bool
++isel_arguments_valid (tree *args, tree *decltypes, int flags, bool cmpp)
++{
++  tree type0 = TREE_TYPE (args[0]);
++  tree type1 = TREE_TYPE (args[1]);
++  tree decltype0 = decltypes[0];
++  tree decltype1 = decltypes[1];
++
++  switch (flags & (cmpp ? ISEL_FLAG_CMP_MASK : ISEL_FLAG_SEL_MASK))
++    {
++      /* For pointer arguments and results, we just need to make sure
++        we're receiving pointers, and they can be freely converted to
++        and from void *.  For pointer results, we also need to ensure
++        that the types of the passed arguments are compatible: this is
++        similar to what the ?: construct would need to ensure.  */
++    case ISEL_FLAG_CMP_PTR:
++    case ISEL_FLAG_SEL_PTR:
++      {
++       /* Results compatible with each other?  */
++       if (!lang_hooks.types_compatible_p (type0, type1))
++         return false;
++
++       return (POINTER_TYPE_P (type0)
++               && POINTER_TYPE_P (type1));
++      }
++      break;
++      /* For signed and unsigned arguments and results, we just need to
++        make sure that the argument types are compatible with the
++        declared types; we can insert conversions to make everything
++        match up.  */
++    case ISEL_FLAG_CMP_SIGNED:
++    case ISEL_FLAG_SEL_SIGNED:
++    case ISEL_FLAG_CMP_UNSIGNED:
++    case ISEL_FLAG_SEL_UNSIGNED:
++      return (lang_hooks.types_compatible_p (type0, decltype0)
++             && lang_hooks.types_compatible_p (type1, decltype1));
++    default:
++      ;
++    }
++
++  gcc_unreachable ();
++}
++
++/* Determine if FNDECL is a generic isel intrinsic and if it can be
++   resolved to a non-generic version with a proper type using the
++   descriptions found in DESC.  Return a call to the non-generic builtin
++   if so.  */
++
++static tree
++rs6000_resolve_isel_builtin (location_t loc, tree fndecl,
++                            void *passed_arglist,
++                            const struct isel_builtin_desc *desc,
++                            int n_descs)
++{
++  VEC(tree,gc) *arglist = (VEC(tree,gc) *) passed_arglist;
++  unsigned int nargs = VEC_length (tree, arglist);
++  int i;
++  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
++  const struct isel_builtin_desc *generic = NULL;
++
++  /* Is this even a builtin we care about?  */
++  if (fcode < ISEL_BUILTIN_OVERLOADED_FIRST
++      || fcode > ISEL_BUILTIN_OVERLOADED_LAST)
++    return NULL_TREE;
++
++  if (nargs != 4)
++    {
++      error ("isel intrinsics only accept 4 arguments");
++      return error_mark_node;
++    }
++
++  /* Find the generic builtin we're resolving.  */
++  for (i = 0; i < n_descs; i++)
++    if (desc[i].code == fcode)
++      {
++       generic = &desc[i];
++       break;
++      }
++
++  /* Happens if we're looking for a 64-bit builtin in the 32-bit
++     descriptors.  */
++  if (generic == NULL)
++    return NULL_TREE;
++
++  /* Try all the builtins whose comparison matches the generic one.  */
++  for (i = 0; i < n_descs; i++)
++    {
++      const struct isel_builtin_desc *d = &desc[i];
++      int j;
++      tree *argp = VEC_address (tree, arglist);
++      tree impl_fndecl;
++      tree decltypes[4], t;
++      tree converted_args[4];
++
++      if (d == generic || d->cmp_code != generic->cmp_code)
++       continue;
++
++      impl_fndecl = rs6000_builtin_decls[d->code];
++      t = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl));
++      for (j = 0 ; t != void_list_node; j++, t = TREE_CHAIN (t))
++       decltypes[j] = TREE_VALUE (t);
++
++      if (!isel_arguments_valid (argp, decltypes, d->arg_flags, true)
++         || !isel_arguments_valid (argp+2, decltypes+2, d->arg_flags, false))
++       continue;
++
++      /* We got here, we're ok.  Build a new, resolved CALL_EXPR.  */
++      for (j = 0; j < 4; j++)
++       converted_args[j] = fold_convert (decltypes[j], argp[j]);
++
++      return build_call_expr_loc (loc, impl_fndecl, 4,
++                                 converted_args[0], converted_args[1],
++                                 converted_args[2], converted_args[3]);
++    }
++
++  error ("invalid parameter combination for isel intrinsic");
++  return error_mark_node;
++}
++
++tree
++rs6000_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
++{
++  tree t;
++
++  t = altivec_resolve_overloaded_builtin (loc, fndecl, arglist);
++  if (t)
++    return t;
++
++  t = rs6000_resolve_isel_builtin (loc, fndecl, arglist,
++                                  builtin_iselw, ARRAY_SIZE (builtin_iselw));
++  if (t)
++    return t;
++
++  t = rs6000_resolve_isel_builtin (loc, fndecl, arglist,
++                                  builtin_iseld, ARRAY_SIZE (builtin_iseld));
++  if (t)
++    return t;
++
++  return NULL_TREE;
++}
+diff -ruN gcc-4.6.0-orig/gcc/config/rs6000/rs6000.h gcc-4.6.0-new/gcc/config/rs6000/rs6000.h
+--- gcc-4.6.0-orig/gcc/config/rs6000/rs6000.h  2011-03-07 13:27:09.000000000 -0600
++++ gcc-4.6.0-new/gcc/config/rs6000/rs6000.h   2011-07-25 16:07:04.045105000 -0500
+@@ -535,7 +535,7 @@
+ #define REGISTER_TARGET_PRAGMAS() do {                                \
+   c_register_pragma (0, "longcall", rs6000_pragma_longcall);  \
+   targetm.target_option.pragma_parse = rs6000_pragma_target_parse; \
+-  targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \
++  targetm.resolve_overloaded_builtin = rs6000_resolve_overloaded_builtin; \
+ } while (0)
+ /* Target #defines.  */
+@@ -2446,3 +2446,41 @@
+ extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
+ extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
++/* Values for struct isel_builtin_desc.arg_flags.  */
++enum {
++  ISEL_FLAG_CMP_PTR = 0x1,
++  ISEL_FLAG_CMP_SIGNED = 0x2,
++  ISEL_FLAG_CMP_UNSIGNED = 0x4,
++  ISEL_FLAG_CMP_MASK = 0x7,
++  ISEL_FLAG_SEL_PTR = 0x10,
++  ISEL_FLAG_SEL_SIGNED = 0x20,
++  ISEL_FLAG_SEL_UNSIGNED = 0x40,
++  ISEL_FLAG_SEL_MASK = 0x70
++};
++
++struct isel_builtin_desc {
++  /* Name of this builtin.  NULL if we should construct it.  */
++  const char *name;
++
++  /* Flags for argument combinations accepted by the builtin.
++     Zero if this builtin is a generic builtin, to be resolved later.  */
++  int arg_flags;
++
++  /* The code of the builtin.  */
++  enum rs6000_builtins code;
++
++  /* rtx_code and machine_mode are not available here; use ints instead.  */
++  /* The comparison code the builtin uses.  */
++  int cmp_code;
++
++  /* The mode the builtin does comparisons in.  */
++  int cmp_mode;
++
++  /* The mode the builtin's selected arguments are in.
++     Also happens to be its result mode.  */
++  int sel_mode;
++};
++
++/* Arrays describing isel builtins.  */
++extern const struct isel_builtin_desc builtin_iselw[32];
++extern const struct isel_builtin_desc builtin_iseld[32];
+diff -ruN gcc-4.6.0-orig/gcc/config/rs6000/rs6000-protos.h gcc-4.6.0-new/gcc/config/rs6000/rs6000-protos.h
+--- gcc-4.6.0-orig/gcc/config/rs6000/rs6000-protos.h   2011-03-15 07:57:37.000000000 -0500
++++ gcc-4.6.0-new/gcc/config/rs6000/rs6000-protos.h    2011-07-25 16:07:50.484773000 -0500
+@@ -142,7 +142,7 @@
+                                                    unsigned int);
+ extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
+                                                           unsigned int);
+-extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
++extern tree rs6000_resolve_overloaded_builtin (location_t, tree, void *);
+ extern rtx rs6000_libcall_value (enum machine_mode);
+ extern rtx rs6000_va_arg (tree, tree);
+ extern int function_ok_for_sibcall (tree);
+diff -ruN gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c
+--- gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel64.c    2011-07-25 12:27:55.343932000 -0500
+@@ -0,0 +1,75 @@
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-mcpu=e500mc64" } */
++
++#include "builtin-isel.h"
++
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64eq
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++  /* Equality checks explicitly permit unsigned comparison operands.  */
++  L = ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b);
++  r = ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, p, q);
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64lt
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gt
++
++SIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64ltu
++
++UNSIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gtu
++
++UNSIGNED64_PROTO
++{
++  L = ISEL_BUILTIN (x, y, a, b);
++  U = ISEL_BUILTIN (x, y, (unsigned long) a, (unsigned long) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  L = ISEL_BUILTIN (p, q, a, b);
++}
++
++/* Don't use bare isel, as that'll match function names and the like.  */
++/* { dg-final { scan-assembler-times "isel " 26 } } */
+diff -ruN gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c
+--- gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c    1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel64-errors.c     2011-07-25 12:27:55.372965000 -0500
+@@ -0,0 +1,110 @@
++/* Test rejection of invalid parameter combinations in isel builtins.  */
++/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
++/* { dg-options "-mcpu=e5500" } */
++
++#include "builtin-isel.h"
++
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64eq
++
++SIGNED64_PROTO
++{
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64lt
++
++SIGNED64_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gt
++
++SIGNED64_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned long) x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64ltu
++
++UNSIGNED64_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((long) x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isel64gtu
++
++UNSIGNED64_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((long) x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((long) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (long) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((long *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (long *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned long) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned long) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (long *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (long *) q); /* { dg-error "isel intrinsic" } */
++}
+diff -ruN gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel.c gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel.c
+--- gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel.c     1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel.c      2011-07-25 12:27:55.405959000 -0500
+@@ -0,0 +1,81 @@
++/* { dg-do compile } */
++/* { dg-options "-mcpu=e500mc" } */
++
++#include "builtin-isel.h"
++
++/* We're not being clever with the preprocessor here because DejaGNU
++   will get confused.  We do try to use it to eliminate what duplication
++   we can.  */
++
++/* We check to see that the resolution permits polymorphic results.  */
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iseleq
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++  /* Equality checks explicitly permit unsigned comparison operands.  */
++  i = ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b);
++  r = ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, p, q);
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isellt
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgt
++
++SIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselltu
++
++UNSIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgtu
++
++UNSIGNED_PROTO
++{
++  i = ISEL_BUILTIN (x, y, a, b);
++  u = ISEL_BUILTIN (x, y, (unsigned int) a, (unsigned int) b);
++  r = ISEL_BUILTIN (x, y, p, q);
++  r = ISEL_BUILTIN (x, y, (char *) p, (char *) q);
++  i = ISEL_BUILTIN (p, q, a, b);
++}
++
++/* Don't use bare isel, as that'll match function names and the like.  */
++/* { dg-final { scan-assembler-times "isel " 26 } } */
+diff -ruN gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c
+--- gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel-errors.c       2011-07-25 12:27:55.443938000 -0500
+@@ -0,0 +1,117 @@
++/* Test rejection of invalid parameter combinations in isel builtins.  */
++/* { dg-do compile } */
++/* { dg-options "-mcpu=e500mc" } */
++
++#include "builtin-isel.h"
++
++/* We're not being clever with the preprocessor here because DejaGNU
++   will get confused.  We do try to use it to eliminate what duplication
++   we can.  */
++
++/* We check basic resolution of each builtin.  We also check to see that
++   the resolution permits polymorphic results.  Argument type mismatches
++   and result type mismatches are not permitted, except where noted.  */
++\f
++/* Equality comparisons.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iseleq
++
++SIGNED_PROTO
++{
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* less-than, greater-than.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME isellt
++
++SIGNED_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgt
++
++SIGNED_PROTO
++{
++  /* Unsigned comparison should be done with the *u variants.  */
++  ISEL_BUILTIN ((unsigned int) x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* So should pointer comparison.  */
++  ISEL_BUILTIN (p, q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((unsigned int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (unsigned int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++\f
++/* Unsigned variants.  These permit unsigned and pointer operands for
++   comparison only.  */
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselltu
++
++UNSIGNED_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((int) x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
++
++#undef FUNCTION_NAME
++#define FUNCTION_NAME iselgtu
++
++UNSIGNED_PROTO
++{
++  /* Signed comparison should be done with the signed variants.  */
++  ISEL_BUILTIN ((int) x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in argument type.  */
++  ISEL_BUILTIN ((int) x, y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, (int) y, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN ((int *) p, q, a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (p, (int *) q, a, b); /* { dg-error "isel intrinsic" } */
++  /* Mismatches in return type.  */
++  ISEL_BUILTIN (x, y, (unsigned int) a, b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, a, (unsigned int) b); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, (int *) p, q); /* { dg-error "isel intrinsic" } */
++  ISEL_BUILTIN (x, y, p, (int *) q); /* { dg-error "isel intrinsic" } */
++}
+diff -ruN gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel.h gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel.h
+--- gcc-4.6.0-orig/gcc/testsuite/gcc.target/powerpc/builtin-isel.h     1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/testsuite/gcc.target/powerpc/builtin-isel.h      2011-07-25 12:27:55.483942000 -0500
+@@ -0,0 +1,25 @@
++/* Common definitions for builtin isel testing.  */
++
++#define SIGNED_ARGLIST (int x, int y, int a, int b, void *p, void *q)
++#define UNSIGNED_ARGLIST (unsigned int x, unsigned int y, \
++                        int a, int b, void *p, void *q)
++
++#define SIGNED_PROTO void FUNCTION_NAME SIGNED_ARGLIST
++#define UNSIGNED_PROTO void FUNCTION_NAME UNSIGNED_ARGLIST
++
++#define SIGNED64_ARGLIST (long x, long y, long a, long b, void *p, void *q)
++#define UNSIGNED64_ARGLIST (unsigned long x, unsigned long y, \
++                          long a, long b, void *p, void *q)
++
++#define SIGNED64_PROTO void FUNCTION_NAME SIGNED64_ARGLIST
++#define UNSIGNED64_PROTO void FUNCTION_NAME UNSIGNED64_ARGLIST
++
++#define CONCAT2(X,Y) X##Y
++#define CONCAT(X,Y) CONCAT2(X, Y)
++#define ISEL_BUILTIN CONCAT(__builtin_, FUNCTION_NAME)
++
++volatile int i;
++volatile unsigned int u;
++volatile void *r;
++volatile long L;
++volatile unsigned long U;
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.case_values.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.case_values.patch
new file mode 100644 (file)
index 0000000..5be766d
--- /dev/null
@@ -0,0 +1,65 @@
+--- gcc-4.6.0/gcc/params.def-orig      2011-06-16 11:39:42.412634260 -0500
++++ gcc-4.6.0/gcc/params.def   2011-06-16 11:41:29.457630886 -0500
+@@ -39,6 +39,11 @@
+    Be sure to add an entry to invoke.texi summarizing the parameter.  */
++DEFPARAM (PARAM_CASE_VALUES_THRESHOLD,
++        "case-values-threshold",
++        "Minimum number of case statements for each a jump table will be used",
++        4, 4, 1000)
++
+ /* The threshold ratio between current and hottest structure counts.
+    We say that if the ratio of the current structure count,
+    calculated by profiling, to the hottest structure count
+--- gcc-4.6.0/gcc/config/rs6000/rs6000.c-orig  2011-06-16 12:24:03.440630751 -0500
++++ gcc-4.6.0/gcc/config/rs6000/rs6000.c       2011-06-16 12:24:51.450630163 -0500
+@@ -1282,6 +1282,7 @@
+                                           struct cl_target_option *);
+ static bool rs6000_can_inline_p (tree, tree);
+ static void rs6000_set_current_function (tree);
++static unsigned int rs6000_case_values_threshold (void);
\f
+ /* Default register names.  */
+--- gcc-4.6.0/gcc/config/rs6000/rs6000.c-orig  2011-06-16 11:18:27.131631000 -0500
++++ gcc-4.6.0/gcc/config/rs6000/rs6000.c       2011-06-16 11:38:15.225631714 -0500
+@@ -1704,6 +1704,9 @@
+ #undef TARGET_SET_CURRENT_FUNCTION
+ #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
++#undef TARGET_CASE_VALUES_THRESHOLD
++#define TARGET_CASE_VALUES_THRESHOLD rs6000_case_values_threshold
++
+ struct gcc_target targetm = TARGET_INITIALIZER;
\f
+@@ -28179,6 +28182,12 @@
+ }
\f
++static unsigned int
++rs6000_case_values_threshold (void)
++{
++  return PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD);
++}
++\f
+ /* Save the current options */
+ static void
+--- gcc-4.6.0/gcc/config/rs6000/rs6000.c-orig  2011-06-17 12:19:00.463631000 -0500
++++ gcc-4.6.0/gcc/config/rs6000/rs6000.c       2011-06-17 12:06:28.904630840 -0500
+@@ -2906,6 +2906,13 @@
+   if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
+     rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
++  if ((rs6000_cpu == PROCESSOR_PPC8540
++       || rs6000_cpu == PROCESSOR_PPCE500MC
++       || rs6000_cpu == PROCESSOR_PPCE5500
++       || rs6000_cpu == PROCESSOR_PPCE6500)
++      && global_options_set.x_param_values[(int) PARAM_CASE_VALUES_THRESHOLD] != true)
++    global_options.x_param_values[(int) PARAM_CASE_VALUES_THRESHOLD] = 8;
++    
+   if (global_init_p)
+     {
+       /* If the appropriate debug option is enabled, replace the target hooks
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.check_path_validity.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.check_path_validity.patch
new file mode 100644 (file)
index 0000000..5d70a39
--- /dev/null
@@ -0,0 +1,12 @@
+--- gcc-4_6-branch/gcc/Makefile.in.orig        2012-03-06 01:10:15.277196930 -0600
++++ gcc-4_6-branch/gcc/Makefile.in     2012-03-06 01:10:54.083378912 -0600
+@@ -4170,6 +4170,9 @@
+       else \
+         set -e; for ml in `cat fixinc_list`; do \
+           sysroot_headers_suffix=`echo $${ml} | sed -e 's/;.*$$//'`; \
++            if test "x$${sysroot_headers_suffix}" = "x"; then \
++              continue; \
++            fi; \
+           multi_dir=`echo $${ml} | sed -e 's/^[^;]*;//'`; \
+           fix_dir=include-fixed$${multi_dir}; \
+           if ! $(inhibit_libc) && test ! -d ${SYSTEM_HEADER_DIR}; then \
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e5500_mfocr.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e5500_mfocr.patch
new file mode 100644 (file)
index 0000000..16b3538
--- /dev/null
@@ -0,0 +1,181 @@
+# Problem: Although gcc is prepared to avoid "mfocr" instructions
+  (which takes 5 cycles in our parts and 2 cycles on IBM parts). This
+  instruction is used on the mentioned program. What is suspicious
+  about it, is that the code compiled for 32 bits does not use the
+  instruction. So, it could be a omission in the previous
+  implementation, or a bug, or a new opportunity.
+# Reported by: Performance team (PARC)
+# Owned by: Ping Hu
+# Action:
+    * 'mfocr' flag problem: that 'mfocr' flag was uncorrectly set for E5500,
+      which caused the 'mfocr' instructions generated even on E5500.
+    * avoid generating 'mfcr' and 'mfocr' instructions: due to the fact
+      that both instructions are expensive on Freescale processors.
+    * A target specific flag, -mslow-mfocr, can be used to avoid generating
+      'mfcr' and 'mfocr' instructions in 64-bit mode, thus restoring legacy
+      operations if desired.
+
+diff -ruN gcc-4.6.2-clean/gcc/config/rs6000/rs6000.c gcc-4.6.2/gcc/config/rs6000/rs6000.c
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.c 2011-11-22 11:11:47.479144000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.c       2011-11-29 16:23:45.074279998 -0600
+@@ -1885,6 +1885,7 @@
+    POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
+ };
++
+ /* Look up a processor name for -mcpu=xxx and -mtune=xxx.  Return -1 if the
+    name is invalid.  */
+@@ -2902,6 +2903,10 @@
+       || rs6000_cpu == PROCESSOR_PPCE6500)
+     target_flags &= ~MASK_PPC_GPOPT;
++  if (rs6000_cpu == PROCESSOR_PPCE5500)
++      target_flags &= ~MASK_MFCRF;
++
++
+   /* store_one_arg depends on expand_block_move to handle at least the
+      size of reg_parm_stack_space.  */
+   if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
+diff -ruN gcc-4.6.2-clean/gcc/config/rs6000/rs6000.md gcc-4.6.2/gcc/config/rs6000/rs6000.md
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.md        2011-11-22 11:11:47.036144001 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.md      2011-11-29 16:24:04.705280001 -0600
+@@ -215,6 +215,8 @@
+ ; (one with a '.') will compare; and the size used for arithmetic carries.
+ (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
++(define_mode_iterator P2 [(SI "TARGET_32BIT || TARGET_SLOW_MFOCR") (DI "TARGET_64BIT")])
++
+ ; Any hardware-supported floating-point mode
+ (define_mode_iterator FP [
+   (SF "TARGET_HARD_FLOAT 
+@@ -2208,9 +2210,9 @@
+ (define_insn ""
+   [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+-      (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
++      (compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r"))
+                   (const_int 0)))
+-   (clobber (match_scratch:P 2 "=r,r"))]
++   (clobber (match_scratch:P2 2 "=r,r"))]
+   ""
+   "@
+    neg. %2,%1
+@@ -2220,12 +2222,12 @@
+ (define_split
+   [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+-      (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
++      (compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+-   (clobber (match_scratch:P 2 ""))]
++   (clobber (match_scratch:P2 2 ""))]
+   "reload_completed"
+   [(set (match_dup 2)
+-      (neg:P (match_dup 1)))
++      (neg:P2 (match_dup 1)))
+    (set (match_dup 0)
+       (compare:CC (match_dup 2)
+                   (const_int 0)))]
+@@ -2233,10 +2235,10 @@
+ (define_insn ""
+   [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
+-      (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
++      (compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r"))
+                   (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+-      (neg:P (match_dup 1)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "=r,r")
++      (neg:P2 (match_dup 1)))]
+   ""
+   "@
+    neg. %0,%1
+@@ -2246,13 +2248,13 @@
+ (define_split
+   [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
+-      (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
++      (compare:CC (neg:P2 (match_operand:P2 1 "gpc_reg_operand" ""))
+                   (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "")
+-      (neg:P (match_dup 1)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "")
++      (neg:P2 (match_dup 1)))]
+   "reload_completed"
+   [(set (match_dup 0)
+-      (neg:P (match_dup 1)))
++      (neg:P2 (match_dup 1)))
+    (set (match_dup 2)
+       (compare:CC (match_dup 0)
+                   (const_int 0)))]
+@@ -15286,31 +15288,31 @@
+   [(set_attr "length" "12")])
+ (define_insn_and_split "*gtu<mode>"
+-  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+-      (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
+-             (match_operand:P 2 "reg_or_short_operand" "rI")))]
++  [(set (match_operand:P2 0 "gpc_reg_operand" "=r")
++      (gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r")
++              (match_operand:P2 2 "reg_or_short_operand" "rI")))]
+   ""
+   "#"
+   ""
+-  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
+-   (set (match_dup 0) (neg:P (match_dup 0)))]
++  [(set (match_dup 0) (neg:P2 (gtu:P2 (match_dup 1) (match_dup 2))))
++   (set (match_dup 0) (neg:P2 (match_dup 0)))]
+   "")
+ (define_insn_and_split "*gtu<mode>_compare"
+   [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+       (compare:CC
+-       (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
+-               (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
++       (gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r,r")
++               (match_operand:P2 2 "reg_or_short_operand" "rI,rI"))
+        (const_int 0)))
+-   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+-      (gtu:P (match_dup 1) (match_dup 2)))]
++   (set (match_operand:P2 0 "gpc_reg_operand" "=r,r")
++      (gtu:P2 (match_dup 1) (match_dup 2)))]
+   ""
+   "#"
+   ""
+-  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
++  [(set (match_dup 0) (neg:P2 (gtu:P2 (match_dup 1) (match_dup 2))))
+    (parallel [(set (match_dup 3)
+-                 (compare:CC (neg:P (match_dup 0)) (const_int 0)))
+-            (set (match_dup 0) (neg:P (match_dup 0)))])]
++                 (compare:CC (neg:P2 (match_dup 0)) (const_int 0)))
++            (set (match_dup 0) (neg:P2 (match_dup 0)))])]
+   "")
+ (define_insn_and_split "*plus_gtu<mode>"
+@@ -15345,9 +15347,9 @@
+   "")
+ (define_insn "*neg_gtu<mode>"
+-  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+-      (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
+-                    (match_operand:P 2 "reg_or_short_operand" "rI"))))]
++  [(set (match_operand:P2 0 "gpc_reg_operand" "=r")
++      (neg:P2 (gtu:P2 (match_operand:P2 1 "gpc_reg_operand" "r")
++                      (match_operand:P2 2 "reg_or_short_operand" "rI"))))]
+   ""
+   "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
+   [(set_attr "type" "two")
+--- gcc-4.6.2-clean/gcc/config/rs6000/rs6000.opt       2011-11-22 11:11:47.480143999 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.opt     2011-11-29 16:24:16.322280634 -0600
+@@ -381,6 +381,10 @@
+ Target
+ Generate SPE SIMD instructions on E500
++mslow-mfocr
++Target Report Var(TARGET_SLOW_MFOCR)
++Generate slow mfocr instructions
++
+ mpaired
+ Target Var(rs6000_paired_float) Save
+ Generate PPC750CL paired-single instructions
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e6500-FSF46.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e6500-FSF46.patch
new file mode 100644 (file)
index 0000000..f9fa33d
--- /dev/null
@@ -0,0 +1,4011 @@
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/altivec.h gcc-4.6.2/gcc/config/rs6000/altivec.h
+--- gcc-4.6.2-orig/gcc/config/rs6000/altivec.h 2011-02-02 23:42:19.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/altivec.h      2012-03-06 12:33:43.943038996 -0600
+@@ -322,6 +322,30 @@
+ #define vec_vsx_st __builtin_vec_vsx_st
+ #endif
++#ifdef __ALTIVEC2__
++/* New Altivec instructions */
++#define vec_absd __builtin_vec_absd
++#define vec_lvexbx __builtin_vec_lvexbx
++#define vec_lvexhx __builtin_vec_lvexhx
++#define vec_lvexwx __builtin_vec_lvexwx
++#define vec_stvexbx __builtin_vec_stvexbx
++#define vec_stvexhx __builtin_vec_stvexhx
++#define vec_stvexwx __builtin_vec_stvexwx
++#define vec_lvswx __builtin_vec_lvswx
++#define vec_lvswxl __builtin_vec_lvswxl
++#define vec_stvswx __builtin_vec_stvswx
++#define vec_stvswxl __builtin_vec_stvswxl
++#define vec_lvsm __builtin_vec_lvsm
++#define vec_lvtlx __builtin_vec_lvtlx
++#define vec_lvtlxl __builtin_vec_lvtlxl
++#define vec_lvtrx __builtin_vec_lvtrx
++#define vec_lvtrxl __builtin_vec_lvtrxl
++#define vec_stvflx __builtin_vec_stvflx
++#define vec_stvflxl __builtin_vec_stvflxl
++#define vec_stvfrx __builtin_vec_stvfrx
++#define vec_stvfrxl __builtin_vec_stvfrxl
++#endif
++
+ /* Predicates.
+    For C++, we use templates in order to allow non-parenthesized arguments.
+    For C, instead, we use macros since non-parenthesized arguments were
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/altivec.md gcc-4.6.2/gcc/config/rs6000/altivec.md
+--- gcc-4.6.2-orig/gcc/config/rs6000/altivec.md        2011-07-08 15:10:18.000000000 -0500
++++ gcc-4.6.2/gcc/config/rs6000/altivec.md     2012-03-06 12:24:35.058038999 -0600
+@@ -91,9 +91,11 @@
+    (UNSPEC_LVSL         194)
+    (UNSPEC_LVSR         195)
+    (UNSPEC_LVE          196)
++   (UNSPEC_LVEX         197)
+    (UNSPEC_STVX         201)
+    (UNSPEC_STVXL        202)
+    (UNSPEC_STVE         203)
++   (UNSPEC_STVEX        204)
+    (UNSPEC_SET_VSCR     213)
+    (UNSPEC_GET_VRSAVE   214)
+    (UNSPEC_LVX                215)
+@@ -123,6 +125,19 @@
+    (UNSPEC_STVLXL       241)
+    (UNSPEC_STVRX        242)
+    (UNSPEC_STVRXL       243)
++   (UNSPEC_LVTLX        244)
++   (UNSPEC_LVTLXL     245)
++   (UNSPEC_LVTRX      246)
++   (UNSPEC_LVTRXL     247)
++   (UNSPEC_STVFLX     248)
++   (UNSPEC_STVFLXL    249)
++   (UNSPEC_STVFRX     250)
++   (UNSPEC_STVFRXL    251)
++   (UNSPEC_LVSWX        252)
++   (UNSPEC_LVSWXL       253)
++   (UNSPEC_LVSM         254)
++   (UNSPEC_STVSWX       255)
++   (UNSPEC_STVSWXL      256)
+    (UNSPEC_VMULWHUB     308)
+    (UNSPEC_VMULWLUB     309)
+    (UNSPEC_VMULWHSB     310)
+@@ -143,6 +158,9 @@
+    (UNSPEC_VUPKLS_V4SF  325)
+    (UNSPEC_VUPKHU_V4SF  326)
+    (UNSPEC_VUPKLU_V4SF  327)
++   (UNSPEC_VABSDUB      328)
++   (UNSPEC_VABSDUH      329)
++   (UNSPEC_VABSDUW      330)
+ ])
+ (define_constants
+@@ -323,6 +341,34 @@
+ ;; Simple binary operations.
++;; absd
++(define_insn "altivec_vabsduw"
++  [(set (match_operand:V4SI 0 "register_operand" "=v")
++        (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
++                      (match_operand:V4SI 2 "register_operand" "v")]
++                   UNSPEC_VABSDUW))]
++  "TARGET_ALTIVEC2"
++  "vabsduw %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
++(define_insn "altivec_vabsduh"
++  [(set (match_operand:V8HI 0 "register_operand" "=v")
++        (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
++                      (match_operand:V8HI 2 "register_operand" "v")]
++                   UNSPEC_VABSDUH))]
++  "TARGET_ALTIVEC2"
++  "vabsduh %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
++(define_insn "altivec_vabsdub"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
++                       (match_operand:V16QI 2 "register_operand" "v")]
++                    UNSPEC_VABSDUB))]
++  "TARGET_ALTIVEC2"
++  "vabsdub %0,%1,%2"
++  [(set_attr "type" "vecsimple")])
++
+ ;; add
+ (define_insn "add<mode>3"
+   [(set (match_operand:VI 0 "register_operand" "=v")
+@@ -1741,6 +1787,15 @@
+   "lvewx %0,%y1"
+   [(set_attr "type" "vecload")])
++(define_insn "altivec_lvex<VI_char>x"
++  [(parallel
++    [(set (match_operand:VI 0 "register_operand" "=v")
++        (match_operand:VI 1 "memory_operand" "Z"))
++     (unspec [(const_int 0)] UNSPEC_LVEX)])]
++  "TARGET_ALTIVEC2"
++  "lvex<VI_char>x %0,%y1"
++  [(set_attr "type" "vecload")])
++
+ (define_insn "altivec_lvxl"
+   [(parallel
+     [(set (match_operand:V4SI 0 "register_operand" "=v")
+@@ -1791,6 +1846,13 @@
+   "stvewx %1,%y0"
+   [(set_attr "type" "vecstore")])
++(define_insn "altivec_stvex<VI_char>x"
++  [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
++      (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVEX))]
++  "TARGET_ALTIVEC2"
++  "stvex<VI_char>x %1,%y0"
++  [(set_attr "type" "vecstore")])
++
+ ;; Generate
+ ;;    vspltis? SCRATCH0,0
+ ;;    vsubu?m SCRATCH2,SCRATCH1,%1
+@@ -2358,7 +2420,7 @@
+   DONE;
+ }")
+-;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
++;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX1, LVRXL,
+ ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
+ (define_insn "altivec_lvlx"
+   [(set (match_operand:V16QI 0 "register_operand" "=v")
+@@ -2394,8 +2456,8 @@
+ (define_insn "altivec_stvlx"
+   [(parallel
+-    [(set (match_operand:V4SI 0 "memory_operand" "=Z")
+-        (match_operand:V4SI 1 "register_operand" "v"))
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
+      (unspec [(const_int 0)] UNSPEC_STVLX)])]
+   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
+   "stvlx %1,%y0"
+@@ -2403,8 +2465,8 @@
+ (define_insn "altivec_stvlxl"
+   [(parallel
+-    [(set (match_operand:V4SI 0 "memory_operand" "=Z")
+-        (match_operand:V4SI 1 "register_operand" "v"))
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
+      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
+   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
+   "stvlxl %1,%y0"
+@@ -2412,8 +2474,8 @@
+ (define_insn "altivec_stvrx"
+   [(parallel
+-    [(set (match_operand:V4SI 0 "memory_operand" "=Z")
+-        (match_operand:V4SI 1 "register_operand" "v"))
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
+      (unspec [(const_int 0)] UNSPEC_STVRX)])]
+   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
+   "stvrx %1,%y0"
+@@ -2421,13 +2483,123 @@
+ (define_insn "altivec_stvrxl"
+   [(parallel
+-    [(set (match_operand:V4SI 0 "memory_operand" "=Z")
+-        (match_operand:V4SI 1 "register_operand" "v"))
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
+      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
+   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
+   "stvrxl %1,%y0"
+   [(set_attr "type" "vecstore")])
++(define_insn "altivec_lvtlx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                     UNSPEC_LVTLX))]
++  "TARGET_ALTIVEC2"
++  "lvtlx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtlxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                     UNSPEC_LVTLXL))]
++  "TARGET_ALTIVEC2"
++  "lvtlxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtrx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                     UNSPEC_LVTRX))]
++  "TARGET_ALTIVEC2"
++  "lvtrx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvtrxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                     UNSPEC_LVTRXL))]
++  "TARGET_ALTIVEC2"
++  "lvtrxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_stvflx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++         (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFLX)])]
++  "TARGET_ALTIVEC2"
++  "stvflx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvflxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++         (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFLXL)])]
++  "TARGET_ALTIVEC2"
++  "stvflxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvfrx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++         (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFRX)])]
++  "TARGET_ALTIVEC2"
++  "stvfrx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvfrxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++         (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVFRXL)])]
++  "TARGET_ALTIVEC2"
++  "stvfrxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_lvswx"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                    UNSPEC_LVSWX))]
++  "TARGET_ALTIVEC2"
++  "lvswx %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvswxl"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                    UNSPEC_LVSWXL))]
++  "TARGET_ALTIVEC2"
++  "lvswxl %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_lvsm"
++  [(set (match_operand:V16QI 0 "register_operand" "=v")
++        (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
++                    UNSPEC_LVSM))]
++  "TARGET_ALTIVEC2"
++  "lvsm %0,%y1"
++  [(set_attr "type" "vecload")])
++
++(define_insn "altivec_stvswx"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVSWX)])]
++  "TARGET_ALTIVEC2"
++  "stvswx %1,%y0"
++  [(set_attr "type" "vecstore")])
++
++(define_insn "altivec_stvswxl"
++  [(parallel
++    [(set (match_operand:V16QI 0 "memory_operand" "=Z")
++        (match_operand:V16QI 1 "register_operand" "v"))
++     (unspec [(const_int 0)] UNSPEC_STVSWXL)])]
++  "TARGET_ALTIVEC2"
++  "stvswxl %1,%y0"
++  [(set_attr "type" "vecstore")])
++
+ (define_expand "vec_extract_evenv4si"
+  [(set (match_operand:V4SI 0 "register_operand" "")
+         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "")
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/e5500.md gcc-4.6.2/gcc/config/rs6000/e5500.md
+--- gcc-4.6.2-orig/gcc/config/rs6000/e5500.md  1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/e5500.md       2012-03-06 12:16:07.590039001 -0600
+@@ -0,0 +1,176 @@
++;; Pipeline description for Freescale PowerPC e5500 core.
++;;   Copyright (C) 2011 Free Software Foundation, Inc.
++;;   Contributed by Edmar Wienskoski (edmar@freescale.com)
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++;;
++;; e5500 64-bit SFX(2), CFX, LSU, FPU, BU
++;; Max issue 3 insns/clock cycle (includes 1 branch)
++
++(define_automaton "e5500_most,e5500_long")
++(define_cpu_unit "e5500_decode_0,e5500_decode_1" "e5500_most")
++
++;; SFX.
++(define_cpu_unit "e5500_sfx_0,e5500_sfx_1" "e5500_most")
++
++;; CFX.
++(define_cpu_unit "e5500_cfx_stage0,e5500_cfx_stage1" "e5500_most")
++
++;; Non-pipelined division.
++(define_cpu_unit "e5500_cfx_div" "e5500_long")
++
++;; LSU.
++(define_cpu_unit "e5500_lsu" "e5500_most")
++
++;; FPU.
++(define_cpu_unit "e5500_fpu" "e5500_long")
++
++;; BU.
++(define_cpu_unit "e5500_bu" "e5500_most")
++
++;; The following units are used to make the automata deterministic.
++(define_cpu_unit "present_e5500_decode_0" "e5500_most")
++(define_cpu_unit "present_e5500_sfx_0" "e5500_most")
++(presence_set "present_e5500_decode_0" "e5500_decode_0")
++(presence_set "present_e5500_sfx_0" "e5500_sfx_0")
++
++;; Some useful abbreviations.
++(define_reservation "e5500_decode"
++    "e5500_decode_0|e5500_decode_1+present_e5500_decode_0")
++(define_reservation "e5500_sfx"
++   "e5500_sfx_0|e5500_sfx_1+present_e5500_sfx_0")
++
++;; SFX.
++(define_insn_reservation "e5500_sfx" 1
++  (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\
++      shift,cntlz,exts")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx")
++
++(define_insn_reservation "e5500_sfx2" 2
++  (and (eq_attr "type" "cmp,compare,fast_compare,trap")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx")
++
++(define_insn_reservation "e5500_delayed" 2
++  (and (eq_attr "type" "var_shift_rotate,var_delayed_compare,popcnt")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx*2")
++
++(define_insn_reservation "e5500_two" 2
++  (and (eq_attr "type" "two")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_decode+e5500_sfx,e5500_sfx")
++
++(define_insn_reservation "e5500_three" 3
++  (and (eq_attr "type" "three")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,(e5500_decode+e5500_sfx)*2,e5500_sfx")
++
++;; SFX - Mfcr.
++(define_insn_reservation "e5500_mfcr" 4
++  (and (eq_attr "type" "mfcr")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx_0*4")
++
++;; SFX - Mtcrf.
++(define_insn_reservation "e5500_mtcrf" 1
++  (and (eq_attr "type" "mtcr")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx_0")
++
++;; SFX - Mtjmpr.
++(define_insn_reservation "e5500_mtjmpr" 1
++  (and (eq_attr "type" "mtjmpr,mfjmpr")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_sfx")
++
++;; CFX - Multiply.
++(define_insn_reservation "e5500_multiply" 4
++  (and (eq_attr "type" "imul")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_cfx_stage0,e5500_cfx_stage1")
++
++(define_insn_reservation "e5500_multiply_i" 5
++  (and (eq_attr "type" "imul2,imul3,imul_compare")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_cfx_stage0,\
++   e5500_cfx_stage0+e5500_cfx_stage1,e5500_cfx_stage1")
++
++;; CFX - Divide.
++(define_insn_reservation "e5500_divide" 16
++  (and (eq_attr "type" "idiv")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\
++   e5500_cfx_div*15")
++
++(define_insn_reservation "e5500_divide_d" 26
++  (and (eq_attr "type" "ldiv")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\
++   e5500_cfx_div*25")
++
++;; LSU - Loads.
++(define_insn_reservation "e5500_load" 3
++  (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
++                      load_l,sync")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_lsu")
++
++(define_insn_reservation "e5500_fpload" 4
++  (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_lsu")
++
++;; LSU - Stores.
++(define_insn_reservation "e5500_store" 3
++  (and (eq_attr "type" "store,store_ux,store_u,store_c")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_lsu")
++
++(define_insn_reservation "e5500_fpstore" 3
++  (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_lsu")
++
++;; FP.
++(define_insn_reservation "e5500_float" 7
++  (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_fpu")
++
++(define_insn_reservation "e5500_sdiv" 20
++  (and (eq_attr "type" "sdiv")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_fpu*20")
++
++(define_insn_reservation "e5500_ddiv" 35
++  (and (eq_attr "type" "ddiv")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_fpu*35")
++
++;; BU.
++(define_insn_reservation "e5500_branch" 1
++  (and (eq_attr "type" "jmpreg,branch,isync")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_bu")
++
++;; BU - CR logical.
++(define_insn_reservation "e5500_cr_logical" 1
++  (and (eq_attr "type" "cr_logical,delayed_cr")
++       (eq_attr "cpu" "ppce5500"))
++  "e5500_decode,e5500_bu")
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/e6500.md gcc-4.6.2/gcc/config/rs6000/e6500.md
+--- gcc-4.6.2-orig/gcc/config/rs6000/e6500.md  1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/e6500.md       2012-03-06 12:16:25.573039002 -0600
+@@ -0,0 +1,213 @@
++;; Pipeline description for Freescale PowerPC e6500 core.
++;;   Copyright (C) 2011 Free Software Foundation, Inc.
++;;   Contributed by Edmar Wienskoski (edmar@freescale.com)
++;;
++;; This file is part of GCC.
++;;
++;; GCC is free software; you can redistribute it and/or modify it
++;; under the terms of the GNU General Public License as published
++;; by the Free Software Foundation; either version 3, or (at your
++;; option) any later version.
++;;
++;; GCC is distributed in the hope that it will be useful, but WITHOUT
++;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
++;; License for more details.
++;;
++;; You should have received a copy of the GNU General Public License
++;; along with GCC; see the file COPYING3.  If not see
++;; <http://www.gnu.org/licenses/>.
++;;
++;; e6500 64-bit SFX(2), CFX, LSU, FPU, BU, VSFX, VCFX, VFPU, VPERM
++;; Max issue 3 insns/clock cycle (includes 1 branch)
++
++(define_automaton "e6500_most,e6500_long,e6500_vec")
++(define_cpu_unit "e6500_decode_0,e6500_decode_1" "e6500_most")
++
++;; SFX.
++(define_cpu_unit "e6500_sfx_0,e6500_sfx_1" "e6500_most")
++
++;; CFX.
++(define_cpu_unit "e6500_cfx_stage0,e6500_cfx_stage1" "e6500_most")
++
++;; Non-pipelined division.
++(define_cpu_unit "e6500_cfx_div" "e6500_long")
++
++;; LSU.
++(define_cpu_unit "e6500_lsu" "e6500_most")
++
++;; FPU.
++(define_cpu_unit "e6500_fpu" "e6500_long")
++
++;; BU.
++(define_cpu_unit "e6500_bu" "e6500_most")
++
++;; Altivec unit
++(define_cpu_unit "e6500_vec,e6500_vecperm" "e6500_vec")
++
++;; The following units are used to make the automata deterministic.
++(define_cpu_unit "present_e6500_decode_0" "e6500_most")
++(define_cpu_unit "present_e6500_sfx_0" "e6500_most")
++(presence_set "present_e6500_decode_0" "e6500_decode_0")
++(presence_set "present_e6500_sfx_0" "e6500_sfx_0")
++
++;; Some useful abbreviations.
++(define_reservation "e6500_decode"
++    "e6500_decode_0|e6500_decode_1+present_e6500_decode_0")
++(define_reservation "e6500_sfx"
++   "e6500_sfx_0|e6500_sfx_1+present_e6500_sfx_0")
++
++;; SFX.
++(define_insn_reservation "e6500_sfx" 1
++  (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\
++      shift,cntlz,exts")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx")
++
++(define_insn_reservation "e6500_sfx2" 2
++  (and (eq_attr "type" "cmp,compare,fast_compare,trap")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx")
++
++(define_insn_reservation "e6500_delayed" 2
++  (and (eq_attr "type" "var_shift_rotate,var_delayed_compare,popcnt")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx*2")
++
++(define_insn_reservation "e6500_two" 2
++  (and (eq_attr "type" "two")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_decode+e6500_sfx,e6500_sfx")
++
++(define_insn_reservation "e6500_three" 3
++  (and (eq_attr "type" "three")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,(e6500_decode+e6500_sfx)*2,e6500_sfx")
++
++;; SFX - Mfcr.
++(define_insn_reservation "e6500_mfcr" 4
++  (and (eq_attr "type" "mfcr")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx_0*4")
++
++;; SFX - Mtcrf.
++(define_insn_reservation "e6500_mtcrf" 1
++  (and (eq_attr "type" "mtcr")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx_0")
++
++;; SFX - Mtjmpr.
++(define_insn_reservation "e6500_mtjmpr" 1
++  (and (eq_attr "type" "mtjmpr,mfjmpr")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_sfx")
++
++;; CFX - Multiply.
++(define_insn_reservation "e6500_multiply" 4
++  (and (eq_attr "type" "imul")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_cfx_stage0,e6500_cfx_stage1")
++
++(define_insn_reservation "e6500_multiply_i" 5
++  (and (eq_attr "type" "imul2,imul3,imul_compare")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_cfx_stage0,\
++   e6500_cfx_stage0+e6500_cfx_stage1,e6500_cfx_stage1")
++
++;; CFX - Divide.
++(define_insn_reservation "e6500_divide" 16
++  (and (eq_attr "type" "idiv")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\
++   e6500_cfx_div*15")
++
++(define_insn_reservation "e6500_divide_d" 26
++  (and (eq_attr "type" "ldiv")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\
++   e6500_cfx_div*25")
++
++;; LSU - Loads.
++(define_insn_reservation "e6500_load" 3
++  (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
++                      load_l,sync")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++(define_insn_reservation "e6500_fpload" 4
++  (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++(define_insn_reservation "e6500_vecload" 4
++  (and (eq_attr "type" "vecload")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++;; LSU - Stores.
++(define_insn_reservation "e6500_store" 3
++  (and (eq_attr "type" "store,store_ux,store_u,store_c")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++(define_insn_reservation "e6500_fpstore" 3
++  (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++(define_insn_reservation "e6500_vecstore" 4
++  (and (eq_attr "type" "vecstore")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_lsu")
++
++;; FP.
++(define_insn_reservation "e6500_float" 7
++  (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_fpu")
++
++(define_insn_reservation "e6500_sdiv" 20
++  (and (eq_attr "type" "sdiv")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_fpu*20")
++
++(define_insn_reservation "e6500_ddiv" 35
++  (and (eq_attr "type" "ddiv")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_fpu*35")
++
++;; BU.
++(define_insn_reservation "e6500_branch" 1
++  (and (eq_attr "type" "jmpreg,branch,isync")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_bu")
++
++;; BU - CR logical.
++(define_insn_reservation "e6500_cr_logical" 1
++  (and (eq_attr "type" "cr_logical,delayed_cr")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_bu")
++
++;; VSFX.
++(define_insn_reservation "e6500_vecsimple" 1
++  (and (eq_attr "type" "vecsimple,veccmp")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_vec")
++
++;; VCFX.
++(define_insn_reservation "e6500_veccomplex" 4
++  (and (eq_attr "type" "veccomplex")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_vec")
++
++;; VFPU.
++(define_insn_reservation "e6500_vecfloat" 6
++  (and (eq_attr "type" "vecfloat")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_vec")
++
++;; VPERM.
++(define_insn_reservation "e6500_vecperm" 2
++  (and (eq_attr "type" "vecperm")
++       (eq_attr "cpu" "ppce6500"))
++  "e6500_decode,e6500_vecperm")
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000-builtin.def gcc-4.6.2/gcc/config/rs6000/rs6000-builtin.def
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000-builtin.def        2011-02-21 15:38:21.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000-builtin.def     2012-03-06 12:37:40.248039025 -0600
+@@ -224,6 +224,9 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEBX,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEHX,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEWX,                 RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEXBX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEXHX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVEXWX,                        RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVXL,                  RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVX,                   RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVX,                  RS6000_BTC_MEM)
+@@ -231,14 +234,30 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVLXL,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVRX,                  RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_LVRXL,                 RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVTLX,                 RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVTLXL,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVTRX,                 RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVTRXL,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVSWX,                 RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVSWXL,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_LVSM,                  RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEBX,                        RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEHX,                        RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEWX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEXBX,                       RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEXHX,                       RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVEXWX,                       RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVXL,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVLX,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVLXL,                        RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVRX,                 RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_STVRXL,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVFLX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVFLXL,                       RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVFRX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVFRXL,                       RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVSWX,                        RS6000_BTC_MEM)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_STVSWXL,                       RS6000_BTC_MEM)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VCMPBFP_P,             RS6000_BTC_FP_PURE)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VCMPEQFP_P,            RS6000_BTC_FP_PURE)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VCMPEQUB_P,            RS6000_BTC_CONST)
+@@ -275,6 +294,9 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_EXT_V4SF,          RS6000_BTC_CONST)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_COPYSIGN_V4SF,         RS6000_BTC_CONST)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VRECIPFP,              RS6000_BTC_FP_PURE)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_ABSDUB,                        RS6000_BTC_CONST)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_ABSDUH,                        RS6000_BTC_CONST)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_ABSDUW,                        RS6000_BTC_CONST)
+ /* Altivec overloaded builtins.  */
+ /* For now, don't set the classification for overloaded functions.
+@@ -286,6 +308,7 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VCMPGT_P,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VCMPGE_P,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_ABS,                       RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_ABSD,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_ABSS,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_ADD,                       RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_ADDC,              RS6000_BTC_MISC)
+@@ -321,10 +344,20 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEBX,             RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEHX,             RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEWX,             RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEXBX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEXHX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVEXWX,            RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVLX,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVLXL,             RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVRX,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVRXL,             RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVTLX,             RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVTLXL,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVTRX,             RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVTRXL,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVSWX,             RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVSWXL,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVSM,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVSL,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_LVSR,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_MADD,              RS6000_BTC_MISC)
+@@ -389,10 +422,19 @@
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEBX,            RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEHX,            RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEWX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEXBX,           RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEXHX,           RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVEXWX,           RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVLX,             RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVLXL,            RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVRX,             RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVRXL,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVFLX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVFLXL,           RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVFRX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVFRXL,           RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVSWX,            RS6000_BTC_MISC)
++RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_STVSWXL,           RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_SUB,                       RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_SUBC,              RS6000_BTC_MISC)
+ RS6000_BUILTIN(ALTIVEC_BUILTIN_VEC_SUBS,              RS6000_BTC_MISC)
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000.c gcc-4.6.2/gcc/config/rs6000/rs6000.c
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000.c  2011-09-18 17:01:56.000000000 -0500
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.c       2012-03-06 12:44:04.689039002 -0600
+@@ -779,6 +779,44 @@
+   1,                  /* prefetch streams /*/
+ };
++/* Instruction costs on PPCE5500 processors.  */
++static const
++struct processor_costs ppce5500_cost = {
++  COSTS_N_INSNS (5),    /* mulsi */
++  COSTS_N_INSNS (5),    /* mulsi_const */
++  COSTS_N_INSNS (5),    /* mulsi_const9 */
++  COSTS_N_INSNS (5),    /* muldi */
++  COSTS_N_INSNS (14),   /* divsi */
++  COSTS_N_INSNS (14),   /* divdi */
++  COSTS_N_INSNS (7),    /* fp */
++  COSTS_N_INSNS (10),   /* dmul */
++  COSTS_N_INSNS (36),   /* sdiv */
++  COSTS_N_INSNS (66),   /* ddiv */
++  64,                 /* cache line size */
++  32,                 /* l1 cache */
++  128,                        /* l2 cache */
++  1,                  /* prefetch streams /*/
++};
++
++/* Instruction costs on PPCE6500 processors.  */
++static const
++struct processor_costs ppce6500_cost = {
++  COSTS_N_INSNS (5),    /* mulsi */
++  COSTS_N_INSNS (5),    /* mulsi_const */
++  COSTS_N_INSNS (5),    /* mulsi_const9 */
++  COSTS_N_INSNS (5),    /* muldi */
++  COSTS_N_INSNS (14),   /* divsi */
++  COSTS_N_INSNS (14),   /* divdi */
++  COSTS_N_INSNS (7),    /* fp */
++  COSTS_N_INSNS (10),   /* dmul */
++  COSTS_N_INSNS (36),   /* sdiv */
++  COSTS_N_INSNS (66),   /* ddiv */
++  64,                 /* cache line size */
++  32,                 /* l1 cache */
++  128,                        /* l2 cache */
++  1,                  /* prefetch streams /*/
++};
++
+ /* Instruction costs on AppliedMicro Titan processors.  */
+ static const
+ struct processor_costs titan_cost = {
+@@ -1690,7 +1728,7 @@
+                  | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
+                  | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
+                  | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
+-                 | MASK_RECIP_PRECISION)
++                 | MASK_RECIP_PRECISION | MASK_ALTIVEC2)
+ };
+ /* Masks for instructions set at various powerpc ISAs.  */
+@@ -1785,6 +1823,12 @@
+    | MASK_ISEL},
+   {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
+    | MASK_PPC_GFXOPT | MASK_ISEL},
++  {"e5500", PROCESSOR_PPCE5500, POWERPC_BASE_MASK | MASK_POWERPC64
++   | MASK_PPC_GFXOPT | MASK_ISEL | MASK_CMPB | MASK_POPCNTB
++   | MASK_POPCNTD},
++  {"e6500", PROCESSOR_PPCE6500, POWERPC_7400_MASK | MASK_POWERPC64
++   | MASK_MFCRF | MASK_ISEL | MASK_CMPB | MASK_POPCNTB | MASK_POPCNTD
++   | MASK_ALTIVEC2},
+   {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+   {"970", PROCESSOR_POWER4,
+    POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+@@ -2742,13 +2786,19 @@
+                  : PROCESSOR_DEFAULT));
+   if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
+-      || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
++      || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64
++      || rs6000_cpu == PROCESSOR_PPCE5500)
+     {
+       if (TARGET_ALTIVEC)
+       error ("AltiVec not supported in this target");
+       if (TARGET_SPE)
+       error ("SPE not supported in this target");
+     }
++  if (rs6000_cpu == PROCESSOR_PPCE6500)
++    {
++      if (TARGET_SPE)
++      error ("SPE not supported in this target");
++    }
+   /* Disable Cell microcode if we are optimizing for the Cell
+      and not optimizing for size.  */
+@@ -2843,9 +2893,16 @@
+      user's opinion, though.  */
+   if (rs6000_block_move_inline_limit == 0
+       && (rs6000_cpu == PROCESSOR_PPCE500MC
+-        || rs6000_cpu == PROCESSOR_PPCE500MC64))
++        || rs6000_cpu == PROCESSOR_PPCE500MC64
++        || rs6000_cpu == PROCESSOR_PPCE5500
++        || rs6000_cpu == PROCESSOR_PPCE6500))
+     rs6000_block_move_inline_limit = 128;
++  /* Those machines does not have fsqrt instruction */
++  if (rs6000_cpu == PROCESSOR_PPCE5500
++      || rs6000_cpu == PROCESSOR_PPCE6500)
++    target_flags &= ~MASK_PPC_GPOPT;
++
+   /* store_one_arg depends on expand_block_move to handle at least the
+      size of reg_parm_stack_space.  */
+   if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
+@@ -2977,7 +3034,9 @@
+ #endif
+   if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
+-      || rs6000_cpu == PROCESSOR_PPCE500MC64)
++      || rs6000_cpu == PROCESSOR_PPCE500MC64
++      || rs6000_cpu == PROCESSOR_PPCE5500
++      || rs6000_cpu == PROCESSOR_PPCE6500)
+     {
+       /* The e500 and e500mc do not have string instructions, and we set
+        MASK_STRING above when optimizing for size.  */
+@@ -3024,7 +3083,9 @@
+                                || rs6000_cpu == PROCESSOR_POWER6
+                                || rs6000_cpu == PROCESSOR_POWER7
+                                || rs6000_cpu == PROCESSOR_PPCE500MC
+-                               || rs6000_cpu == PROCESSOR_PPCE500MC64);
++                               || rs6000_cpu == PROCESSOR_PPCE500MC64
++                               || rs6000_cpu == PROCESSOR_PPCE5500
++                               || rs6000_cpu == PROCESSOR_PPCE6500);
+   /* Allow debug switches to override the above settings.  These are set to -1
+      in rs6000.opt to indicate the user hasn't directly set the switch.  */
+@@ -3246,6 +3307,14 @@
+       rs6000_cost = &ppce500mc64_cost;
+       break;
++      case PROCESSOR_PPCE5500:
++      rs6000_cost = &ppce5500_cost;
++      break;
++
++      case PROCESSOR_PPCE6500:
++      rs6000_cost = &ppce6500_cost;
++      break;
++
+       case PROCESSOR_TITAN:
+       rs6000_cost = &titan_cost;
+       break;
+@@ -10212,6 +10281,9 @@
+   { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
+   { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
+   { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
++  { MASK_ALTIVEC2, CODE_FOR_altivec_vabsdub, "__builtin_altivec_vabsdub", ALTIVEC_BUILTIN_ABSDUB },
++  { MASK_ALTIVEC2, CODE_FOR_altivec_vabsduh, "__builtin_altivec_vabsduh", ALTIVEC_BUILTIN_ABSDUH },
++  { MASK_ALTIVEC2, CODE_FOR_altivec_vabsduw, "__builtin_altivec_vabsduw", ALTIVEC_BUILTIN_ABSDUW },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
+   { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
+@@ -10372,6 +10444,7 @@
+   { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
+   { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
++  { MASK_ALTIVEC2, CODE_FOR_nothing, "__builtin_vec_absd", ALTIVEC_BUILTIN_VEC_ABSD },
+   { 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 },
+@@ -11803,6 +11876,12 @@
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
+     case ALTIVEC_BUILTIN_STVEWX:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
++    case ALTIVEC_BUILTIN_STVEXBX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexbx, exp);
++    case ALTIVEC_BUILTIN_STVEXHX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexhx, exp);
++    case ALTIVEC_BUILTIN_STVEXWX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvexwx, exp);
+     case ALTIVEC_BUILTIN_STVXL:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
+@@ -11814,6 +11893,18 @@
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
+     case ALTIVEC_BUILTIN_STVRXL:
+       return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
++    case ALTIVEC_BUILTIN_STVFLX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvflx, exp);
++    case ALTIVEC_BUILTIN_STVFLXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvflxl, exp);
++    case ALTIVEC_BUILTIN_STVFRX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvfrx, exp);
++    case ALTIVEC_BUILTIN_STVFRXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvfrxl, exp);
++    case ALTIVEC_BUILTIN_STVSWX:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvswx, exp);
++    case ALTIVEC_BUILTIN_STVSWXL:
++      return altivec_expand_stv_builtin (CODE_FOR_altivec_stvswxl, exp);
+     case VSX_BUILTIN_STXVD2X_V2DF:
+       return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
+@@ -11948,6 +12039,15 @@
+     case ALTIVEC_BUILTIN_LVEWX:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
+                                       exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXBX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexbx,
++                                      exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXHX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexhx,
++                                      exp, target, false);
++    case ALTIVEC_BUILTIN_LVEXWX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvexwx,
++                                      exp, target, false);
+     case ALTIVEC_BUILTIN_LVXL:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
+                                       exp, target, false);
+@@ -11966,6 +12066,27 @@
+     case ALTIVEC_BUILTIN_LVRXL:
+       return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
+                                       exp, target, true);
++    case ALTIVEC_BUILTIN_LVTLX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtlx,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVTLXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtlxl,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVTRX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtrx,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVTRXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvtrxl,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVSWX:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvswx,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVSWXL:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvswxl,
++                                      exp, target, true);
++    case ALTIVEC_BUILTIN_LVSM:
++      return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsm,
++                                      exp, target, true);
+     case VSX_BUILTIN_LXVD2X_V2DF:
+       return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
+                                       exp, target, false);
+@@ -13278,6 +13399,9 @@
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvexbx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXBX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvexhx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXHX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvexwx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEXWX);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
+@@ -13285,6 +13409,9 @@
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
+   def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvexbx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEXBX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvexhx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEXHX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvexwx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEXWX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
+@@ -13293,12 +13420,18 @@
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvexbx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXBX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvexhx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXHX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvexwx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEXWX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvexwx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvexbx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXBX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvexhx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEXHX);
+   def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
+              VSX_BUILTIN_LXVD2X_V2DF);
+@@ -13351,6 +13484,33 @@
+       def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
+       def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
+     }
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvtlx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTLX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvtlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTLXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvtrx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTRX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvtrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVTRXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvtlx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTLX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvtlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTLXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvtrx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTRX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvtrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVTRXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvflx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFLX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvflxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFLXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvfrx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFRX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvfrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVFRXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvflx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFLX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvflxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFLXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvfrx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFRX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvfrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVFRXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvswx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvswxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSWXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvswx",  v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvswxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSWXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_lvsm", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSM);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_lvsm", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSM);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvswx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVSWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_altivec_stvswxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVSWXL);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvswx",  void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVSWX);
++  def_builtin (MASK_ALTIVEC2, "__builtin_vec_stvswxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVSWXL);
++
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
+   def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
+@@ -13668,6 +13828,9 @@
+     case ALTIVEC_BUILTIN_VMULEUH_UNS:
+     case ALTIVEC_BUILTIN_VMULOUB_UNS:
+     case ALTIVEC_BUILTIN_VMULOUH_UNS:
++    case ALTIVEC_BUILTIN_ABSDUB:
++    case ALTIVEC_BUILTIN_ABSDUH:
++    case ALTIVEC_BUILTIN_ABSDUW:
+       h.uns_p[0] = 1;
+       h.uns_p[1] = 1;
+       h.uns_p[2] = 1;
+@@ -23250,6 +23413,7 @@
+                  || rs6000_cpu_attr == CPU_PPC750
+                  || rs6000_cpu_attr == CPU_PPC7400
+                  || rs6000_cpu_attr == CPU_PPC7450
++                 || rs6000_cpu_attr == CPU_PPCE5500
+                  || rs6000_cpu_attr == CPU_POWER4
+                  || rs6000_cpu_attr == CPU_POWER5
+                || rs6000_cpu_attr == CPU_POWER7
+@@ -23794,6 +23958,8 @@
+   case CPU_PPCE300C3:
+   case CPU_PPCE500MC:
+   case CPU_PPCE500MC64:
++  case CPU_PPCE5500:
++  case CPU_PPCE6500:
+   case CPU_TITAN:
+     return 2;
+   case CPU_RIOS2:
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000-c.c gcc-4.6.2/gcc/config/rs6000/rs6000-c.c
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000-c.c        2011-02-02 23:42:19.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000-c.c     2012-03-06 12:54:55.964038969 -0600
+@@ -310,6 +310,8 @@
+         /* Enable context-sensitive macros.  */
+         cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand;
+       }
++      if (TARGET_ALTIVEC2)
++      builtin_define ("__ALTIVEC2__");
+     }
+   if (rs6000_cpu == PROCESSOR_CELL)
+     builtin_define ("__PPU__");
+@@ -569,6 +571,24 @@
+     RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
+   /* Binary AltiVec/VSX builtins.  */
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUB,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUH,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_ABSD, ALTIVEC_BUILTIN_ABSDUW,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 },
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+     RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
+@@ -1084,6 +1104,24 @@
+     RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXWX, ALTIVEC_BUILTIN_LVEXWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXHX, ALTIVEC_BUILTIN_LVEXHX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXHX, ALTIVEC_BUILTIN_LVEXHX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXBX, ALTIVEC_BUILTIN_LVEXBX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVEXBX, ALTIVEC_BUILTIN_LVEXBX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL,
+     RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
+   { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL,
+@@ -1336,6 +1374,258 @@
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLX, ALTIVEC_BUILTIN_LVTLX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTLXL, ALTIVEC_BUILTIN_LVTLXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRX, ALTIVEC_BUILTIN_LVTRX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVTRXL, ALTIVEC_BUILTIN_LVTRXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWX, ALTIVEC_BUILTIN_LVSWX,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSWXL, ALTIVEC_BUILTIN_LVSWXL,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 },
++  { ALTIVEC_BUILTIN_VEC_LVSM, ALTIVEC_BUILTIN_LVSM,
++    RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 },
+   { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB,
+     RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+   { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB,
+@@ -2812,6 +3102,46 @@
+     RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
+   { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX,
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXWX, ALTIVEC_BUILTIN_STVEXWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXHX, ALTIVEC_BUILTIN_STVEXHX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
++  { ALTIVEC_BUILTIN_VEC_STVEXBX, ALTIVEC_BUILTIN_STVEXBX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void },
+   { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL,
+     RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
+   { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL,
+@@ -3016,6 +3346,222 @@
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
+   { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL,
+     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLX, ALTIVEC_BUILTIN_STVFLX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFLXL, ALTIVEC_BUILTIN_STVFLXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRX, ALTIVEC_BUILTIN_STVFRX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVFRXL, ALTIVEC_BUILTIN_STVFRXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWX, ALTIVEC_BUILTIN_STVSWX,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
++  { ALTIVEC_BUILTIN_VEC_STVSWXL, ALTIVEC_BUILTIN_STVSWXL,
++    RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
+   { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+     RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
+   { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000.h gcc-4.6.2/gcc/config/rs6000/rs6000.h
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000.h  2011-07-27 13:17:15.000000000 -0500
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.h       2012-03-06 12:16:25.582039002 -0600
+@@ -168,6 +168,8 @@
+ %{mcpu=e300c3: -me300} \
+ %{mcpu=e500mc: -me500mc} \
+ %{mcpu=e500mc64: -me500mc64} \
++%{mcpu=e5500: -me5500} \
++%{mcpu=e6500: -me6500} \
+ %{maltivec: -maltivec} \
+ %{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \
+ -many"
+@@ -477,13 +479,15 @@
+ #define TARGET_FCTIDZ TARGET_FCFID
+ #define TARGET_STFIWX TARGET_PPC_GFXOPT
+-#define TARGET_LFIWAX TARGET_CMPB
+-#define TARGET_LFIWZX TARGET_POPCNTD
+-#define TARGET_FCFIDS TARGET_POPCNTD
+-#define TARGET_FCFIDU TARGET_POPCNTD
+-#define TARGET_FCFIDUS        TARGET_POPCNTD
+-#define TARGET_FCTIDUZ        TARGET_POPCNTD
+-#define TARGET_FCTIWUZ        TARGET_POPCNTD
++#define TARGET_LFIWAX (TARGET_CMPB && rs6000_cpu != PROCESSOR_PPCE5500 \
++                       && rs6000_cpu != PROCESSOR_PPCE6500)
++#define TARGET_LFIWZX (TARGET_POPCNTD && rs6000_cpu != PROCESSOR_PPCE5500 \
++                       && rs6000_cpu != PROCESSOR_PPCE6500)
++#define TARGET_FCFIDS TARGET_LFIWZX
++#define TARGET_FCFIDU TARGET_LFIWZX
++#define TARGET_FCFIDUS        TARGET_LFIWZX
++#define TARGET_FCTIDUZ        TARGET_LFIWZX
++#define TARGET_FCTIWUZ        TARGET_LFIWZX
+ /* E500 processors only support plain "sync", not lwsync.  */
+ #define TARGET_NO_LWSYNC TARGET_E500
+@@ -494,10 +498,14 @@
+ #define TARGET_FRE    (TARGET_HARD_FLOAT && TARGET_FPRS \
+                        && TARGET_DOUBLE_FLOAT \
+-                       && (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)))
++                       && (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) \
++                       && rs6000_cpu != PROCESSOR_PPCE5500 \
++                       && rs6000_cpu != PROCESSOR_PPCE6500)
+ #define TARGET_FRSQRTES       (TARGET_HARD_FLOAT && TARGET_POPCNTB \
+-                       && TARGET_FPRS && TARGET_SINGLE_FLOAT)
++                       && TARGET_FPRS && TARGET_SINGLE_FLOAT \
++                       && rs6000_cpu != PROCESSOR_PPCE5500 \
++                       && rs6000_cpu != PROCESSOR_PPCE6500)
+ #define TARGET_FRSQRTE        (TARGET_HARD_FLOAT && TARGET_FPRS \
+                        && TARGET_DOUBLE_FLOAT \
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000.md gcc-4.6.2/gcc/config/rs6000/rs6000.md
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000.md 2011-09-19 11:41:20.000000000 -0500
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.md      2012-03-06 12:16:25.584039002 -0600
+@@ -126,7 +126,7 @@
\f
+ ;; Define an insn type attribute.  This is used in function unit delay
+ ;; computations.
+-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel"
++(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt"
+   (const_string "integer"))
+ ;; Define floating point instruction sub-types for use with Xfpu.md
+@@ -148,7 +148,7 @@
+ ;; Processor type -- this attribute must exactly match the processor_type
+ ;; enumeration in rs6000.h.
+-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2,titan"
++(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,power4,power5,power6,power7,cell,ppca2,titan"
+   (const (symbol_ref "rs6000_cpu_attr")))
+@@ -176,6 +176,8 @@
+ (include "e300c2c3.md")
+ (include "e500mc.md")
+ (include "e500mc64.md")
++(include "e5500.md")
++(include "e6500.md")
+ (include "power4.md")
+ (include "power5.md")
+ (include "power6.md")
+@@ -2302,13 +2304,17 @@
+         (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
+                      UNSPEC_POPCNTB))]
+   "TARGET_POPCNTB"
+-  "popcntb %0,%1")
++  "popcntb %0,%1"
++  [(set_attr "length" "4")
++   (set_attr "type" "popcnt")])
+ (define_insn "popcntd<mode>2"
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+       (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
+   "TARGET_POPCNTD"
+-  "popcnt<wd> %0,%1")
++  "popcnt<wd> %0,%1"
++  [(set_attr "length" "4")
++   (set_attr "type" "popcnt")])
+ (define_expand "popcount<mode>2"
+   [(set (match_operand:GPR 0 "gpc_reg_operand" "")
+@@ -5957,10 +5963,10 @@
+    && ((TARGET_PPC_GFXOPT
+         && !HONOR_NANS (<MODE>mode)
+         && !HONOR_SIGNED_ZEROS (<MODE>mode))
+-       || TARGET_CMPB
++       || TARGET_LFIWAX
+        || VECTOR_UNIT_VSX_P (<MODE>mode))"
+ {
+-  if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
++  if (TARGET_LFIWAX || VECTOR_UNIT_VSX_P (<MODE>mode))
+     {
+       emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
+                                            operands[2]));
+@@ -5979,7 +5985,7 @@
+       (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")
+                     (match_operand:SFDF 2 "gpc_reg_operand" "<rreg2>")]
+                    UNSPEC_COPYSIGN))]
+-  "TARGET_CMPB && !VECTOR_UNIT_VSX_P (<MODE>mode)"
++  "TARGET_LFIWAX && !VECTOR_UNIT_VSX_P (<MODE>mode)"
+   "fcpsgn %0,%2,%1"
+   [(set_attr "type" "fp")])
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000.opt gcc-4.6.2/gcc/config/rs6000/rs6000.opt
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000.opt        2010-11-29 19:47:54.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000.opt     2012-03-06 12:16:25.584039002 -0600
+@@ -179,6 +179,10 @@
+ Target Report Mask(ALTIVEC) Save
+ Use AltiVec instructions
++maltivec2
++Target Report Mask(ALTIVEC2) Save
++Use AltiVec PowerPC V2.07 instructions
++
+ mhard-dfp
+ Target Report Mask(DFP) Save
+ Use decimal floating point instructions
+diff -ruN gcc-4.6.2-orig/gcc/config/rs6000/rs6000-opts.h gcc-4.6.2/gcc/config/rs6000/rs6000-opts.h
+--- gcc-4.6.2-orig/gcc/config/rs6000/rs6000-opts.h     2010-11-19 11:27:18.000000000 -0600
++++ gcc-4.6.2/gcc/config/rs6000/rs6000-opts.h  2012-03-06 12:16:25.584039002 -0600
+@@ -53,6 +53,8 @@
+    PROCESSOR_PPCE300C3,
+    PROCESSOR_PPCE500MC,
+    PROCESSOR_PPCE500MC64,
++   PROCESSOR_PPCE5500,
++   PROCESSOR_PPCE6500,
+    PROCESSOR_POWER4,
+    PROCESSOR_POWER5,
+    PROCESSOR_POWER6,
+diff -ruN gcc-4.6.2-orig/gcc/config.gcc gcc-4.6.2/gcc/config.gcc
+--- gcc-4.6.2-orig/gcc/config.gcc      2011-07-22 11:44:50.000000000 -0500
++++ gcc-4.6.2/gcc/config.gcc   2012-03-06 12:16:25.585039002 -0600
+@@ -396,7 +396,7 @@
+       extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h"
+       need_64bit_hwint=yes
+       case x$with_cpu in
+-          xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2|xe500mc64)
++          xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[34567]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|Xe6500)
+               cpu_is_64bit=yes
+               ;;
+       esac
+@@ -3501,8 +3501,8 @@
+                       | 401 | 403 | 405 | 405fp | 440 | 440fp | 464 | 464fp \
+                       | 476 | 476fp | 505 | 601 | 602 | 603 | 603e | ec603e \
+                       | 604 | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \
+-                      | a2 | e300c[23] | 854[08] | e500mc | e500mc64 | titan\
+-                      | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell)
++                      | a2 | e300c[23] | 854[08] | e500mc | e500mc64 | e5500 | e6500 \
++                      | titan | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5 | cell)
+                               # OK
+                               ;;
+                       *)
+diff -ruN gcc-4.6.2-orig/gcc/doc/extend.texi gcc-4.6.2/gcc/doc/extend.texi
+--- gcc-4.6.2-orig/gcc/doc/extend.texi 2011-10-24 09:55:45.000000000 -0500
++++ gcc-4.6.2/gcc/doc/extend.texi      2012-03-06 12:56:49.399039002 -0600
+@@ -12509,6 +12509,291 @@
+ @samp{vec_vsx_st} builtins will always generate the VSX @samp{LXVD2X},
+ @samp{LXVW4X}, @samp{STXVD2X}, and @samp{STXVW4X} instructions.
++Using @option{-maltivec2} will extend the Altivec interface with the
++following additional functions:
++
++@smallexample
++vector unsigned char vec_absd (vector unsigned char, vector unsigned char);
++vector unsigned char vec_absd (vector bool char, vector unsigned char);
++vector unsigned char vec_absd (vector unsigned char, vector bool char);
++vector unsigned short vec_absd (vector unsigned short, vector unsigned short);
++vector unsigned short vec_absd (vector bool short, vector unsigned short);
++vector unsigned short vec_absd (vector unsigned short, vector bool short);
++vector unsigned int vec_absd (vector unsigned int, vector unsigned int);
++vector unsigned int vec_absd (vector bool int, vector unsigned int);
++vector unsigned int vec_absd (vector unsigned int, vector bool int);
++
++vector signed char vec_lvexbx (long, signed char *);
++vector unsigned char vec_lvexbx (long, unsigned char *);
++vector signed short vec_lvexhx (long, signed short *);
++vector unsigned short vec_lvexhx (long, unsigned short *);
++vector float vec_lvexwx (long, float *);
++vector signed int vec_lvexwx (long, signed int *);
++vector unsigned int vec_lvexwx (long, unsigned int *);
++vector signed int vec_lvexwx (long, signed long *);
++vector unsigned int vec_lvexwx (long, unsigned long *);
++
++void vec_stvexbx (vector signed char, long, signed char *);
++void vec_stvexbx (vector unsigned char, long, unsigned char *);
++void vec_stvexbx (vector bool char, long, signed char *);
++void vec_stvexbx (vector bool char, long, unsigned char *);
++void vec_stvexbx (vector signed char, long, void *);
++void vec_stvexbx (vector unsigned char, long, void *);
++void vec_stvexhx (vector signed short, long, signed short *);
++void vec_stvexhx (vector unsigned short, long, unsigned short *);
++void vec_stvexhx (vector bool short, long, signed short *);
++void vec_stvexhx (vector bool short, long, unsigned short *);
++void vec_stvexhx (vector signed short, long, void *);
++void vec_stvexhx (vector unsigned short, long, void *);
++void vec_stvexwx (vector float, long, float *);
++void vec_stvexwx (vector signed int, long, signed int *);
++void vec_stvexwx (vector unsigned int, long, unsigned int *);
++void vec_stvexwx (vector bool int, long, signed int *);
++void vec_stvexwx (vector bool int, long, unsigned int *);
++void vec_stvexwx (vector float, long, void *);
++void vec_stvexwx (vector signed int, long, void *);
++void vec_stvexwx (vector unsigned int, long, void *);
++
++vector float vec_lvtlx (long, vector float *);
++vector float vec_lvtlx (long, float *);
++vector bool int vec_lvtlx (long, vector bool int *);
++vector signed int vec_lvtlx (long, vector signed int *);
++vector signed int vec_lvtlx (long, signed int *);
++vector unsigned int vec_lvtlx (long, vector unsigned int *);
++vector unsigned int vec_lvtlx (long, unsigned int *);
++vector bool short vec_lvtlx (long, vector bool short *);
++vector pixel vec_lvtlx (long, vector pixel *);
++vector signed short vec_lvtlx (long, vector signed short *);
++vector signed short vec_lvtlx (long, signed short *);
++vector unsigned short vec_lvtlx (long, vector unsigned short *);
++vector unsigned short vec_lvtlx (long, unsigned short *);
++vector bool char vec_lvtlx (long, vector bool char *);
++vector signed char vec_lvtlx (long, vector signed char *);
++vector signed char vec_lvtlx (long, signed char *);
++vector unsigned char vec_lvtlx (long, vector unsigned char *);
++vector unsigned char vec_lvtlx (long, unsigned char *);
++vector float vec_lvtlxl (long, vector float *);
++vector float vec_lvtlxl (long, float *);
++vector bool int vec_lvtlxl (long, vector bool int *);
++vector signed int vec_lvtlxl (long, vector signed int *);
++vector signed int vec_lvtlxl (long, signed int *);
++vector unsigned int vec_lvtlxl (long, vector unsigned int *);
++vector unsigned int vec_lvtlxl (long, unsigned int *);
++vector bool short vec_lvtlxl (long, vector bool short *);
++vector pixel vec_lvtlxl (long, vector pixel *);
++vector signed short vec_lvtlxl (long, vector signed short *);
++vector signed short vec_lvtlxl (long, signed short *);
++vector unsigned short vec_lvtlxl (long, vector unsigned short *);
++vector unsigned short vec_lvtlxl (long, unsigned short *);
++vector bool char vec_lvtlxl (long, vector bool char *);
++vector signed char vec_lvtlxl (long, vector signed char *);
++vector signed char vec_lvtlxl (long, signed char *);
++vector unsigned char vec_lvtlxl (long, vector unsigned char *);
++vector unsigned char vec_lvtlxl (long, unsigned char *);
++vector float vec_lvtrx (long, vector float *);
++vector float vec_lvtrx (long, float *);
++vector bool int vec_lvtrx (long, vector bool int *);
++vector signed int vec_lvtrx (long, vector signed int *);
++vector signed int vec_lvtrx (long, signed int *);
++vector unsigned int vec_lvtrx (long, vector unsigned int *);
++vector unsigned int vec_lvtrx (long, unsigned int *);
++vector bool short vec_lvtrx (long, vector bool short *);
++vector pixel vec_lvtrx (long, vector pixel *);
++vector signed short vec_lvtrx (long, vector signed short *);
++vector signed short vec_lvtrx (long, signed short *);
++vector unsigned short vec_lvtrx (long, vector unsigned short *);
++vector unsigned short vec_lvtrx (long, unsigned short *);
++vector bool char vec_lvtrx (long, vector bool char *);
++vector signed char vec_lvtrx (long, vector signed char *);
++vector signed char vec_lvtrx (long, signed char *);
++vector unsigned char vec_lvtrx (long, vector unsigned char *);
++vector unsigned char vec_lvtrx (long, unsigned char *);
++vector float vec_lvtrxl (long, vector float *);
++vector float vec_lvtrxl (long, float *);
++vector bool int vec_lvtrxl (long, vector bool int *);
++vector signed int vec_lvtrxl (long, vector signed int *);
++vector signed int vec_lvtrxl (long, signed int *);
++vector unsigned int vec_lvtrxl (long, vector unsigned int *);
++vector unsigned int vec_lvtrxl (long, unsigned int *);
++vector bool short vec_lvtrxl (long, vector bool short *);
++vector pixel vec_lvtrxl (long, vector pixel *);
++vector signed short vec_lvtrxl (long, vector signed short *);
++vector signed short vec_lvtrxl (long, signed short *);
++vector unsigned short vec_lvtrxl (long, vector unsigned short *);
++vector unsigned short vec_lvtrxl (long, unsigned short *);
++vector bool char vec_lvtrxl (long, vector bool char *);
++vector signed char vec_lvtrxl (long, vector signed char *);
++vector signed char vec_lvtrxl (long, signed char *);
++vector unsigned char vec_lvtrxl (long, vector unsigned char *);
++vector unsigned char vec_lvtrxl (long, unsigned char *);
++
++void vec_stvflx (vector float, long, vector float *);
++void vec_stvflx (vector float, long, float *);
++void vec_stvflx (vector bool int, long, vector bool int *);
++void vec_stvflx (vector signed int, long, vector signed int *);
++void vec_stvflx (vector signed int, long, signed int *);
++void vec_stvflx (vector unsigned int, long, vector unsigned int *);
++void vec_stvflx (vector unsigned int, long, unsigned int *);
++void vec_stvflx (vector bool short, long, vector bool short *);
++void vec_stvflx (vector pixel, long, vector pixel *);
++void vec_stvflx (vector signed short, long, vector signed short *);
++void vec_stvflx (vector signed short, long, signed short *);
++void vec_stvflx (vector unsigned short, long, vector unsigned short *);
++void vec_stvflx (vector unsigned short, long, unsigned short *);
++void vec_stvflx (vector bool char, long, vector bool char *);
++void vec_stvflx (vector signed char, long, vector signed char *);
++void vec_stvflx (vector signed char, long, signed char *);
++void vec_stvflx (vector unsigned char, long, vector unsigned char *);
++void vec_stvflx (vector unsigned char, long, unsigned char *);
++void vec_stvflxl (vector float, long, vector float *);
++void vec_stvflxl (vector float, long, float *);
++void vec_stvflxl (vector bool int, long, vector bool int *);
++void vec_stvflxl (vector signed int, long, vector signed int *);
++void vec_stvflxl (vector signed int, long, signed int *);
++void vec_stvflxl (vector unsigned int, long, vector unsigned int *);
++void vec_stvflxl (vector unsigned int, long, unsigned int *);
++void vec_stvflxl (vector bool short, long, vector bool short *);
++void vec_stvflxl (vector pixel, long, vector pixel *);
++void vec_stvflxl (vector signed short, long, vector signed short *);
++void vec_stvflxl (vector signed short, long, signed short *);
++void vec_stvflxl (vector unsigned short, long, vector unsigned short *);
++void vec_stvflxl (vector unsigned short, long, unsigned short *);
++void vec_stvflxl (vector bool char, long, vector bool char *);
++void vec_stvflxl (vector signed char, long, vector signed char *);
++void vec_stvflxl (vector signed char, long, signed char *);
++void vec_stvflxl (vector unsigned char, long, vector unsigned char *);
++void vec_stvflxl (vector unsigned char, long, unsigned char *);
++void vec_stvfrx (vector float, long, vector float *);
++void vec_stvfrx (vector float, long, float *);
++void vec_stvfrx (vector bool int, long, vector bool int *);
++void vec_stvfrx (vector signed int, long, vector signed int *);
++void vec_stvfrx (vector signed int, long, signed int *);
++void vec_stvfrx (vector unsigned int, long, vector unsigned int *);
++void vec_stvfrx (vector unsigned int, long, unsigned int *);
++void vec_stvfrx (vector bool short, long, vector bool short *);
++void vec_stvfrx (vector pixel, long, vector pixel *);
++void vec_stvfrx (vector signed short, long, vector signed short *);
++void vec_stvfrx (vector signed short, long, signed short *);
++void vec_stvfrx (vector unsigned short, long, vector unsigned short *);
++void vec_stvfrx (vector unsigned short, long, unsigned short *);
++void vec_stvfrx (vector bool char, long, vector bool char *);
++void vec_stvfrx (vector signed char, long, vector signed char *);
++void vec_stvfrx (vector signed char, long, signed char *);
++void vec_stvfrx (vector unsigned char, long, vector unsigned char *);
++void vec_stvfrx (vector unsigned char, long, unsigned char *);
++void vec_stvfrxl (vector float, long, vector float *);
++void vec_stvfrxl (vector float, long, float *);
++void vec_stvfrxl (vector bool int, long, vector bool int *);
++void vec_stvfrxl (vector signed int, long, vector signed int *);
++void vec_stvfrxl (vector signed int, long, signed int *);
++void vec_stvfrxl (vector unsigned int, long, vector unsigned int *);
++void vec_stvfrxl (vector unsigned int, long, unsigned int *);
++void vec_stvfrxl (vector bool short, long, vector bool short *);
++void vec_stvfrxl (vector pixel, long, vector pixel *);
++void vec_stvfrxl (vector signed short, long, vector signed short *);
++void vec_stvfrxl (vector signed short, long, signed short *);
++void vec_stvfrxl (vector unsigned short, long, vector unsigned short *);
++void vec_stvfrxl (vector unsigned short, long, unsigned short *);
++void vec_stvfrxl (vector bool char, long, vector bool char *);
++void vec_stvfrxl (vector signed char, long, vector signed char *);
++void vec_stvfrxl (vector signed char, long, signed char *);
++void vec_stvfrxl (vector unsigned char, long, vector unsigned char *);
++void vec_stvfrxl (vector unsigned char, long, unsigned char *);
++
++vector float vec_lvswx (long, vector float *);
++vector float vec_lvswx (long, float *);
++vector bool int vec_lvswx (long, vector bool int *);
++vector signed int vec_lvswx (long, vector signed int *);
++vector signed int vec_lvswx (long, signed int *);
++vector unsigned int vec_lvswx (long, vector unsigned int *);
++vector unsigned int vec_lvswx (long, unsigned int *);
++vector bool short vec_lvswx (long, vector bool short *);
++vector pixel vec_lvswx (long, vector pixel *);
++vector signed short vec_lvswx (long, vector signed short *);
++vector signed short vec_lvswx (long, signed short *);
++vector unsigned short vec_lvswx (long, vector unsigned short *);
++vector unsigned short vec_lvswx (long, unsigned short *);
++vector bool char vec_lvswx (long, vector bool char *);
++vector signed char vec_lvswx (long, vector signed char *);
++vector signed char vec_lvswx (long, signed char *);
++vector unsigned char vec_lvswx (long, vector unsigned char *);
++vector unsigned char vec_lvswx (long, unsigned char *);
++vector float vec_lvswxl (long, vector float *);
++vector float vec_lvswxl (long, float *);
++vector bool int vec_lvswxl (long, vector bool int *);
++vector signed int vec_lvswxl (long, vector signed int *);
++vector signed int vec_lvswxl (long, signed int *);
++vector unsigned int vec_lvswxl (long, vector unsigned int *);
++vector unsigned int vec_lvswxl (long, unsigned int *);
++vector bool short vec_lvswxl (long, vector bool short *);
++vector pixel vec_lvswxl (long, vector pixel *);
++vector signed short vec_lvswxl (long, vector signed short *);
++vector signed short vec_lvswxl (long, signed short *);
++vector unsigned short vec_lvswxl (long, vector unsigned short *);
++vector unsigned short vec_lvswxl (long, unsigned short *);
++vector bool char vec_lvswxl (long, vector bool char *);
++vector signed char vec_lvswxl (long, vector signed char *);
++vector signed char vec_lvswxl (long, signed char *);
++vector unsigned char vec_lvswxl (long, vector unsigned char *);
++vector unsigned char vec_lvswxl (long, unsigned char *);
++
++void vec_stvswx (vector float, long, vector float *);
++void vec_stvswx (vector float, long, float  *);
++void vec_stvswx (vector bool int, long, vector bool int *);
++void vec_stvswx (vector signed int, long, vector signed int *);
++void vec_stvswx (vector signed int, long, signed int  *);
++void vec_stvswx (vector unsigned int, long, vector unsigned int *);
++void vec_stvswx (vector unsigned int, long, unsigned int  *);
++void vec_stvswx (vector bool short, long, vector bool short *);
++void vec_stvswx (vector pixel, long, vector pixel  *);
++void vec_stvswx (vector signed short, long, vector signed short *);
++void vec_stvswx (vector signed short, long, signed short  *);
++void vec_stvswx (vector unsigned short, long, vector unsigned short *);
++void vec_stvswx (vector unsigned short, long, unsigned short  *);
++void vec_stvswx (vector bool char, long, vector bool char *);
++void vec_stvswx (vector signed char, long, vector signed char *);
++void vec_stvswx (vector signed char, long, signed char  *);
++void vec_stvswx (vector unsigned char, long, vector unsigned char *);
++void vec_stvswx (vector unsigned char, long, unsigned char  *);
++void vec_stvswxl (vector float, long, vector float *);
++void vec_stvswxl (vector float, long, float  *);
++void vec_stvswxl (vector bool int, long, vector bool int *);
++void vec_stvswxl (vector signed int, long, vector signed int *);
++void vec_stvswxl (vector signed int, long, signed int  *);
++void vec_stvswxl (vector unsigned int, long, vector unsigned int *);
++void vec_stvswxl (vector unsigned int, long, unsigned int  *);
++void vec_stvswxl (vector bool short, long, vector bool short *);
++void vec_stvswxl (vector pixel, long, vector pixel  *);
++void vec_stvswxl (vector signed short, long, vector signed short *);
++void vec_stvswxl (vector signed short, long, signed short  *);
++void vec_stvswxl (vector unsigned short, long, vector unsigned short *);
++void vec_stvswxl (vector unsigned short, long, unsigned short  *);
++void vec_stvswxl (vector bool char, long, vector bool char *);
++void vec_stvswxl (vector signed char, long, vector signed char *);
++void vec_stvswxl (vector signed char, long, signed char  *);
++void vec_stvswxl (vector unsigned char, long, vector unsigned char *);
++void vec_stvswxl (vector unsigned char, long, unsigned char  *);
++
++vector float vec_lvsm (long, vector float *);
++vector float vec_lvsm (long, float *);
++vector bool int vec_lvsm (long, vector bool int *);
++vector signed int vec_lvsm (long, vector signed int *);
++vector signed int vec_lvsm (long, signed int *);
++vector unsigned int vec_lvsm (long, vector unsigned int *);
++vector unsigned int vec_lvsm (long, unsigned int *);
++vector bool short vec_lvsm (long, vector bool short *);
++vector pixel vec_lvsm (long, vector pixel *);
++vector signed short vec_lvsm (long, vector signed short *);
++vector signed short vec_lvsm (long, signed short *);
++vector unsigned short vec_lvsm (long, vector unsigned short *);
++vector unsigned short vec_lvsm (long, unsigned short *);
++vector bool char vec_lvsm (long, vector bool char *);
++vector signed char vec_lvsm (long, vector signed char *);
++vector signed char vec_lvsm (long, signed char *);
++vector unsigned char vec_lvsm (long, vector unsigned char *);
++vector unsigned char vec_lvsm (long, unsigned char *);
++@end smallexample
++
+ GCC provides a few other builtins on Powerpc to access certain instructions:
+ @smallexample
+ float __builtin_recipdivf (float, float);
+diff -ruN gcc-4.6.2-orig/gcc/doc/invoke.texi gcc-4.6.2/gcc/doc/invoke.texi
+--- gcc-4.6.2-orig/gcc/doc/invoke.texi 2011-10-24 07:22:21.000000000 -0500
++++ gcc-4.6.2/gcc/doc/invoke.texi      2012-03-06 12:56:49.402039002 -0600
+@@ -770,7 +770,7 @@
+ -mcmodel=@var{code-model} @gol
+ -mpower  -mno-power  -mpower2  -mno-power2 @gol
+ -mpowerpc  -mpowerpc64  -mno-powerpc @gol
+--maltivec  -mno-altivec @gol
++-maltivec  -mno-altivec -maltivec2 -mno-altivec2 @gol
+ -mpowerpc-gpopt  -mno-powerpc-gpopt @gol
+ -mpowerpc-gfxopt  -mno-powerpc-gfxopt @gol
+ -mmfcrf  -mno-mfcrf  -mpopcntb  -mno-popcntb -mpopcntd -mno-popcntd @gol
+@@ -15536,16 +15536,21 @@
+ The @option{-mpopcntb} option allows GCC to generate the popcount and
+ double precision FP reciprocal estimate instruction implemented on the
+ POWER5 processor and other processors that support the PowerPC V2.02
+-architecture.
+-The @option{-mpopcntd} option allows GCC to generate the popcount
+-instruction implemented on the POWER7 processor and other processors
+-that support the PowerPC V2.06 architecture.
++architecture. On the e5500 and e6500 processors, only the popcount
++instruction is generated.
++The @option{-mpopcntd} option allows GCC to generate the popcount and
++double word to FP conversion instructions implemented on the POWER7
++processor and other processors that support the PowerPC V2.06
++architecture. On the e5500 and e6500 processors, only the popcount
++instruction is generated.
+ 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.
+ The @option{-mcmpb} option allows GCC to generate the compare bytes
+-instruction implemented on the POWER6 processor and other processors
+-that support the PowerPC V2.05 architecture.
++and copy sign instructions implemented on the POWER6 processor and
++other processors that support the PowerPC V2.05 architecture. On the
++e5500 and e6500 processors, only the compare bytes instruction is
++generated.
+ The @option{-mmfpgpr} option allows GCC to generate the FP move to/from
+ general purpose register instructions implemented on the POWER6X
+ processor and other processors that support the extended PowerPC V2.05
+@@ -15592,11 +15597,13 @@
+ @samp{603e}, @samp{604}, @samp{604e}, @samp{620}, @samp{630}, @samp{740},
+ @samp{7400}, @samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
+ @samp{860}, @samp{970}, @samp{8540}, @samp{a2}, @samp{e300c2},
+-@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{ec603e}, @samp{G3},
+-@samp{G4}, @samp{G5}, @samp{titan}, @samp{power}, @samp{power2}, @samp{power3},
+-@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6}, @samp{power6x},
+-@samp{power7}, @samp{common}, @samp{powerpc}, @samp{powerpc64}, @samp{rios},
+-@samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64}.
++@samp{e300c3}, @samp{e500mc}, @samp{e500mc64}, @samp{e5500},
++@samp{e6500}, @samp{ec603e}, @samp{G3}, @samp{G4}, @samp{G5},
++@samp{titan}, @samp{power}, @samp{power2}, @samp{power3},
++@samp{power4}, @samp{power5}, @samp{power5+}, @samp{power6},
++@samp{power6x}, @samp{power7}, @samp{common}, @samp{powerpc},
++@samp{powerpc64}, @samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc},
++and @samp{rs64}.
+ @option{-mcpu=common} selects a completely generic processor.  Code
+ generated under this option will run on any POWER or PowerPC processor.
+@@ -15617,10 +15624,11 @@
+ The @option{-mcpu} options automatically enable or disable the
+ following options:
+-@gccoptlist{-maltivec  -mfprnd  -mhard-float  -mmfcrf  -mmultiple @gol
+--mnew-mnemonics  -mpopcntb -mpopcntd  -mpower  -mpower2  -mpowerpc64 @gol
+--mpowerpc-gpopt  -mpowerpc-gfxopt  -msingle-float -mdouble-float @gol
+--msimple-fpu -mstring  -mmulhw  -mdlmzb  -mmfpgpr -mvsx}
++@gccoptlist{-maltivec -maltivec2 -mfprnd -mhard-float -mmfcrf
++-mmultiple @gol -mnew-mnemonics -mpopcntb -mpopcntd -mpower -mpower2
++-mpowerpc64 @gol -mpowerpc-gpopt -mpowerpc-gfxopt -msingle-float
++-mdouble-float @gol -msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr
++-mvsx}
+ The particular options set for any particular CPU will vary between
+ compiler versions, depending on what setting seems to produce optimal
+@@ -15671,6 +15679,16 @@
+ @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
+ enhancements.
++@item -maltivec2
++@itemx -mno-altivec2
++@opindex maltivec2
++@opindex mno-altivec2
++Generate code that uses (does not use) AltiVec2 instructions, and also
++enable the use of built-in functions that allow more direct access to
++the AltiVec2 instruction set.  You may also need to set
++@option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
++enhancements.
++
+ @item -mvrsave
+ @itemx -mno-vrsave
+ @opindex mvrsave
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-10.c   2012-03-06 12:31:05.152039004 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtlx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc1(long a, void *p)           { return __builtin_altivec_lvtlx (a,p); }
++vsf  llx01(long a, vsf *p)          { return __builtin_vec_lvtlx (a,p); }
++vsf  llx02(long a, sf *p)           { return __builtin_vec_lvtlx (a,p); }
++vbi  llx03(long a, vbi *p)          { return __builtin_vec_lvtlx (a,p); }
++vsi  llx04(long a, vsi *p)          { return __builtin_vec_lvtlx (a,p); }
++vsi  llx05(long a, si *p)           { return __builtin_vec_lvtlx (a,p); }
++vui  llx06(long a, vui *p)          { return __builtin_vec_lvtlx (a,p); }
++vui  llx07(long a, ui *p)           { return __builtin_vec_lvtlx (a,p); }
++vbs  llx08(long a, vbs *p)          { return __builtin_vec_lvtlx (a,p); }
++vp   llx09(long a, vp *p)           { return __builtin_vec_lvtlx (a,p); }
++vss  llx10(long a, vss *p)          { return __builtin_vec_lvtlx (a,p); }
++vss  llx11(long a, ss *p)           { return __builtin_vec_lvtlx (a,p); }
++vus  llx12(long a, vus *p)          { return __builtin_vec_lvtlx (a,p); }
++vus  llx13(long a, us *p)           { return __builtin_vec_lvtlx (a,p); }
++vbc  llx14(long a, vbc *p)          { return __builtin_vec_lvtlx (a,p); }
++vsc  llx15(long a, vsc *p)          { return __builtin_vec_lvtlx (a,p); }
++vsc  llx16(long a, sc *p)           { return __builtin_vec_lvtlx (a,p); }
++vuc  llx17(long a, vuc *p)          { return __builtin_vec_lvtlx (a,p); }
++vuc  llx18(long a, uc *p)           { return __builtin_vec_lvtlx (a,p); }
++vsf  Dllx01(long a, vsf *p)         { return vec_lvtlx (a,p); }
++vsf  Dllx02(long a, sf *p)          { return vec_lvtlx (a,p); }
++vbi  Dllx03(long a, vbi *p)         { return vec_lvtlx (a,p); }
++vsi  Dllx04(long a, vsi *p)         { return vec_lvtlx (a,p); }
++vsi  Dllx05(long a, si *p)          { return vec_lvtlx (a,p); }
++vui  Dllx06(long a, vui *p)         { return vec_lvtlx (a,p); }
++vui  Dllx07(long a, ui *p)          { return vec_lvtlx (a,p); }
++vbs  Dllx08(long a, vbs *p)         { return vec_lvtlx (a,p); }
++vp   Dllx09(long a, vp *p)          { return vec_lvtlx (a,p); }
++vss  Dllx10(long a, vss *p)         { return vec_lvtlx (a,p); }
++vss  Dllx11(long a, ss *p)          { return vec_lvtlx (a,p); }
++vus  Dllx12(long a, vus *p)         { return vec_lvtlx (a,p); }
++vus  Dllx13(long a, us *p)          { return vec_lvtlx (a,p); }
++vbc  Dllx14(long a, vbc *p)         { return vec_lvtlx (a,p); }
++vsc  Dllx15(long a, vsc *p)         { return vec_lvtlx (a,p); }
++vsc  Dllx16(long a, sc *p)          { return vec_lvtlx (a,p); }
++vuc  Dllx17(long a, vuc *p)         { return vec_lvtlx (a,p); }
++vuc  Dllx18(long a, uc *p)          { return vec_lvtlx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-11.c   2012-03-06 12:31:05.153039004 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtlxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc2(long a, void *p)           { return __builtin_altivec_lvtlxl (a,p); }
++vsf  llxl01(long a, vsf *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsf  llxl02(long a, sf *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbi  llxl03(long a, vbi *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsi  llxl04(long a, vsi *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsi  llxl05(long a, si *p)          { return __builtin_vec_lvtlxl (a,p); }
++vui  llxl06(long a, vui *p)         { return __builtin_vec_lvtlxl (a,p); }
++vui  llxl07(long a, ui *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbs  llxl08(long a, vbs *p)         { return __builtin_vec_lvtlxl (a,p); }
++vp   llxl09(long a, vp *p)          { return __builtin_vec_lvtlxl (a,p); }
++vss  llxl10(long a, vss *p)         { return __builtin_vec_lvtlxl (a,p); }
++vss  llxl11(long a, ss *p)          { return __builtin_vec_lvtlxl (a,p); }
++vus  llxl12(long a, vus *p)         { return __builtin_vec_lvtlxl (a,p); }
++vus  llxl13(long a, us *p)          { return __builtin_vec_lvtlxl (a,p); }
++vbc  llxl14(long a, vbc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsc  llxl15(long a, vsc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vsc  llxl16(long a, sc *p)          { return __builtin_vec_lvtlxl (a,p); }
++vuc  llxl17(long a, vuc *p)         { return __builtin_vec_lvtlxl (a,p); }
++vuc  llxl18(long a, uc *p)          { return __builtin_vec_lvtlxl (a,p); }
++vsf  Dllxl01(long a, vsf *p)        { return vec_lvtlxl (a,p); }
++vsf  Dllxl02(long a, sf *p)         { return vec_lvtlxl (a,p); }
++vbi  Dllxl03(long a, vbi *p)        { return vec_lvtlxl (a,p); }
++vsi  Dllxl04(long a, vsi *p)        { return vec_lvtlxl (a,p); }
++vsi  Dllxl05(long a, si *p)         { return vec_lvtlxl (a,p); }
++vui  Dllxl06(long a, vui *p)        { return vec_lvtlxl (a,p); }
++vui  Dllxl07(long a, ui *p)         { return vec_lvtlxl (a,p); }
++vbs  Dllxl08(long a, vbs *p)        { return vec_lvtlxl (a,p); }
++vp   Dllxl09(long a, vp *p)         { return vec_lvtlxl (a,p); }
++vss  Dllxl10(long a, vss *p)        { return vec_lvtlxl (a,p); }
++vss  Dllxl11(long a, ss *p)         { return vec_lvtlxl (a,p); }
++vus  Dllxl12(long a, vus *p)        { return vec_lvtlxl (a,p); }
++vus  Dllxl13(long a, us *p)         { return vec_lvtlxl (a,p); }
++vbc  Dllxl14(long a, vbc *p)        { return vec_lvtlxl (a,p); }
++vsc  Dllxl15(long a, vsc *p)        { return vec_lvtlxl (a,p); }
++vsc  Dllxl16(long a, sc *p)         { return vec_lvtlxl (a,p); }
++vuc  Dllxl17(long a, vuc *p)        { return vec_lvtlxl (a,p); }
++vuc  Dllxl18(long a, uc *p)         { return vec_lvtlxl (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-12.c   2012-03-06 12:31:05.153039004 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtrx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc3(long a, void *p)           { return __builtin_altivec_lvtrx (a,p); }
++vsf  lrx01(long a, vsf *p)          { return __builtin_vec_lvtrx (a,p); }
++vsf  lrx02(long a, sf *p)           { return __builtin_vec_lvtrx (a,p); }
++vbi  lrx03(long a, vbi *p)          { return __builtin_vec_lvtrx (a,p); }
++vsi  lrx04(long a, vsi *p)          { return __builtin_vec_lvtrx (a,p); }
++vsi  lrx05(long a, si *p)           { return __builtin_vec_lvtrx (a,p); }
++vui  lrx06(long a, vui *p)          { return __builtin_vec_lvtrx (a,p); }
++vui  lrx07(long a, ui *p)           { return __builtin_vec_lvtrx (a,p); }
++vbs  lrx08(long a, vbs *p)          { return __builtin_vec_lvtrx (a,p); }
++vp   lrx09(long a, vp *p)           { return __builtin_vec_lvtrx (a,p); }
++vss  lrx10(long a, vss *p)          { return __builtin_vec_lvtrx (a,p); }
++vss  lrx11(long a, ss *p)           { return __builtin_vec_lvtrx (a,p); }
++vus  lrx12(long a, vus *p)          { return __builtin_vec_lvtrx (a,p); }
++vus  lrx13(long a, us *p)           { return __builtin_vec_lvtrx (a,p); }
++vbc  lrx14(long a, vbc *p)          { return __builtin_vec_lvtrx (a,p); }
++vsc  lrx15(long a, vsc *p)          { return __builtin_vec_lvtrx (a,p); }
++vsc  lrx16(long a, sc *p)           { return __builtin_vec_lvtrx (a,p); }
++vuc  lrx17(long a, vuc *p)          { return __builtin_vec_lvtrx (a,p); }
++vuc  lrx18(long a, uc *p)           { return __builtin_vec_lvtrx (a,p); }
++vsf  Dlrx01(long a, vsf *p)         { return vec_lvtrx (a,p); }
++vsf  Dlrx02(long a, sf *p)          { return vec_lvtrx (a,p); }
++vbi  Dlrx03(long a, vbi *p)         { return vec_lvtrx (a,p); }
++vsi  Dlrx04(long a, vsi *p)         { return vec_lvtrx (a,p); }
++vsi  Dlrx05(long a, si *p)          { return vec_lvtrx (a,p); }
++vui  Dlrx06(long a, vui *p)         { return vec_lvtrx (a,p); }
++vui  Dlrx07(long a, ui *p)          { return vec_lvtrx (a,p); }
++vbs  Dlrx08(long a, vbs *p)         { return vec_lvtrx (a,p); }
++vp   Dlrx09(long a, vp *p)          { return vec_lvtrx (a,p); }
++vss  Dlrx10(long a, vss *p)         { return vec_lvtrx (a,p); }
++vss  Dlrx11(long a, ss *p)          { return vec_lvtrx (a,p); }
++vus  Dlrx12(long a, vus *p)         { return vec_lvtrx (a,p); }
++vus  Dlrx13(long a, us *p)          { return vec_lvtrx (a,p); }
++vbc  Dlrx14(long a, vbc *p)         { return vec_lvtrx (a,p); }
++vsc  Dlrx15(long a, vsc *p)         { return vec_lvtrx (a,p); }
++vsc  Dlrx16(long a, sc *p)          { return vec_lvtrx (a,p); }
++vuc  Dlrx17(long a, vuc *p)         { return vec_lvtrx (a,p); }
++vuc  Dlrx18(long a, uc *p)          { return vec_lvtrx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-13.c   2012-03-06 12:31:05.153039004 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvtrxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc4(long a, void *p)           { return __builtin_altivec_lvtrxl (a,p); }
++vsf  lrxl01(long a, vsf *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsf  lrxl02(long a, sf *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbi  lrxl03(long a, vbi *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsi  lrxl04(long a, vsi *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsi  lrxl05(long a, si *p)          { return __builtin_vec_lvtrxl (a,p); }
++vui  lrxl06(long a, vui *p)         { return __builtin_vec_lvtrxl (a,p); }
++vui  lrxl07(long a, ui *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbs  lrxl08(long a, vbs *p)         { return __builtin_vec_lvtrxl (a,p); }
++vp   lrxl09(long a, vp *p)          { return __builtin_vec_lvtrxl (a,p); }
++vss  lrxl10(long a, vss *p)         { return __builtin_vec_lvtrxl (a,p); }
++vss  lrxl11(long a, ss *p)          { return __builtin_vec_lvtrxl (a,p); }
++vus  lrxl12(long a, vus *p)         { return __builtin_vec_lvtrxl (a,p); }
++vus  lrxl13(long a, us *p)          { return __builtin_vec_lvtrxl (a,p); }
++vbc  lrxl14(long a, vbc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsc  lrxl15(long a, vsc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vsc  lrxl16(long a, sc *p)          { return __builtin_vec_lvtrxl (a,p); }
++vuc  lrxl17(long a, vuc *p)         { return __builtin_vec_lvtrxl (a,p); }
++vuc  lrxl18(long a, uc *p)          { return __builtin_vec_lvtrxl (a,p); }
++vsf  Dlrxl01(long a, vsf *p)        { return vec_lvtrxl (a,p); }
++vsf  Dlrxl02(long a, sf *p)         { return vec_lvtrxl (a,p); }
++vbi  Dlrxl03(long a, vbi *p)        { return vec_lvtrxl (a,p); }
++vsi  Dlrxl04(long a, vsi *p)        { return vec_lvtrxl (a,p); }
++vsi  Dlrxl05(long a, si *p)         { return vec_lvtrxl (a,p); }
++vui  Dlrxl06(long a, vui *p)        { return vec_lvtrxl (a,p); }
++vui  Dlrxl07(long a, ui *p)         { return vec_lvtrxl (a,p); }
++vbs  Dlrxl08(long a, vbs *p)        { return vec_lvtrxl (a,p); }
++vp   Dlrxl09(long a, vp *p)         { return vec_lvtrxl (a,p); }
++vss  Dlrxl10(long a, vss *p)        { return vec_lvtrxl (a,p); }
++vss  Dlrxl11(long a, ss *p)         { return vec_lvtrxl (a,p); }
++vus  Dlrxl12(long a, vus *p)        { return vec_lvtrxl (a,p); }
++vus  Dlrxl13(long a, us *p)         { return vec_lvtrxl (a,p); }
++vbc  Dlrxl14(long a, vbc *p)        { return vec_lvtrxl (a,p); }
++vsc  Dlrxl15(long a, vsc *p)        { return vec_lvtrxl (a,p); }
++vsc  Dlrxl16(long a, sc *p)         { return vec_lvtrxl (a,p); }
++vuc  Dlrxl17(long a, vuc *p)        { return vec_lvtrxl (a,p); }
++vuc  Dlrxl18(long a, uc *p)         { return vec_lvtrxl (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-14.c   2012-03-06 12:31:05.154039003 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvflx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc1(vsc v, long a, void *p)    { __builtin_altivec_stvflx (v,a,p); }
++void slx01(vsf v, long a, vsf *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx02(vsf v, long a, sf *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx03(vbi v, long a, vbi *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx04(vsi v, long a, vsi *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx05(vsi v, long a, si *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx06(vui v, long a, vui *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx07(vui v, long a, ui *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx08(vbs v, long a, vbs *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx09(vp v, long a, vp *p)     { __builtin_vec_stvflx (v,a,p); }
++void slx10(vss v, long a, vss *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx11(vss v, long a, ss *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx12(vus v, long a, vus *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx13(vus v, long a, us *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx14(vbc v, long a, vbc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx15(vsc v, long a, vsc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx16(vsc v, long a, sc *p)    { __builtin_vec_stvflx (v,a,p); }
++void slx17(vuc v, long a, vuc *p)   { __builtin_vec_stvflx (v,a,p); }
++void slx18(vuc v, long a, uc *p)    { __builtin_vec_stvflx (v,a,p); }
++void Dslx01(vsf v, long a, vsf *p)  { vec_stvflx (v,a,p); }
++void Dslx02(vsf v, long a, sf *p)   { vec_stvflx (v,a,p); }
++void Dslx03(vbi v, long a, vbi *p)  { vec_stvflx (v,a,p); }
++void Dslx04(vsi v, long a, vsi *p)  { vec_stvflx (v,a,p); }
++void Dslx05(vsi v, long a, si *p)   { vec_stvflx (v,a,p); }
++void Dslx06(vui v, long a, vui *p)  { vec_stvflx (v,a,p); }
++void Dslx07(vui v, long a, ui *p)   { vec_stvflx (v,a,p); }
++void Dslx08(vbs v, long a, vbs *p)  { vec_stvflx (v,a,p); }
++void Dslx09(vp v, long a, vp *p)    { vec_stvflx (v,a,p); }
++void Dslx10(vss v, long a, vss *p)  { vec_stvflx (v,a,p); }
++void Dslx11(vss v, long a, ss *p)   { vec_stvflx (v,a,p); }
++void Dslx12(vus v, long a, vus *p)  { vec_stvflx (v,a,p); }
++void Dslx13(vus v, long a, us *p)   { vec_stvflx (v,a,p); }
++void Dslx14(vbc v, long a, vbc *p)  { vec_stvflx (v,a,p); }
++void Dslx15(vsc v, long a, vsc *p)  { vec_stvflx (v,a,p); }
++void Dslx16(vsc v, long a, sc *p)   { vec_stvflx (v,a,p); }
++void Dslx17(vuc v, long a, vuc *p)  { vec_stvflx (v,a,p); }
++void Dslx18(vuc v, long a, uc *p)   { vec_stvflx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-15.c   2012-03-06 12:31:05.154039003 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvflxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc2(vsc v, long a, void *p)    { __builtin_altivec_stvflxl (v,a,p); }
++void slxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl02(vsf v, long a, sf *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl05(vsi v, long a, si *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl06(vui v, long a, vui *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl07(vui v, long a, ui *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl09(vp v, long a, vp *p)    { __builtin_vec_stvflxl (v,a,p); }
++void slxl10(vss v, long a, vss *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl11(vss v, long a, ss *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl12(vus v, long a, vus *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl13(vus v, long a, us *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl16(vsc v, long a, sc *p)   { __builtin_vec_stvflxl (v,a,p); }
++void slxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvflxl (v,a,p); }
++void slxl18(vuc v, long a, uc *p)   { __builtin_vec_stvflxl (v,a,p); }
++void Dslxl01(vsf v, long a, vsf *p) { vec_stvflxl (v,a,p); }
++void Dslxl02(vsf v, long a, sf *p)  { vec_stvflxl (v,a,p); }
++void Dslxl03(vbi v, long a, vbi *p) { vec_stvflxl (v,a,p); }
++void Dslxl04(vsi v, long a, vsi *p) { vec_stvflxl (v,a,p); }
++void Dslxl05(vsi v, long a, si *p)  { vec_stvflxl (v,a,p); }
++void Dslxl06(vui v, long a, vui *p) { vec_stvflxl (v,a,p); }
++void Dslxl07(vui v, long a, ui *p)  { vec_stvflxl (v,a,p); }
++void Dslxl08(vbs v, long a, vbs *p) { vec_stvflxl (v,a,p); }
++void Dslxl09(vp v, long a, vp *p)   { vec_stvflxl (v,a,p); }
++void Dslxl10(vss v, long a, vss *p) { vec_stvflxl (v,a,p); }
++void Dslxl11(vss v, long a, ss *p)  { vec_stvflxl (v,a,p); }
++void Dslxl12(vus v, long a, vus *p) { vec_stvflxl (v,a,p); }
++void Dslxl13(vus v, long a, us *p)  { vec_stvflxl (v,a,p); }
++void Dslxl14(vbc v, long a, vbc *p) { vec_stvflxl (v,a,p); }
++void Dslxl15(vsc v, long a, vsc *p) { vec_stvflxl (v,a,p); }
++void Dslxl16(vsc v, long a, sc *p)  { vec_stvflxl (v,a,p); }
++void Dslxl17(vuc v, long a, vuc *p) { vec_stvflxl (v,a,p); }
++void Dslxl18(vuc v, long a, uc *p)  { vec_stvflxl (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-16.c   2012-03-06 12:31:05.154039003 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvfrx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc3(vsc v, long a, void *p)    { __builtin_altivec_stvfrx (v,a,p); }
++void srx01(vsf v, long a, vsf *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx02(vsf v, long a, sf *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx03(vbi v, long a, vbi *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx04(vsi v, long a, vsi *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx05(vsi v, long a, si *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx06(vui v, long a, vui *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx07(vui v, long a, ui *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx08(vbs v, long a, vbs *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx09(vp v, long a, vp *p)     { __builtin_vec_stvfrx (v,a,p); }
++void srx10(vss v, long a, vss *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx11(vss v, long a, ss *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx12(vus v, long a, vus *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx13(vus v, long a, us *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx14(vbc v, long a, vbc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx15(vsc v, long a, vsc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx16(vsc v, long a, sc *p)    { __builtin_vec_stvfrx (v,a,p); }
++void srx17(vuc v, long a, vuc *p)   { __builtin_vec_stvfrx (v,a,p); }
++void srx18(vuc v, long a, uc *p)    { __builtin_vec_stvfrx (v,a,p); }
++void Dsrx01(vsf v, long a, vsf *p)  { vec_stvfrx (v,a,p); }
++void Dsrx02(vsf v, long a, sf *p)   { vec_stvfrx (v,a,p); }
++void Dsrx03(vbi v, long a, vbi *p)  { vec_stvfrx (v,a,p); }
++void Dsrx04(vsi v, long a, vsi *p)  { vec_stvfrx (v,a,p); }
++void Dsrx05(vsi v, long a, si *p)   { vec_stvfrx (v,a,p); }
++void Dsrx06(vui v, long a, vui *p)  { vec_stvfrx (v,a,p); }
++void Dsrx07(vui v, long a, ui *p)   { vec_stvfrx (v,a,p); }
++void Dsrx08(vbs v, long a, vbs *p)  { vec_stvfrx (v,a,p); }
++void Dsrx09(vp v, long a, vp *p)    { vec_stvfrx (v,a,p); }
++void Dsrx10(vss v, long a, vss *p)  { vec_stvfrx (v,a,p); }
++void Dsrx11(vss v, long a, ss *p)   { vec_stvfrx (v,a,p); }
++void Dsrx12(vus v, long a, vus *p)  { vec_stvfrx (v,a,p); }
++void Dsrx13(vus v, long a, us *p)   { vec_stvfrx (v,a,p); }
++void Dsrx14(vbc v, long a, vbc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx15(vsc v, long a, vsc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx16(vsc v, long a, sc *p)   { vec_stvfrx (v,a,p); }
++void Dsrx17(vuc v, long a, vuc *p)  { vec_stvfrx (v,a,p); }
++void Dsrx18(vuc v, long a, uc *p)   { vec_stvfrx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-17.c   2012-03-06 12:31:05.155039001 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvfrxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc4(vsc v, long a, void *p)    { __builtin_altivec_stvfrxl (v,a,p); }
++void srxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl02(vsf v, long a, sf *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl05(vsi v, long a, si *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl06(vui v, long a, vui *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl07(vui v, long a, ui *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl09(vp v, long a, vp *p)    { __builtin_vec_stvfrxl (v,a,p); }
++void srxl10(vss v, long a, vss *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl11(vss v, long a, ss *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl12(vus v, long a, vus *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl13(vus v, long a, us *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl16(vsc v, long a, sc *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void srxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvfrxl (v,a,p); }
++void srxl18(vuc v, long a, uc *p)   { __builtin_vec_stvfrxl (v,a,p); }
++void Dsrxl01(vsf v, long a, vsf *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl02(vsf v, long a, sf *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl03(vbi v, long a, vbi *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl04(vsi v, long a, vsi *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl05(vsi v, long a, si *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl06(vui v, long a, vui *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl07(vui v, long a, ui *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl08(vbs v, long a, vbs *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl09(vp v, long a, vp *p)   { vec_stvfrxl (v,a,p); }
++void Dsrxl10(vss v, long a, vss *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl11(vss v, long a, ss *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl12(vus v, long a, vus *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl13(vus v, long a, us *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl14(vbc v, long a, vbc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl15(vsc v, long a, vsc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl16(vsc v, long a, sc *p)  { vec_stvfrxl (v,a,p); }
++void Dsrxl17(vuc v, long a, vuc *p) { vec_stvfrxl (v,a,p); }
++void Dsrxl18(vuc v, long a, uc *p)  { vec_stvfrxl (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-18.c   2012-03-06 12:31:05.155039001 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvswx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  ls1(long a, void *p)           { return __builtin_altivec_lvswx (a,p); }
++vsf  ls01(long a, vsf *p)           { return __builtin_vec_lvswx (a,p); }
++vsf  ls02(long a, sf *p)            { return __builtin_vec_lvswx (a,p); }
++vbi  ls03(long a, vbi *p)           { return __builtin_vec_lvswx (a,p); }
++vsi  ls04(long a, vsi *p)           { return __builtin_vec_lvswx (a,p); }
++vsi  ls05(long a, si *p)            { return __builtin_vec_lvswx (a,p); }
++vui  ls06(long a, vui *p)           { return __builtin_vec_lvswx (a,p); }
++vui  ls07(long a, ui *p)            { return __builtin_vec_lvswx (a,p); }
++vbs  ls08(long a, vbs *p)           { return __builtin_vec_lvswx (a,p); }
++vp   ls09(long a, vp *p)            { return __builtin_vec_lvswx (a,p); }
++vss  ls10(long a, vss *p)           { return __builtin_vec_lvswx (a,p); }
++vss  ls11(long a, ss *p)            { return __builtin_vec_lvswx (a,p); }
++vus  ls12(long a, vus *p)           { return __builtin_vec_lvswx (a,p); }
++vus  ls13(long a, us *p)            { return __builtin_vec_lvswx (a,p); }
++vbc  ls14(long a, vbc *p)           { return __builtin_vec_lvswx (a,p); }
++vsc  ls15(long a, vsc *p)           { return __builtin_vec_lvswx (a,p); }
++vsc  ls16(long a, sc *p)            { return __builtin_vec_lvswx (a,p); }
++vuc  ls17(long a, vuc *p)           { return __builtin_vec_lvswx (a,p); }
++vuc  ls18(long a, uc *p)            { return __builtin_vec_lvswx (a,p); }
++vsf  Dls01(long a, vsf *p)          { return vec_lvswx (a,p); }
++vsf  Dls02(long a, sf *p)           { return vec_lvswx (a,p); }
++vbi  Dls03(long a, vbi *p)          { return vec_lvswx (a,p); }
++vsi  Dls04(long a, vsi *p)          { return vec_lvswx (a,p); }
++vsi  Dls05(long a, si *p)           { return vec_lvswx (a,p); }
++vui  Dls06(long a, vui *p)          { return vec_lvswx (a,p); }
++vui  Dls07(long a, ui *p)           { return vec_lvswx (a,p); }
++vbs  Dls08(long a, vbs *p)          { return vec_lvswx (a,p); }
++vp   Dls09(long a, vp *p)           { return vec_lvswx (a,p); }
++vss  Dls10(long a, vss *p)          { return vec_lvswx (a,p); }
++vss  Dls11(long a, ss *p)           { return vec_lvswx (a,p); }
++vus  Dls12(long a, vus *p)          { return vec_lvswx (a,p); }
++vus  Dls13(long a, us *p)           { return vec_lvswx (a,p); }
++vbc  Dls14(long a, vbc *p)          { return vec_lvswx (a,p); }
++vsc  Dls15(long a, vsc *p)          { return vec_lvswx (a,p); }
++vsc  Dls16(long a, sc *p)           { return vec_lvswx (a,p); }
++vuc  Dls17(long a, vuc *p)          { return vec_lvswx (a,p); }
++vuc  Dls18(long a, uc *p)           { return vec_lvswx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-19.c   2012-03-06 12:31:05.155039001 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvswxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  ls2l(long a, void *p)          { return __builtin_altivec_lvswxl (a,p); }
++vsf  lsl01(long a, vsf *p)          { return __builtin_vec_lvswxl (a,p); }
++vsf  lsl02(long a, sf *p)           { return __builtin_vec_lvswxl (a,p); }
++vbi  lsl03(long a, vbi *p)          { return __builtin_vec_lvswxl (a,p); }
++vsi  lsl04(long a, vsi *p)          { return __builtin_vec_lvswxl (a,p); }
++vsi  lsl05(long a, si *p)           { return __builtin_vec_lvswxl (a,p); }
++vui  lsl06(long a, vui *p)          { return __builtin_vec_lvswxl (a,p); }
++vui  lsl07(long a, ui *p)           { return __builtin_vec_lvswxl (a,p); }
++vbs  lsl08(long a, vbs *p)          { return __builtin_vec_lvswxl (a,p); }
++vp   lsl09(long a, vp *p)           { return __builtin_vec_lvswxl (a,p); }
++vss  lsl10(long a, vss *p)          { return __builtin_vec_lvswxl (a,p); }
++vss  lsl11(long a, ss *p)           { return __builtin_vec_lvswxl (a,p); }
++vus  lsl12(long a, vus *p)          { return __builtin_vec_lvswxl (a,p); }
++vus  lsl13(long a, us *p)           { return __builtin_vec_lvswxl (a,p); }
++vbc  lsl14(long a, vbc *p)          { return __builtin_vec_lvswxl (a,p); }
++vsc  lsl15(long a, vsc *p)          { return __builtin_vec_lvswxl (a,p); }
++vsc  lsl16(long a, sc *p)           { return __builtin_vec_lvswxl (a,p); }
++vuc  lsl17(long a, vuc *p)          { return __builtin_vec_lvswxl (a,p); }
++vuc  lsl18(long a, uc *p)           { return __builtin_vec_lvswxl (a,p); }
++vsf  Dlsl01(long a, vsf *p)         { return vec_lvswxl (a,p); }
++vsf  Dlsl02(long a, sf *p)          { return vec_lvswxl (a,p); }
++vbi  Dlsl03(long a, vbi *p)         { return vec_lvswxl (a,p); }
++vsi  Dlsl04(long a, vsi *p)         { return vec_lvswxl (a,p); }
++vsi  Dlsl05(long a, si *p)          { return vec_lvswxl (a,p); }
++vui  Dlsl06(long a, vui *p)         { return vec_lvswxl (a,p); }
++vui  Dlsl07(long a, ui *p)          { return vec_lvswxl (a,p); }
++vbs  Dlsl08(long a, vbs *p)         { return vec_lvswxl (a,p); }
++vp   Dlsl09(long a, vp *p)          { return vec_lvswxl (a,p); }
++vss  Dlsl10(long a, vss *p)         { return vec_lvswxl (a,p); }
++vss  Dlsl11(long a, ss *p)          { return vec_lvswxl (a,p); }
++vus  Dlsl12(long a, vus *p)         { return vec_lvswxl (a,p); }
++vus  Dlsl13(long a, us *p)          { return vec_lvswxl (a,p); }
++vbc  Dlsl14(long a, vbc *p)         { return vec_lvswxl (a,p); }
++vsc  Dlsl15(long a, vsc *p)         { return vec_lvswxl (a,p); }
++vsc  Dlsl16(long a, sc *p)          { return vec_lvswxl (a,p); }
++vuc  Dlsl17(long a, vuc *p)         { return vec_lvswxl (a,p); }
++vuc  Dlsl18(long a, uc *p)          { return vec_lvswxl (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-1.c    2012-03-06 12:31:05.156039000 -0600
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsdub" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vuc  fa1b(vuc a, vuc b)             { return __builtin_altivec_vabsdub (a,b); }
++vuc  ad1(vuc a, vuc b)              { return __builtin_vec_absd (a,b); }
++vuc  ad2(vbc a, vuc b)              { return __builtin_vec_absd (a,b); }
++vuc  ad3(vuc a, vbc b)              { return __builtin_vec_absd (a,b); }
++vuc  Dad1(vuc a, vuc b)             { return vec_absd (a,b); }
++vuc  Dad2(vbc a, vuc b)             { return vec_absd (a,b); }
++vuc  Dad3(vuc a, vbc b)             { return vec_absd (a,b); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-20.c   2012-03-06 12:31:05.156039000 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvswx" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void ss1(vsc v, long a, vsc *p)     { __builtin_altivec_stvswx (v,a,p); }
++void ssx01(vsf v, long a, vsf *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx02(vsf v, long a, sf  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx03(vbi v, long a, vbi *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx04(vsi v, long a, vsi *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx05(vsi v, long a, si  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx06(vui v, long a, vui *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx07(vui v, long a, ui  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx08(vbs v, long a, vbs *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx09(vp  v, long a, vp  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx10(vss v, long a, vss *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx11(vss v, long a, ss  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx12(vus v, long a, vus *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx13(vus v, long a, us  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx14(vbc v, long a, vbc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx15(vsc v, long a, vsc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx16(vsc v, long a, sc  *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx17(vuc v, long a, vuc *p)   { __builtin_vec_stvswx (v,a,p); }
++void ssx18(vuc v, long a, uc  *p)   { __builtin_vec_stvswx (v,a,p); }
++void Dssx01(vsf v, long a, vsf *p)  { vec_stvswx (v,a,p); }
++void Dssx02(vsf v, long a, sf  *p)  { vec_stvswx (v,a,p); }
++void Dssx03(vbi v, long a, vbi *p)  { vec_stvswx (v,a,p); }
++void Dssx04(vsi v, long a, vsi *p)  { vec_stvswx (v,a,p); }
++void Dssx05(vsi v, long a, si  *p)  { vec_stvswx (v,a,p); }
++void Dssx06(vui v, long a, vui *p)  { vec_stvswx (v,a,p); }
++void Dssx07(vui v, long a, ui  *p)  { vec_stvswx (v,a,p); }
++void Dssx08(vbs v, long a, vbs *p)  { vec_stvswx (v,a,p); }
++void Dssx09(vp  v, long a, vp  *p)  { vec_stvswx (v,a,p); }
++void Dssx10(vss v, long a, vss *p)  { vec_stvswx (v,a,p); }
++void Dssx11(vss v, long a, ss  *p)  { vec_stvswx (v,a,p); }
++void Dssx12(vus v, long a, vus *p)  { vec_stvswx (v,a,p); }
++void Dssx13(vus v, long a, us  *p)  { vec_stvswx (v,a,p); }
++void Dssx14(vbc v, long a, vbc *p)  { vec_stvswx (v,a,p); }
++void Dssx15(vsc v, long a, vsc *p)  { vec_stvswx (v,a,p); }
++void Dssx16(vsc v, long a, sc  *p)  { vec_stvswx (v,a,p); }
++void Dssx17(vuc v, long a, vuc *p)  { vec_stvswx (v,a,p); }
++void Dssx18(vuc v, long a, uc  *p)  { vec_stvswx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-21.c   2012-03-06 12:31:05.156039000 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvswxl" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void ss2l(vsc v, long a, vsc *p)    { __builtin_altivec_stvswxl (v,a,p); }
++void ssxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl02(vsf v, long a, sf  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl05(vsi v, long a, si  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl06(vui v, long a, vui *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl07(vui v, long a, ui  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl09(vp  v, long a, vp  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl10(vss v, long a, vss *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl11(vss v, long a, ss  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl12(vus v, long a, vus *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl13(vus v, long a, us  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl16(vsc v, long a, sc  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvswxl (v,a,p); }
++void ssxl18(vuc v, long a, uc  *p)  { __builtin_vec_stvswxl (v,a,p); }
++void Dssxl01(vsf v, long a, vsf *p) { vec_stvswxl (v,a,p); }
++void Dssxl02(vsf v, long a, sf  *p) { vec_stvswxl (v,a,p); }
++void Dssxl03(vbi v, long a, vbi *p) { vec_stvswxl (v,a,p); }
++void Dssxl04(vsi v, long a, vsi *p) { vec_stvswxl (v,a,p); }
++void Dssxl05(vsi v, long a, si  *p) { vec_stvswxl (v,a,p); }
++void Dssxl06(vui v, long a, vui *p) { vec_stvswxl (v,a,p); }
++void Dssxl07(vui v, long a, ui  *p) { vec_stvswxl (v,a,p); }
++void Dssxl08(vbs v, long a, vbs *p) { vec_stvswxl (v,a,p); }
++void Dssxl09(vp  v, long a, vp  *p) { vec_stvswxl (v,a,p); }
++void Dssxl10(vss v, long a, vss *p) { vec_stvswxl (v,a,p); }
++void Dssxl11(vss v, long a, ss  *p) { vec_stvswxl (v,a,p); }
++void Dssxl12(vus v, long a, vus *p) { vec_stvswxl (v,a,p); }
++void Dssxl13(vus v, long a, us  *p) { vec_stvswxl (v,a,p); }
++void Dssxl14(vbc v, long a, vbc *p) { vec_stvswxl (v,a,p); }
++void Dssxl15(vsc v, long a, vsc *p) { vec_stvswxl (v,a,p); }
++void Dssxl16(vsc v, long a, sc  *p) { vec_stvswxl (v,a,p); }
++void Dssxl17(vuc v, long a, vuc *p) { vec_stvswxl (v,a,p); }
++void Dssxl18(vuc v, long a, uc  *p) { vec_stvswxl (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-22.c   2012-03-06 12:31:05.157039001 -0600
+@@ -0,0 +1,66 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvsm" 37 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lsm(long a, void *p)           { return __builtin_altivec_lvsm (a,p); }
++vsf  lm01(long a, vsf *p)           { return __builtin_vec_lvsm (a,p); }
++vsf  lm02(long a, sf *p)            { return __builtin_vec_lvsm (a,p); }
++vbi  lm03(long a, vbi *p)           { return __builtin_vec_lvsm (a,p); }
++vsi  lm04(long a, vsi *p)           { return __builtin_vec_lvsm (a,p); }
++vsi  lm05(long a, si *p)            { return __builtin_vec_lvsm (a,p); }
++vui  lm06(long a, vui *p)           { return __builtin_vec_lvsm (a,p); }
++vui  lm07(long a, ui *p)            { return __builtin_vec_lvsm (a,p); }
++vbs  lm08(long a, vbs *p)           { return __builtin_vec_lvsm (a,p); }
++vp   lm09(long a, vp *p)            { return __builtin_vec_lvsm (a,p); }
++vss  lm10(long a, vss *p)           { return __builtin_vec_lvsm (a,p); }
++vss  lm11(long a, ss *p)            { return __builtin_vec_lvsm (a,p); }
++vus  lm12(long a, vus *p)           { return __builtin_vec_lvsm (a,p); }
++vus  lm13(long a, us *p)            { return __builtin_vec_lvsm (a,p); }
++vbc  lm14(long a, vbc *p)           { return __builtin_vec_lvsm (a,p); }
++vsc  lm15(long a, vsc *p)           { return __builtin_vec_lvsm (a,p); }
++vsc  lm16(long a, sc *p)            { return __builtin_vec_lvsm (a,p); }
++vuc  lm17(long a, vuc *p)           { return __builtin_vec_lvsm (a,p); }
++vuc  lm18(long a, uc *p)            { return __builtin_vec_lvsm (a,p); }
++vsf  Dlm01(long a, vsf *p)          { return vec_lvsm (a,p); }
++vsf  Dlm02(long a, sf *p)           { return vec_lvsm (a,p); }
++vbi  Dlm03(long a, vbi *p)          { return vec_lvsm (a,p); }
++vsi  Dlm04(long a, vsi *p)          { return vec_lvsm (a,p); }
++vsi  Dlm05(long a, si *p)           { return vec_lvsm (a,p); }
++vui  Dlm06(long a, vui *p)          { return vec_lvsm (a,p); }
++vui  Dlm07(long a, ui *p)           { return vec_lvsm (a,p); }
++vbs  Dlm08(long a, vbs *p)          { return vec_lvsm (a,p); }
++vp   Dlm09(long a, vp *p)           { return vec_lvsm (a,p); }
++vss  Dlm10(long a, vss *p)          { return vec_lvsm (a,p); }
++vss  Dlm11(long a, ss *p)           { return vec_lvsm (a,p); }
++vus  Dlm12(long a, vus *p)          { return vec_lvsm (a,p); }
++vus  Dlm13(long a, us *p)           { return vec_lvsm (a,p); }
++vbc  Dlm14(long a, vbc *p)          { return vec_lvsm (a,p); }
++vsc  Dlm15(long a, vsc *p)          { return vec_lvsm (a,p); }
++vsc  Dlm16(long a, sc *p)           { return vec_lvsm (a,p); }
++vuc  Dlm17(long a, vuc *p)          { return vec_lvsm (a,p); }
++vuc  Dlm18(long a, uc *p)           { return vec_lvsm (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-2.c    2012-03-06 12:31:05.157039001 -0600
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsduh" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vus  fa2h(vus a, vus b)             { return __builtin_altivec_vabsduh (a,b); }
++vus  ad4(vus a, vus b)              { return __builtin_vec_absd (a,b); }
++vus  ad5(vbs a, vus b)              { return __builtin_vec_absd (a,b); }
++vus  ad6(vus a, vbs b)              { return __builtin_vec_absd (a,b); }
++vus  Dad4(vus a, vus b)             { return vec_absd (a,b); }
++vus  Dad5(vbs a, vus b)             { return vec_absd (a,b); }
++vus  Dad6(vus a, vbs b)             { return vec_absd (a,b); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-3.c    2012-03-06 12:31:05.157039001 -0600
+@@ -0,0 +1,36 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "vabsduw" 7 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vui  fa3w(vui a, vui b)             { return __builtin_altivec_vabsduw (a,b); }
++vui  ad7(vui a, vui b)              { return __builtin_vec_absd (a,b); }
++vui  ad8(vbi a, vui b)              { return __builtin_vec_absd (a,b); }
++vui  ad9(vui a, vbi b)              { return __builtin_vec_absd (a,b); }
++vui  Dad7(vui a, vui b)             { return vec_absd (a,b); }
++vui  Dad8(vbi a, vui b)             { return vec_absd (a,b); }
++vui  Dad9(vui a, vbi b)             { return vec_absd (a,b); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-4.c    2012-03-06 12:31:05.158039002 -0600
+@@ -0,0 +1,34 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexbx" 5 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  le1b(long a, void *p)          { return __builtin_altivec_lvexbx (a,p); }
++vsc  leb1(long a, sc *p)            { return __builtin_vec_lvexbx (a,p); }
++vuc  leb2(long a, uc *p)            { return __builtin_vec_lvexbx (a,p); }
++vsc  Dleb1(long a, sc *p)           { return vec_lvexbx (a,p); }
++vuc  Dleb2(long a, uc *p)           { return vec_lvexbx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-5.c    2012-03-06 12:31:05.158039002 -0600
+@@ -0,0 +1,34 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexhx" 5 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vss  le2h(long a, void *p)          { return __builtin_altivec_lvexhx (a,p); }
++vss  leh1(long a, ss *p)            { return __builtin_vec_lvexhx (a,p); }
++vus  leh2(long a, us *p)            { return __builtin_vec_lvexhx (a,p); }
++vss  Dleh1(long a, ss *p)           { return vec_lvexhx (a,p); }
++vus  Dleh2(long a, us *p)           { return vec_lvexhx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-6.c    2012-03-06 12:31:05.158039002 -0600
+@@ -0,0 +1,40 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "lvexwx" 11 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsi  le3w(long a, void *p)          { return __builtin_altivec_lvexwx (a,p); }
++vsf  lew1(long a, sf *p)            { return __builtin_vec_lvexwx (a,p); }
++vsi  lew2(long a, si *p)            { return __builtin_vec_lvexwx (a,p); }
++vui  lew3(long a, ui *p)            { return __builtin_vec_lvexwx (a,p); }
++vsi  lew4(long a, sl *p)            { return __builtin_vec_lvexwx (a,p); }
++vui  lew5(long a, ul *p)            { return __builtin_vec_lvexwx (a,p); }
++vsf  Dlew1(long a, sf *p)           { return vec_lvexwx (a,p); }
++vsi  Dlew2(long a, si *p)           { return vec_lvexwx (a,p); }
++vui  Dlew3(long a, ui *p)           { return vec_lvexwx (a,p); }
++vsi  Dlew4(long a, sl *p)           { return vec_lvexwx (a,p); }
++vui  Dlew5(long a, ul *p)           { return vec_lvexwx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-7.c    2012-03-06 12:31:05.159039002 -0600
+@@ -0,0 +1,42 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexbx" 13 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se1b(vsc v, long a, vsc *p)    { __builtin_altivec_stvexbx (v,a,p); }
++void seb1(vsc v, long a, sc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb2(vuc v, long a, uc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb3(vbc v, long a, sc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb4(vbc v, long a, uc *p)     { __builtin_vec_stvexbx (v,a,p); }
++void seb5(vsc v, long a, void *p)   { __builtin_vec_stvexbx (v,a,p); }
++void seb6(vuc v, long a, void *p)   { __builtin_vec_stvexbx (v,a,p); }
++void Dseb1(vsc v, long a, sc *p)    { vec_stvexbx (v,a,p); }
++void Dseb2(vuc v, long a, uc *p)    { vec_stvexbx (v,a,p); }
++void Dseb3(vbc v, long a, sc *p)    { vec_stvexbx (v,a,p); }
++void Dseb4(vbc v, long a, uc *p)    { vec_stvexbx (v,a,p); }
++void Dseb5(vsc v, long a, void *p)  { vec_stvexbx (v,a,p); }
++void Dseb6(vuc v, long a, void *p)  { vec_stvexbx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-8.c    2012-03-06 12:31:05.159039002 -0600
+@@ -0,0 +1,42 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexhx" 13 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se2h(vss v, long a, vss *p)    { __builtin_altivec_stvexhx (v,a,p); }
++void seh1(vss v, long a, ss *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh2(vus v, long a, us *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh3(vbs v, long a, ss *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh4(vbs v, long a, us *p)     { __builtin_vec_stvexhx (v,a,p); }
++void seh5(vss v, long a, void *p)   { __builtin_vec_stvexhx (v,a,p); }
++void seh6(vus v, long a, void *p)   { __builtin_vec_stvexhx (v,a,p); }
++void Dseh1(vss v, long a, ss *p)    { vec_stvexhx (v,a,p); }
++void Dseh2(vus v, long a, us *p)    { vec_stvexhx (v,a,p); }
++void Dseh3(vbs v, long a, ss *p)    { vec_stvexhx (v,a,p); }
++void Dseh4(vbs v, long a, us *p)    { vec_stvexhx (v,a,p); }
++void Dseh5(vss v, long a, void *p)  { vec_stvexhx (v,a,p); }
++void Dseh6(vus v, long a, void *p)  { vec_stvexhx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c       1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/altivec2_builtin-9.c    2012-03-06 12:31:05.159039002 -0600
+@@ -0,0 +1,46 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -maltivec2" } */
++/* { dg-final { scan-assembler-times "stvexwx" 17 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void se3w(vsi v, long a, vsi *p)    { __builtin_altivec_stvexwx (v,a,p); }
++void sew1(vsf v, long a, sf *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew2(vsi v, long a, si *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew3(vui v, long a, ui *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew4(vbi v, long a, si *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew5(vbi v, long a, ui *p)     { __builtin_vec_stvexwx (v,a,p); }
++void sew6(vsf v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void sew7(vsi v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void sew8(vui v, long a, void *p)   { __builtin_vec_stvexwx (v,a,p); }
++void Dsew1(vsf v, long a, sf *p)    { vec_stvexwx (v,a,p); }
++void Dsew2(vsi v, long a, si *p)    { vec_stvexwx (v,a,p); }
++void Dsew3(vui v, long a, ui *p)    { vec_stvexwx (v,a,p); }
++void Dsew4(vbi v, long a, si *p)    { vec_stvexwx (v,a,p); }
++void Dsew5(vbi v, long a, ui *p)    { vec_stvexwx (v,a,p); }
++void Dsew6(vsf v, long a, void *p)  { vec_stvexwx (v,a,p); }
++void Dsew7(vsi v, long a, void *p)  { vec_stvexwx (v,a,p); }
++void Dsew8(vui v, long a, void *p)  { vec_stvexwx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-1.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-1.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-1.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-1.c        2012-03-06 12:31:15.921038995 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "lvlx" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc1(long a, void *p)           { return __builtin_altivec_lvlx (a,p); }
++vsf  llx01(long a, vsf *p)          { return __builtin_vec_lvlx (a,p); }
++vsf  llx02(long a, sf *p)           { return __builtin_vec_lvlx (a,p); }
++vbi  llx03(long a, vbi *p)          { return __builtin_vec_lvlx (a,p); }
++vsi  llx04(long a, vsi *p)          { return __builtin_vec_lvlx (a,p); }
++vsi  llx05(long a, si *p)           { return __builtin_vec_lvlx (a,p); }
++vui  llx06(long a, vui *p)          { return __builtin_vec_lvlx (a,p); }
++vui  llx07(long a, ui *p)           { return __builtin_vec_lvlx (a,p); }
++vbs  llx08(long a, vbs *p)          { return __builtin_vec_lvlx (a,p); }
++vp   llx09(long a, vp *p)           { return __builtin_vec_lvlx (a,p); }
++vss  llx10(long a, vss *p)          { return __builtin_vec_lvlx (a,p); }
++vss  llx11(long a, ss *p)           { return __builtin_vec_lvlx (a,p); }
++vus  llx12(long a, vus *p)          { return __builtin_vec_lvlx (a,p); }
++vus  llx13(long a, us *p)           { return __builtin_vec_lvlx (a,p); }
++vbc  llx14(long a, vbc *p)          { return __builtin_vec_lvlx (a,p); }
++vsc  llx15(long a, vsc *p)          { return __builtin_vec_lvlx (a,p); }
++vsc  llx16(long a, sc *p)           { return __builtin_vec_lvlx (a,p); }
++vuc  llx17(long a, vuc *p)          { return __builtin_vec_lvlx (a,p); }
++vuc  llx18(long a, uc *p)           { return __builtin_vec_lvlx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-2.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-2.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-2.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-2.c        2012-03-06 12:31:15.921038995 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "lvlxl" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc2(long a, void *p)           { return __builtin_altivec_lvlxl (a,p); }
++vsf  llxl01(long a, vsf *p)         { return __builtin_vec_lvlxl (a,p); }
++vsf  llxl02(long a, sf *p)          { return __builtin_vec_lvlxl (a,p); }
++vbi  llxl03(long a, vbi *p)         { return __builtin_vec_lvlxl (a,p); }
++vsi  llxl04(long a, vsi *p)         { return __builtin_vec_lvlxl (a,p); }
++vsi  llxl05(long a, si *p)          { return __builtin_vec_lvlxl (a,p); }
++vui  llxl06(long a, vui *p)         { return __builtin_vec_lvlxl (a,p); }
++vui  llxl07(long a, ui *p)          { return __builtin_vec_lvlxl (a,p); }
++vbs  llxl08(long a, vbs *p)         { return __builtin_vec_lvlxl (a,p); }
++vp   llxl09(long a, vp *p)          { return __builtin_vec_lvlxl (a,p); }
++vss  llxl10(long a, vss *p)         { return __builtin_vec_lvlxl (a,p); }
++vss  llxl11(long a, ss *p)          { return __builtin_vec_lvlxl (a,p); }
++vus  llxl12(long a, vus *p)         { return __builtin_vec_lvlxl (a,p); }
++vus  llxl13(long a, us *p)          { return __builtin_vec_lvlxl (a,p); }
++vbc  llxl14(long a, vbc *p)         { return __builtin_vec_lvlxl (a,p); }
++vsc  llxl15(long a, vsc *p)         { return __builtin_vec_lvlxl (a,p); }
++vsc  llxl16(long a, sc *p)          { return __builtin_vec_lvlxl (a,p); }
++vuc  llxl17(long a, vuc *p)         { return __builtin_vec_lvlxl (a,p); }
++vuc  llxl18(long a, uc *p)          { return __builtin_vec_lvlxl (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-3.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-3.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-3.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-3.c        2012-03-06 12:31:15.922038996 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "lvrx" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc3(long a, void *p)           { return __builtin_altivec_lvrx (a,p); }
++vsf  lrx01(long a, vsf *p)          { return __builtin_vec_lvrx (a,p); }
++vsf  lrx02(long a, sf *p)           { return __builtin_vec_lvrx (a,p); }
++vbi  lrx03(long a, vbi *p)          { return __builtin_vec_lvrx (a,p); }
++vsi  lrx04(long a, vsi *p)          { return __builtin_vec_lvrx (a,p); }
++vsi  lrx05(long a, si *p)           { return __builtin_vec_lvrx (a,p); }
++vui  lrx06(long a, vui *p)          { return __builtin_vec_lvrx (a,p); }
++vui  lrx07(long a, ui *p)           { return __builtin_vec_lvrx (a,p); }
++vbs  lrx08(long a, vbs *p)          { return __builtin_vec_lvrx (a,p); }
++vp   lrx09(long a, vp *p)           { return __builtin_vec_lvrx (a,p); }
++vss  lrx10(long a, vss *p)          { return __builtin_vec_lvrx (a,p); }
++vss  lrx11(long a, ss *p)           { return __builtin_vec_lvrx (a,p); }
++vus  lrx12(long a, vus *p)          { return __builtin_vec_lvrx (a,p); }
++vus  lrx13(long a, us *p)           { return __builtin_vec_lvrx (a,p); }
++vbc  lrx14(long a, vbc *p)          { return __builtin_vec_lvrx (a,p); }
++vsc  lrx15(long a, vsc *p)          { return __builtin_vec_lvrx (a,p); }
++vsc  lrx16(long a, sc *p)           { return __builtin_vec_lvrx (a,p); }
++vuc  lrx17(long a, vuc *p)          { return __builtin_vec_lvrx (a,p); }
++vuc  lrx18(long a, uc *p)           { return __builtin_vec_lvrx (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-4.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-4.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-4.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-4.c        2012-03-06 12:31:15.922038996 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "lvrxl" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++vsc  lc4(long a, void *p)           { return __builtin_altivec_lvrxl (a,p); }
++vsf  lrxl01(long a, vsf *p)         { return __builtin_vec_lvrxl (a,p); }
++vsf  lrxl02(long a, sf *p)          { return __builtin_vec_lvrxl (a,p); }
++vbi  lrxl03(long a, vbi *p)         { return __builtin_vec_lvrxl (a,p); }
++vsi  lrxl04(long a, vsi *p)         { return __builtin_vec_lvrxl (a,p); }
++vsi  lrxl05(long a, si *p)          { return __builtin_vec_lvrxl (a,p); }
++vui  lrxl06(long a, vui *p)         { return __builtin_vec_lvrxl (a,p); }
++vui  lrxl07(long a, ui *p)          { return __builtin_vec_lvrxl (a,p); }
++vbs  lrxl08(long a, vbs *p)         { return __builtin_vec_lvrxl (a,p); }
++vp   lrxl09(long a, vp *p)          { return __builtin_vec_lvrxl (a,p); }
++vss  lrxl10(long a, vss *p)         { return __builtin_vec_lvrxl (a,p); }
++vss  lrxl11(long a, ss *p)          { return __builtin_vec_lvrxl (a,p); }
++vus  lrxl12(long a, vus *p)         { return __builtin_vec_lvrxl (a,p); }
++vus  lrxl13(long a, us *p)          { return __builtin_vec_lvrxl (a,p); }
++vbc  lrxl14(long a, vbc *p)         { return __builtin_vec_lvrxl (a,p); }
++vsc  lrxl15(long a, vsc *p)         { return __builtin_vec_lvrxl (a,p); }
++vsc  lrxl16(long a, sc *p)          { return __builtin_vec_lvrxl (a,p); }
++vuc  lrxl17(long a, vuc *p)         { return __builtin_vec_lvrxl (a,p); }
++vuc  lrxl18(long a, uc *p)          { return __builtin_vec_lvrxl (a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-5.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-5.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-5.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-5.c        2012-03-06 12:31:15.922038996 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "stvlx" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc1(vsc v, long a, void *p)    { __builtin_altivec_stvlx (v,a,p); }
++void slx01(vsf v, long a, vsf *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx02(vsf v, long a, sf *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx03(vbi v, long a, vbi *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx04(vsi v, long a, vsi *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx05(vsi v, long a, si *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx06(vui v, long a, vui *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx07(vui v, long a, ui *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx08(vbs v, long a, vbs *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx09(vp v, long a, vp *p)     { __builtin_vec_stvlx (v,a,p); }
++void slx10(vss v, long a, vss *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx11(vss v, long a, ss *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx12(vus v, long a, vus *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx13(vus v, long a, us *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx14(vbc v, long a, vbc *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx15(vsc v, long a, vsc *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx16(vsc v, long a, sc *p)    { __builtin_vec_stvlx (v,a,p); }
++void slx17(vuc v, long a, vuc *p)   { __builtin_vec_stvlx (v,a,p); }
++void slx18(vuc v, long a, uc *p)    { __builtin_vec_stvlx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-6.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-6.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-6.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-6.c        2012-03-06 12:31:15.923039000 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "stvlxl" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc2(vsc v, long a, void *p)    { __builtin_altivec_stvlxl (v,a,p); }
++void slxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl02(vsf v, long a, sf *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl05(vsi v, long a, si *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl06(vui v, long a, vui *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl07(vui v, long a, ui *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl09(vp v, long a, vp *p)    { __builtin_vec_stvlxl (v,a,p); }
++void slxl10(vss v, long a, vss *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl11(vss v, long a, ss *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl12(vus v, long a, vus *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl13(vus v, long a, us *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl16(vsc v, long a, sc *p)   { __builtin_vec_stvlxl (v,a,p); }
++void slxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvlxl (v,a,p); }
++void slxl18(vuc v, long a, uc *p)   { __builtin_vec_stvlxl (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-7.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-7.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-7.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-7.c        2012-03-06 12:31:15.923039000 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "stvrx" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc3(vsc v, long a, void *p)    { __builtin_altivec_stvrx (v,a,p); }
++void srx01(vsf v, long a, vsf *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx02(vsf v, long a, sf *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx03(vbi v, long a, vbi *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx04(vsi v, long a, vsi *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx05(vsi v, long a, si *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx06(vui v, long a, vui *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx07(vui v, long a, ui *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx08(vbs v, long a, vbs *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx09(vp v, long a, vp *p)     { __builtin_vec_stvrx (v,a,p); }
++void srx10(vss v, long a, vss *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx11(vss v, long a, ss *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx12(vus v, long a, vus *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx13(vus v, long a, us *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx14(vbc v, long a, vbc *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx15(vsc v, long a, vsc *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx16(vsc v, long a, sc *p)    { __builtin_vec_stvrx (v,a,p); }
++void srx17(vuc v, long a, vuc *p)   { __builtin_vec_stvrx (v,a,p); }
++void srx18(vuc v, long a, uc *p)    { __builtin_vec_stvrx (v,a,p); }
+diff -ruN gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-8.c gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-8.c
+--- gcc-4.6.2-orig/gcc/testsuite/gcc.target/powerpc/cell_builtin-8.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.2/gcc/testsuite/gcc.target/powerpc/cell_builtin-8.c        2012-03-06 12:31:15.923039000 -0600
+@@ -0,0 +1,48 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
++/* { dg-require-effective-target powerpc_altivec_ok } */
++/* { dg-options "-O2 -maltivec -mcpu=cell" } */
++/* { dg-final { scan-assembler-times "stvrxl" 19 } } */
++
++#include <altivec.h>
++
++typedef __vector signed char vsc;
++typedef __vector signed short vss;
++typedef __vector signed int vsi;
++typedef __vector unsigned char vuc;
++typedef __vector unsigned short vus;
++typedef __vector unsigned int vui;
++typedef __vector bool char vbc;
++typedef __vector bool short vbs;
++typedef __vector bool int vbi;
++typedef __vector float vsf;
++typedef __vector pixel vp;
++typedef signed char sc;
++typedef signed short ss;
++typedef signed int si;
++typedef signed long sl;
++typedef unsigned char uc;
++typedef unsigned short us;
++typedef unsigned int ui;
++typedef unsigned long ul;
++typedef float sf;
++
++void sc4(vsc v, long a, void *p)    { __builtin_altivec_stvrxl (v,a,p); }
++void srxl01(vsf v, long a, vsf *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl02(vsf v, long a, sf *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl03(vbi v, long a, vbi *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl04(vsi v, long a, vsi *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl05(vsi v, long a, si *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl06(vui v, long a, vui *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl07(vui v, long a, ui *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl08(vbs v, long a, vbs *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl09(vp v, long a, vp *p)    { __builtin_vec_stvrxl (v,a,p); }
++void srxl10(vss v, long a, vss *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl11(vss v, long a, ss *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl12(vus v, long a, vus *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl13(vus v, long a, us *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl14(vbc v, long a, vbc *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl15(vsc v, long a, vsc *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl16(vsc v, long a, sc *p)   { __builtin_vec_stvrxl (v,a,p); }
++void srxl17(vuc v, long a, vuc *p)  { __builtin_vec_stvrxl (v,a,p); }
++void srxl18(vuc v, long a, uc *p)   { __builtin_vec_stvrxl (v,a,p); }
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.experimental_move.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.experimental_move.patch
new file mode 100644 (file)
index 0000000..b9642ed
--- /dev/null
@@ -0,0 +1,32 @@
+diff -ruN gcc-4.4.0/gcc/config/rs6000/rs6000.c gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.c
+--- gcc-4.4.0/gcc/config/rs6000/rs6000.c       2009-03-17 15:18:21.000000000 -0500
++++ gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.c      2009-12-04 10:36:44.000000000 -0600
+@@ -11032,6 +11059,14 @@
+         mode = SImode;
+         gen_func.mov = gen_movsi;
+       }
++      else if (TARGET_COPY_UNALIGNED && bytes == 3 && offset > 0)
++      {
++        /* We generate a single unaligned SI move instead of 2 (HI, QI) */
++        move_bytes = 3;
++        mode = SImode;
++        gen_func.mov = gen_movsi;
++        offset--;
++      }
+       else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
+       {                       /* move 2 bytes */
+         move_bytes = 2;
+diff -ruN gcc-4.4.0/gcc/config/rs6000/rs6000.opt gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.opt
+--- gcc-4.4.0/gcc/config/rs6000/rs6000.opt     2009-02-20 09:20:38.000000000 -0600
++++ gcc-4.4.0-e500mc64/gcc/config/rs6000/rs6000.opt    2009-09-30 13:51:17.000000000 -0500
+@@ -201,6 +201,10 @@
+ Target RejectNegative Joined
+ -misel=yes/no Deprecated option.  Use -misel/-mno-isel instead
++mcopy-unaligned
++Target Report Var(TARGET_COPY_UNALIGNED)
++Generate unaligned word load and stores to move 3 bytes
++
+ mspe
+ Target
+ Generate SPE SIMD instructions on E500
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.extelim-v3.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.extelim-v3.patch
new file mode 100644 (file)
index 0000000..e124b18
--- /dev/null
@@ -0,0 +1,3491 @@
+Eliminate sign and zero extensions in PPC generated code
+A new module is introduced 'extelim.c' and a new RTL pass is introduced.
+The '-f[no-]extelim' flag controls this pass and is enabled at -O2 and above.
+The algorithm is based on the paper "Effective Sign Extension Elimination", Kawahito, et. al.
+More details on implementation in the extelim.c module.
+
+--- gcc-4.6-branch-clean/gcc/opts.c    2011-07-27 12:02:02.483850879 -0500
++++ gcc-4.6-branch/gcc/opts.c  2011-07-25 17:59:00.911975444 -0500
+@@ -492,6 +492,7 @@
+     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
+     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
+     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
++    { OPT_LEVELS_2_PLUS, OPT_fextelim, NULL, 1 },
+     /* -O3 optimizations.  */
+     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
+--- gcc-4.6-branch-clean/gcc/tree-pass.h       2011-07-27 12:02:02.485981448 -0500
++++ gcc-4.6-branch/gcc/tree-pass.h     2011-07-25 17:59:00.912976334 -0500
+@@ -483,6 +483,7 @@
+ extern struct rtl_opt_pass pass_initial_value_sets;
+ extern struct rtl_opt_pass pass_unshare_all_rtl;
+ extern struct rtl_opt_pass pass_instantiate_virtual_regs;
++extern struct rtl_opt_pass pass_rtl_extelim;
+ extern struct rtl_opt_pass pass_rtl_fwprop;
+ extern struct rtl_opt_pass pass_rtl_fwprop_addr;
+ extern struct rtl_opt_pass pass_jump2;
+--- gcc-4.6-branch-clean/gcc/timevar.def       2011-07-27 12:02:02.487999008 -0500
++++ gcc-4.6-branch/gcc/timevar.def     2011-07-25 17:59:00.913979563 -0500
+@@ -180,6 +180,7 @@
+ DEFTIMEVAR (TV_VARCONST              , "varconst")
+ DEFTIMEVAR (TV_LOWER_SUBREG        , "lower subreg")
+ DEFTIMEVAR (TV_JUMP                  , "jump")
++DEFTIMEVAR (TV_EXTELIM               , "extension elimination")
+ DEFTIMEVAR (TV_FWPROP                , "forward prop")
+ DEFTIMEVAR (TV_CSE                   , "CSE")
+ DEFTIMEVAR (TV_DCE                   , "dead code elimination")
+--- gcc-4.6-branch-clean/gcc/common.opt        2011-07-27 12:02:02.490978128 -0500
++++ gcc-4.6-branch/gcc/common.opt      2011-07-25 17:59:00.915979093 -0500
+@@ -996,6 +996,10 @@
+ Common Report Var(flag_eliminate_dwarf2_dups)
+ Perform DWARF2 duplicate elimination
++fextelim
++Common Report Var(flag_extelim)
++Perform zero/sign extension removal
++
+ fipa-sra
+ Common Report Var(flag_ipa_sra) Init(0) Optimization
+ Perform interprocedural reduction of aggregates
+--- gcc-4.6-branch-clean/gcc/Makefile.in       2011-07-27 12:02:02.498976606 -0500
++++ gcc-4.6-branch/gcc/Makefile.in     2011-07-25 17:59:00.919975303 -0500
+@@ -1233,6 +1233,7 @@
+       explow.o \
+       expmed.o \
+       expr.o \
++      extelim.o \
+       final.o \
+       fixed-value.o \
+       fold-const.o \
+@@ -2891,6 +2892,11 @@
+    reload.h langhooks.h intl.h $(TM_P_H) $(TARGET_H) \
+    tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \
+    $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h $(SSAEXPAND_H)
++extelim.o : extelim.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
++   $(TREE_H) $(TM_P_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) \
++   insn-config.h $(FUNCTION_H) $(EXPR_H) $(INSN_ATTR_H) $(RECOG_H) \
++   toplev.h $(TARGET_H) $(TIMEVAR_H) $(OPTABS_H) insn-codes.h  \
++   output.h $(PARAMS_H) $(TREE_PASS_H) $(CGRAPH_H)
+ dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+    $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \
+    langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) output.h
+--- gcc-4.6-branch-clean/gcc/passes.c  2011-07-27 12:02:02.502976386 -0500
++++ gcc-4.6-branch/gcc/passes.c        2011-07-25 17:59:00.922975752 -0500
+@@ -990,6 +990,7 @@
+       NEXT_PASS (pass_web);
+       NEXT_PASS (pass_rtl_cprop);
+       NEXT_PASS (pass_cse2);
++      NEXT_PASS (pass_rtl_extelim);
+       NEXT_PASS (pass_rtl_dse1);
+       NEXT_PASS (pass_rtl_fwprop_addr);
+       NEXT_PASS (pass_inc_dec);
+--- gcc-4.6.1-clean/gcc/extelim.c      1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.1/gcc/extelim.c    2011-11-14 15:43:10.041143996 -0600
+@@ -0,0 +1,3407 @@
++/* Redundant extension elimination 
++   Copyright (C) 2010 Free Software Foundation, Inc.
++   Contributed by John Russo (john.russo@freescale.com)
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it under
++the terms of the GNU General Public License as published by the Free
++Software Foundation; either version 3, or (at your option) any later
++version.
++
++GCC is distributed in the hope that it will be useful, but WITHOUT ANY
++WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++/*
++PURPOSE: Implement a method for eliminating redundant and superflous sign
++extension instructions from 64-bit PPC e5500 generated code.
++
++MOTIVATING EXAMPLE:
++The Nullstone loop_6.c kernel looks like:
++  int i;
++  int a[100];
++  
++  ref_int_p (&a[0]);
++  
++  for (i=2; i<100; i++)
++    a[i] = a[i-1] + a[i-2];
++  
++The final, generated code for the loop body is:
++
++32-bit                  64-bit
++add     r25,r11,r0    add     r5,r5,r8
++add     r26,r0,r25    addi    r4,r4,12
++stw     r25,0(r9)     add     r27,r5,r8
++add     r27,r25,r26   stw     r5,0(r9)
++stw     r26,4(r9)     extsw   r12,r27       <===
++add     r28,r26,r27   stw     r27,4(r9)
++stw     r27,8(r9)     add     r6,r5,r12
++add     r29,r27,r28   add     r28,r6,r12
++stw     r28,12(r9)    stw     r6,8(r9)
++add     r30,r28,r29   extsw   r0,r28        <===
++stw     r29,16(r9)    stw     r28,12(r9)
++add     r12,r29,r30   add     r7,r6,r0
++stw     r30,20(r9)    add     r29,r7,r0
++add     r3,r30,r12    stw     r7,16(r9)
++stw     r12,24(r9)    extsw   r3,r29        <===
++add     r4,r12,r3     stw     r29,20(r9)
++stw     r3,28(r9)     add     r10,r7,r3
++add     r5,r3,r4      add     r30,r10,r3
++stw     r4,32(r9)     stw     r10,24(r9)
++add     r6,r4,r5      extsw   r8,r30        <===
++stw     r5,36(r9)     stw     r30,28(r9)
++add     r7,r5,r6      add     r11,r10,r8
++stw     r6,40(r9)     add     r12,r11,r8
++add     r8,r6,r7      stw     r11,32(r9)
++stw     r7,44(r9)     extsw   r26,r12       <===
++add     r10,r7,r8     stw     r12,36(r9)
++stw     r8,48(r9)     add     r0,r11,r26
++add     r11,r8,r10    add     r3,r0,r26
++stw     r10,52(r9)    stw     r0,40(r9)
++add     r0,r10,r11    subfic  r26,r4,100
++stw     r11,56(r9)    stw     r3,44(r9)
++stw     r0,60(r9)     extsw   r5,r0         <===
++addi    r9,r9,64      extsw   r8,r3         <===
++bdnz+   10000640        extsw   r4,r4         <===
++                        clrldi  r26,r26,32
++                        addi    r9,r9,48
++                        bdnz+   10000890 
++
++GENERAL APPROACH:
++Consider a machine whose native register size is 64-bits
++
++0          3132         63
++|-----------||-----------|
++
++where bit 63 is the LSB and bit 0 is the MSB of a long int
++and bit 63 is the LSB and bit 32 is the MSB of an int.
++
++Sign and zero extension are inserted to RTL to preserve the
++operation's semantics when the operands used are not the 
++native register size since normally the machine only performs
++the operation using a native register size. In practice, many
++of the inserted extensions are not necessary.
++
++First, the extension may simply be redundant. That is, the 
++same operation is performed on the same operands. The redundant
++extensions can be eliminated.
++
++Secondly, if the extended portion of the register (the "upper" bits)
++are not essential to the calculations performed on the output of the
++extension, then the extension is not necessary. For example, given
++int (32-bit) inputs and outputs:
++
++c = a + b
++d = sxt(c)
++e = d + 1; 
++
++The "upper" bits of d (bit 0-31) do not affect the calculation
++of e. It doesn't matter what the "upper" bits of d are, the int result
++e is the same regardless of the sxt instruction.
++
++Thirdly, the extensions may not be necessary if the operands are
++already extended and the operation preserves the extended bits.
++
++a = mem[&b] ; sign extending load
++c = a + 1
++d = sxt(c)
++
++Here, a is generated by a sign extending load, the operation
++does nothing to invalidate the extension to c, thus the extension
++on c to d is not necessary.
++
++In each case, the redundant extension must be replaced by a copy,
++with the copy to be optimized out in later phases.
++
++The three cases described above form the general idea behind the
++algorithms implemented here to eliminate redundant and unneccessary
++extensions. 
++
++Sign extensions do not have to be preserved for overflow conditions
++since signed overflow behavior is not defined in C. For example,
++take a 16-bit variable in a 32-bit register. It is ok
++for 0x0000_7fff to overflow to 0x0000_8000 and not 0xffff_8000.
++This implies that it is not necessary to preserve the sign
++extension.
++
++Unsigned overflow extension need to be preserved because 
++unsigned overflow is modulo. For example, a 16-bit unsigned 
++overflow of 0x0000_FFFF must be 0x0000_0000 in a 32-bit register, 
++not 0x0001_0000. In order to remove the unsigned zero extension,
++we would need to range check the variable to be sure it doesn't
++overflow.  
++
++RTL ANALYSIS:
++I looked at the RTL representation after RTL generation (.expand) and
++after the first forward propagation (.fwprop1). Since RTL is not compact
++when printing out, I reduced the .fwprop1 RTL to this pseudocode:
++
++(note: sxt,zxt mean double word length, 64-bit, extension).
++
++(1)     r198 = m[r113+ #112]     ; load a[0]
++(2)     r174 = sxt(r198)
++(3)     r199 = m[r113+ #116]     ; load a[1] 
++(4)     r186 = sxt(r199)
++(5)     r181 = r113 + #120       ; load &a[2]
++(6)     r180 = 2                 ; i = 2
++(7)     L1:
++(8)     r200 = r174 + r186       ; t1 = a[i-1] + a[i-2]
++(9)     r174 = sxt(r200)
++(10)    m[r181] = r200           ; a[i] = t1
++(11)    r201 = r200 + r186       ; t2 = t1 + a[i-1]
++(12)    r186 = sxt(r201)
++(13)    m[r181+4] = r201         ; a[i+1] = t2
++(14)    r202 = r180 + 2          ; i += 2
++(14.1)  r180 = sxt(r202)     
++(15)    r203 = 100 - r202        ; used to calc loop remainder
++(16)    r185 = zxt(r203)         ; used to calc loop remainder
++(17)    r181 = r181 + 8          ; address induction var
++(18)    ccr204 = cmp(r202,#98)   ; set CC
++(19)    BNE ccr204,L1            ; branch 
++
++In the pseudo-code, you see several sign extension candidates: (2),(4),
++(9), (12), (14.1), (16).  
++
++ALGORITHM:
++To eliminate the extra sign ext you have to look at (1) the definitions
++of the source of the sign extensions and/or (2) look at the uses of the target
++of the sign extensions. In either case, if doing a global elimination
++pass, you'll need def-use chain information. 
++
++The algorithms are recursive. Using the use/def and def/use chains
++we attempt to find ultimately whether the extension is relevant
++or not. 
++
++
++Example 1.
++Extensions (2) and (4) are not put in the candidate list because
++they are combined into a load/ext pair that is ultimately generated
++as sign extending loads.
++
++Take the sign extension at (9), r174 = sxt(r200).
++Def analysis shows that r200 is defined by 2 registers, thus no
++further def analysis recursion can occur.
++Use analysis. Find all the uses of r174. There is 1 use at (8) r200 = r174 + r186. 
++The extension does not affect the add operation results. Continuing, we look at
++the uses of r200 to see if the results of operations on r200 need the sign extended bits.
++We see 2 uses of r200 at (10) and (11). (10) is a 32-bit store of r200,
++so the sign extended bits are irrelevant. (11), however, is an unknown,
++so we must look that the uses of this result, r201. A similar sequence
++occurs for r201 when it defines r186. Looking at the uses of r186 at 
++(8) and (11), we have already visited those statements so they have
++been covered already. So it appears that the sxt to r174 at (9) ultimately
++dead-ends to a store instruction that doesn't case about the sign extended
++bits. The sxt at (9) can be removed.
++
++The remaining extensions are processed similarly.
++
++PROGRAM STRUCTURE:
++
++extension elimination                            -- main entry point
++ find extensions                                 -- identify extension candidates
++ extension duplication                           -- insert extension at strategic points to
++                                                    enable removal of extensions at more frequently
++                                                    executed points.
++ find extensions                                 -- recreate extension candidate list
++ sort extensions                                 -- sort extension candidate list by loop depth
++ for each ext in list                            -- process each extension candidate
++  eliminate one extension
++ replace marked candidates with copy             -- optimize the extension
++
++PSEUDOCODE:
++
++Create working list of sign extensions, sxt_list
++
++For each insn, insn_sxt,  in sxt_list 
++   ext_needed = true 
++   For all insns, insn_def, that DEFINE and REACH the SOURCE_REG(insn_sxt)
++     ext_needed = analyze_def(insn_def, insn_sxt)
++     if (ext_needed)
++       break;
++   end_loop
++   if (ext_needed)
++     For all insns, insn_use, that USE and are REACHED by the DEST_REG(insn_sxt)
++       ext_needed = analyze_use(insn_use, insn_sxt)
++       if (ext_needed)
++         break;
++     end_loop
++    
++   if (!ext_needed)
++     mark_for_replace_with_copy(I)
++end_loop
++
++For each insn, insn_sxt, in sxt_list
++   if (insn_sxt is marked for replacement)
++     replace_insn_with_copy(insn_sxt)
++end_loop
++
++--------------------------
++function: analyze_def(def)
++---------------------------
++return true if extension is needed, false otherwise.
++
++destination_operand = defined operand of source 
++source_operand = source operand of def 
++
++if (have_seen_this_insn_already (def))
++ return true;
++
++set_seen_this_insn_flag (def)
++
++analysis_result = analyze_result_def (def)
++switch (analysis_result)
++ case source_operand_is_extended:
++  return false
++ case stop_recursion:
++  return true
++ case continue_recursion: 
++  break;
++
++ext_needed = true;
++
++For all insns, insn_def, that USE and REACHED by the register of destination_operand 
++ ext_needed = analyze_def(insn_def))
++ if (ext_needed)
++  break;
++end_loop
++
++return ext_needed 
++
++--------------------------
++function: analyze_use(use)
++---------------------------
++return true if extension is needed, false otherwise.
++
++destination_operand = destination operand of use
++source_operand = source operand of use
++
++if (have_seen_this_insn_already (use))
++ return false;
++
++set_seen_this_insn_flag (use)
++
++analysis_result = analyze_result_use (use)
++switch (analysis_result)
++ case low_bits_not_affected_by_use:
++  return false
++ case low_bits_affected_by_use:
++  return true
++ case look_at_uses_of_destination_operand
++  break;
++
++ext_needed = true;
++For all insns, insn_use, that USE the register of destination_operand 
++    ext_needed = analyze_use(insn_use))
++    if (ext_needed)
++     break;
++end_loop
++
++return ext_needed 
++
++REFERENCES:
++
++"Effective Sign Extension Elimination", Kawahito, Komatsu, Nakatani. 
++IBM Tokyo Researc Laboratory.
++
++"New sign/zero extension elimination pass", deVries.
++http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01529.html
++*/
++
++/*
++Iteration 4: pre-ZERO_EXTEND version, duplicates sign_extend at uses
++Iteration 5: begin supporting ZERO_EXTEND, crashes on Coremark.
++Iteration 6: revert to 4, support SI:HI sign_extensions.
++Iteration 7: Add support for zero extend. This version deletes
++ "inserted" duplicate extensions when redundant and propagates
++ the copied value. This propagate fails in other_tests/test2.sh.
++ I am reverting back to replacing the "inserted" extension to a copy.
++ Copy propagation should always be able to eliminate this copy.
++ Coremark was stable, however.
++Iteration 8: Revert to change extensions to copy, regardless of whether
++ the extension was duplicated or not. 
++ Refactor setting of dest,src in analyze_ext_use, analyze_ext_def, now
++ handled with a single function.
++Iteration 9: 
++ Inserted redundant extensions at function return points.
++ Sorted the order that extensions are processed by loop depth.
++ Additional cases in upper_bits_do_not_affect_dest
++Iteration 10:
++ Fixes for test failures. A major problem was uncovered where
++ the "visited" flag was not properly cleared. This meant that
++ each time a new extension was processed, it appeared that some
++ extensions were visited already and there were not. The result
++ was false removals. This fix significantly affects the benchmark.
++ Another change was to comment out the duplicate_exts_at_uses. This
++ seemed to have little effect now that the visited flag issue is
++ fixed. 
++Iteration 11:
++ Cleanup warnings during build.
++Iteration 12:
++ QImode support started.
++Iteration 13:
++ Redesign and refactor analyze_ext_use, analyze_ext_def
++Iteration 14:
++ Continue redesign and refactor of analyze_ext_use, analyze_ext_def
++ Debugging paper_example.c
++Iteration 15:
++ cond_c fix
++Iteration 16: (not tested)
++ Refactor check_compare code 
++ Refactor action decision in PARALLEL 
++ Allow pass-thru on insns that are marked for replace copy 
++ instead of stopping recursion if we see a marked insn.
++ Examining lshiftrt.c program (signed and unsigned).
++Iteration 17: 
++ Refactor mostly complete. Passed all local testing including
++ nas and perfect. Best coremark results so far.
++Iteration 18:
++ Oops. analyze_ext_def was disabled. Enabling it improves
++ Coremark. Passed coremark, perfect.
++Iteration 19:
++ Local tests are passing. Tested with glibc.
++ Added statistics.
++ Fixed elimination from CALL output in operand_is_extended.
++  This impacted Coremark went from 6300 to 6170. But is necessary.
++ More safety for used regs in analyze_ext_def.
++ More safety for the types of extensions.
++Iteration 20:
++ Fixes for various tests.
++Iteration 21:
++ pr43017 -funroll_loops fix.
++Iteration 22:
++ Fixes for AND immediate in operand_is_extended.
++ Cosmetic cleanup.
++Iteration 23:
++ Fixes for consumer-2,spec2k,spec2k6. Handle 
++ SUBREG_PROMOTED_VAR_P flags on operands whose
++ dependent extension has been eliminated.
++Iteration 24:
++ Fixed problem in native build during bootstrapping.
++ Extelim was considering debug_insns and should have
++ ignored them. This resulted in a compare fail between
++ stage2 and stage3.
++Iteration 25:
++ - Post-release 4.6.1 development
++ - Full duplication of extensions at uses turned on.
++ - Recursion into original extension no longer kills optimization (analyze_ext_def only)
++ - Allow some duplication into the same block if it enables insn selection
++ - Allow CCmode and CCUNSmode into mode_supported_p
++Iteration 26:
++ - Solve ICEs due to null df-ref.
++Iteration 27:
++ - Fixed issue with duplication of extension at a self-assign.
++ - Some fixes for copying flags during duplication
++ - Some fixes for counting register uses.
++Iteration 28:
++ - Fixed issue with duplication of extension when use has multiple
++   reaching definitions.
++Iteration 29:
++ - Release candidate for Q42011 release iteration.
++Iteration 30:
++ - Turn off extension duplication - minimally effective
++ 
++*/
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "rtl.h"
++#include "tree.h"
++#include "tm_p.h"
++#include "flags.h"
++#include "regs.h"
++#include "hard-reg-set.h"
++#include "basic-block.h"
++#include "insn-config.h"
++#include "function.h"
++#include "expr.h"
++#include "insn-attr.h"
++#include "recog.h"
++#include "toplev.h"
++#include "target.h"
++#include "timevar.h"
++#include "optabs.h"
++#include "insn-codes.h"
++#include "rtlhooks-def.h"
++#include "output.h"
++#include "params.h"
++#include "timevar.h"
++#include "tree-pass.h"
++#include "cgraph.h"
++#include "df.h"
++#include "vec.h"
++
++/* Feature flags */
++/* Duplicate extensions at each immediate use */
++#define EXTELIM_DUPLICATE_EXTS_AT_USES 0
++/* Dump DF information also in dump */
++#define EXTELIM_DF_DUMP 0
++
++
++/* Typedefs */
++typedef unsigned int insn_flag_t;       /* Insn flags type */
++typedef int extelim_uid_t;      /* UID type */
++DEF_VEC_I (insn_flag_t);        /* Define vector type and allocation type */
++DEF_VEC_ALLOC_I (insn_flag_t, heap);
++
++typedef struct GTY (()) ext_record
++{
++  rtx ext;                      /* The extension insn */
++  VEC (rtx, heap) * ext_uses;   /* List of use records for this extension. For some
++                                   some extensions, we will duplicate the extension
++                                   at these use points. */
++  VEC (rtx, heap) * ext_updates;/* List of rtx that need to be updated if the extension
++                                   is to be eliminated. For example, SUBREG_PROMOTED flags
++                                   on SUBREG uses defined by this extension should
++                                   be reset since the extension is eliminated. The PROMOTED
++                                   flag is no longer valid. */
++} *ext_record_t;
++
++typedef struct regspec_cb_data
++{
++  unsigned int regno;
++  rtx exp;
++} regspec_cb_data_t;
++
++/* Static variables */
++DEF_VEC_P (ext_record_t);
++DEF_VEC_ALLOC_P (ext_record_t, heap);
++VEC (ext_record_t, heap) * extensions;  /* Vector holding all extension records */
++VEC (insn_flag_t, heap) * insn_flags;   /* Vector holding flags for all insns */
++VEC (rtx, heap) * returns;      /* Vector holding return insns for this function */
++
++     static extelim_uid_t max_uid;      /* Max UID insn value for insn_flags allocation */
++     static ext_record_t current_ext_record; /* Current extension record being processed */
++
++/* Statistics */
++     static int num_cand;       /* Number of extensions detected */
++     static int num_cand_ignored;       /* Number of extensions ignored */
++     static int num_cand_transformed;   /* Number of extensions transformed to copy */
++
++/* Basic information about the extension being processed */
++     enum machine_mode ext_to_mode;     /* Mode extended to */
++     enum machine_mode ext_from_mode;   /* Mode extended from */
++     enum rtx_code ext_code;    /* Sign or zero extend */
++
++/* Insn use analysis possible results */
++     enum insn_use_results
++     {
++       EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED,
++       EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED,
++       EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION
++     };
++
++/* Insn def analysis possible results */
++     enum insn_def_results
++     {
++       EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED,
++       EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION,
++       EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION
++     };
++
++/* Insn flags for this pass */
++#define       EXTELIM_NONE           0
++#define       EXTELIM_SEEN           (1<<0)     /* Mark insn as visited during DF traversal */
++#define       EXTELIM_REPLACE_COPY   (1<<1)     /* Mark ext insn as replace with copy */
++#define       EXTELIM_INSERTED       (1<<2)     /* Mark ext insn as algorithmically inserted */
++#define       EXTELIM_INSERTED_FOR   (1<<3)     /* Mark use insn for which ext has been inserted */
++
++
++/* Query the insn flag */
++
++     static bool insn_flag_p (insn_flag_t set_p, extelim_uid_t uid)
++{
++  insn_flag_t flags;
++
++  if (((flags = VEC_index (insn_flag_t, insn_flags, uid)) & set_p) == set_p)
++    return true;
++
++  return false;
++}
++
++/* Set the insn flags */
++
++static void
++insn_flag_set (insn_flag_t flags, extelim_uid_t uid)
++{
++  insn_flag_t set;
++  set = VEC_index (insn_flag_t, insn_flags, uid);
++  set |= flags;
++  VEC_replace (insn_flag_t, insn_flags, uid, set);
++}
++
++/* Clear insn flags */
++
++static void
++insn_flag_clear (insn_flag_t flags, extelim_uid_t uid)
++{
++  insn_flag_t clear;
++  clear = VEC_index (insn_flag_t, insn_flags, uid);
++  clear &= ~flags;
++  VEC_replace (insn_flag_t, insn_flags, uid, clear);
++}
++
++/* Set static variable max_uid to the largest
++   insn uid found in the module plus 1. This will be the
++   size of the vector for insn flags. */
++
++static void
++set_max_uid (void)
++{
++  basic_block bb;
++  rtx insn;
++  extelim_uid_t lmax_uid = 0;
++
++  FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn)
++  {
++    if (INSN_P (insn))
++      {
++        if (INSN_UID (insn) > lmax_uid)
++          lmax_uid = INSN_UID (insn);
++      }
++  }
++  max_uid = lmax_uid + 1;
++}
++
++/* Re-initializes the requested insn flags to their reset state */
++
++static void
++reinit_insn_flags (insn_flag_t flags_to_be_reset)
++{
++  extelim_uid_t i;
++
++  /* Account for new insns */
++  set_max_uid ();
++
++  for (i = 0; i < max_uid; i++)
++    {
++      insn_flag_clear (flags_to_be_reset, i);
++    }
++}
++
++/* Init the vector for insn flags. One
++   vector element per insn is created.
++   The flags are init'd to EXTELIM_NONE. */
++
++static void
++init_flags_vector (void)
++{
++  extelim_uid_t i;
++  /* Get the maximum uid value. We'll use this
++     information to set up a vector of max_uid
++     length. Each element of the vector will hold
++     the pass-specific flags for each insn. */
++  max_uid = 0;
++  set_max_uid ();
++
++  /* Allocate the vector of insn flags */
++  insn_flags = VEC_alloc (insn_flag_t, heap, max_uid);
++
++  /* Initialize the insn flags vector */
++  for (i = 0; i < max_uid; i++)
++    {
++      VEC_quick_insert (insn_flag_t, insn_flags, i, EXTELIM_NONE);
++    }
++}
++
++/* Initialize this pass */
++
++static void
++init_pass (void)
++{
++  /* Init insn flags vector */
++  init_flags_vector ();
++
++  /* This pass requires def-use chain information */
++  df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
++  df_analyze ();
++}
++
++static void
++free_extensions (void)
++{
++  ext_record_t ext_record;
++  unsigned i;
++
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext_record)
++  {
++    if (!VEC_empty (rtx, ext_record->ext_uses))
++      VEC_free (rtx, heap, ext_record->ext_uses);
++
++    if (!VEC_empty (rtx, ext_record->ext_updates))
++      VEC_free (rtx, heap, ext_record->ext_updates);
++  }
++  VEC_free (ext_record_t, heap, extensions);
++}
++
++/* Clean up this pass */
++
++static void
++finish_pass (void)
++{
++  free_extensions ();
++  VEC_free (insn_flag_t, heap, insn_flags);
++  VEC_free (rtx, heap, returns);
++}
++
++static void
++update_uid_vectors (extelim_uid_t uid)
++{
++  VEC_safe_grow_cleared (insn_flag_t, heap, insn_flags, uid + 1);
++}
++
++/* Emit a insn before a given insn, update vector lengths
++   of those vectors that are indexed by uid. Return uid
++   of the inserted insn. */
++
++static extelim_uid_t
++extelim_emit_before (rtx new_insn, rtx before_insn)
++{
++  rtx seq;
++  extelim_uid_t new_uid;
++
++  start_sequence ();
++  emit_insn (new_insn);
++  seq = get_insns ();
++  end_sequence ();
++  new_insn = emit_insn_before (seq, before_insn);
++
++  /* Expand the flags vector to hold the new insn and set the
++     inserted flag on the insn. */
++  new_uid = INSN_UID (new_insn);
++  update_uid_vectors (new_uid);
++  return new_uid;
++}
++
++/* Utility function to find the REG exp 
++   given an rtx */
++
++static rtx
++register_exp (rtx exp)
++{
++  if (REG_P (exp))
++    {
++      return exp;
++    }
++  else if (GET_CODE (exp) == SUBREG)
++    {
++      return SUBREG_REG (exp);
++    }
++  else
++    return NULL;
++}
++
++/* Check whether this is a sign extension.  */
++
++static bool
++extension_p (rtx insn, rtx * dest, rtx * inner, int *preserved_size)
++{
++  rtx src, op0;
++
++  /* Detect set of reg.  */
++  if (GET_CODE (PATTERN (insn)) != SET)
++    return false;
++
++  src = SET_SRC (PATTERN (insn));
++  *dest = SET_DEST (PATTERN (insn));
++
++  if (!REG_P (*dest))
++    return false;
++
++  if (GET_CODE (src) == SIGN_EXTEND || GET_CODE (src) == ZERO_EXTEND)
++    {
++      op0 = XEXP (src, 0);
++
++      /* Determine amount of least significant bits preserved by operation.  */
++      if (GET_CODE (src) == AND)
++        *preserved_size = ctz_hwi (~UINTVAL (XEXP (src, 1)));
++      else
++        *preserved_size = GET_MODE_BITSIZE (GET_MODE (op0));
++
++      if (GET_CODE (op0) == SUBREG)
++        {
++          if (subreg_lsb (op0) != 0)
++            return false;
++
++          *inner = SUBREG_REG (op0);
++          return true;
++        }
++      else if (REG_P (op0))
++        {
++          *inner = op0;
++          return true;
++        }
++    }
++
++  return false;
++}
++
++/* Return true if this is the last use of a
++   register, false otherwise.  */
++
++static bool
++reg_is_dead_p (rtx insn, rtx reg_expr)
++{
++  rtx link;
++  gcc_assert (REG_P (reg_expr));
++
++  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
++    {
++      if (REG_NOTE_KIND (link) == REG_DEAD && REG_P (XEXP (link, 0)))
++        {
++          if (REGNO (XEXP (link, 0)) == REGNO (reg_expr))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Return true if we don't want to place this
++   extension in the candidate extensions list because of the
++   previous insn. Return false otherwise. */
++
++static bool
++ignore_extension_prev_p (rtx ext_insn, rtx prev_insn)
++{
++  rtx prev_dest, prev_src, prev = PATTERN (prev_insn);
++  rtx ext_src, ext = PATTERN (ext_insn);
++
++  /* It's OK to allow extension with no accompanying prev real insn */
++  if (!NONDEBUG_INSN_P (prev_insn) || NOTE_P (prev_insn))
++    return false;
++
++  if (GET_CODE (prev) != SET)
++    return false;
++
++  if (GET_CODE (ext) != SET)
++    return false;
++
++  prev_dest = SET_DEST (prev);
++  prev_src = SET_SRC (prev);
++
++  /* Source register of sign extension */
++  ext_src = XEXP (SET_SRC (ext), 0);
++
++  /* Check previous insns */
++
++  /* Previous insn is a load whose dest is the
++     extension's source  and the dest reg is
++     dead */
++  if (MEM_P (prev_src) && (prev_dest = register_exp (prev_dest)))
++    {
++      if ((ext_src = register_exp (ext_src)))
++        {
++          if ((REGNO (prev_dest) == REGNO (ext_src))
++              && reg_is_dead_p (ext_insn, ext_src))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Return true if we don't want to place this
++   extension in the candidate extensions list because of the
++   next insn. Return false otherwise. */
++
++static bool
++ignore_extension_next_p (rtx ext_insn, rtx next_insn)
++{
++  rtx next = PATTERN (next_insn);
++  rtx ext_src, ext = PATTERN (ext_insn);
++
++  if (GET_CODE (ext) != SET)
++    return false;
++
++  /* Check next insns */
++  if (!NONDEBUG_INSN_P (next_insn) || NOTE_P (next_insn))
++    return false;
++
++  if (GET_CODE (next) != SET)
++    return false;
++
++  /* zero-extend followed by left shift by 1 -- this sequence will be
++     detected by the insn selection. */
++  if (GET_CODE (SET_SRC (ext)) == ZERO_EXTEND)
++    {
++      if (GET_CODE (SET_SRC (next)) == ASHIFT
++          && CONST_INT_P (XEXP (SET_SRC (next), 1))
++          && UINTVAL (XEXP (SET_SRC (next), 1)) == 0x1)
++        return true;
++    }
++
++  return false;
++}
++
++/* Find extensions and store them in the extensions vector.  */
++
++static bool
++find_extensions (void)
++{
++  basic_block bb;
++  rtx insn, dest, inner;
++  int preserved_size;
++  ext_record_t extrec;
++
++  /* For all insns, call note_use for each use in insn.  */
++  FOR_EACH_BB (bb)
++  {
++    FOR_BB_INSNS (bb, insn)
++    {
++      if (!NONDEBUG_INSN_P (insn))
++        continue;
++
++      if (!extension_p (insn, &dest, &inner, &preserved_size))
++        {
++          continue;
++        }
++
++      /* We do not consider extensions that follow a load for
++         this target, as the code selector optimizes the sequence
++         to a load with sign extend or load with zero extend. */
++      if (PREV_INSN (insn)
++          && ignore_extension_prev_p (insn, PREV_INSN (insn)))
++        {
++          if (dump_file)
++            fprintf (dump_file, "extension at uid=%d ignored\n",
++                     INSN_UID (insn));
++          num_cand_ignored++;
++          continue;
++        }
++      /* We don't consider certain sequences that are picked up by
++         insn selection. */
++      if (NEXT_INSN (insn)
++          && ignore_extension_next_p (insn, NEXT_INSN (insn)))
++        {
++          if (dump_file)
++            fprintf (dump_file, "extension at uid=%d ignored\n",
++                     INSN_UID (insn));
++          num_cand_ignored++;
++          continue;
++        }
++
++      /* Only looking at sign extensions to DImode, SImode, or HImode  */
++      if (GET_MODE_BITSIZE (SImode) != preserved_size
++          && GET_MODE_BITSIZE (HImode) != preserved_size
++          && GET_MODE_BITSIZE (QImode) != preserved_size)
++        continue;
++
++      extrec = (ext_record_t) xmalloc (sizeof (struct ext_record));
++      extrec->ext = insn;
++      extrec->ext_uses = NULL;
++      extrec->ext_updates = NULL;
++      VEC_safe_push (ext_record_t, heap, extensions, extrec);
++      num_cand++;
++    }
++  }
++
++  if (dump_file)
++    {
++      if (!VEC_empty (ext_record_t, extensions))
++        fprintf (dump_file, "\n");
++      else
++        fprintf (dump_file, "no extensions found.\n");
++    }
++
++  return !VEC_empty (ext_record_t, extensions);
++}
++
++/* Return true if the rtx mode is a supported mode for
++   this optimization, false otherwise. */
++
++static bool
++mode_supported_p (rtx exp)
++{
++  if (GET_MODE (exp) != QImode
++      && GET_MODE (exp) != HImode
++      && GET_MODE (exp) != SImode 
++      && GET_MODE (exp) != DImode
++      && GET_MODE (exp) != CCmode
++      && GET_MODE (exp) != CCUNSmode)
++    return false;
++
++  return true;
++}
++
++/* Return true if the rtx is a function return expr, false otherwise */
++
++static bool
++return_val_p (rtx dest)
++{
++  if ((REG_P (dest) || GET_CODE (dest) == PARALLEL) &&
++      REG_FUNCTION_VALUE_P (dest))
++    {
++      return true;
++    }
++  return false;
++}
++
++
++/* A 'for_each_rtx' callback returning 1 if the rtx is a
++   REG or SUBREG rtx. The first matching rtx found stops the 
++   rtx traversal. */
++
++static int
++reg_or_subreg_rtx (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (REG_P (*x))
++    {
++      ldata->exp = *x;
++      return 1;
++    }
++
++  if (GET_CODE (*x) == SUBREG)
++    {
++      ldata->exp = SUBREG_REG (*x);
++      return 1;
++    }
++
++  return 0;
++}
++
++/* A 'for_each_rtx' callback returning 1 if the rtx is a
++   REG or SUBREG rtx whose register number is that passed
++   in the data parameter. Data parameter's rtx value is
++   set to the matching rtx if found. */
++
++static int
++reg_or_subreg_rtx_regno (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (REG_P (*x) && (REGNO (*x) == ldata->regno))
++    {
++      ldata->exp = *x;
++      return 1;
++    }
++  if (GET_CODE (*x) == SUBREG && (REGNO (SUBREG_REG (*x)) == ldata->regno))
++    {
++      ldata->exp = SUBREG_REG (*x);
++      return 1;
++    }
++  return 0;
++}
++
++/* Callback that counts the number of register operands
++   in an expression. Return 0 to allow all rtxs to be
++   traversed. */
++
++static int
++count_reg_operands (rtx * x, void *data)
++{
++  regspec_cb_data_t *ldata = (regspec_cb_data_t *) data;
++
++  if (register_exp (*x) != NULL)
++    {
++      ldata->regno++;
++    }
++  return 0;
++}
++
++/* Count the number of register operands in an expression.
++   We use the regspec_cb_data_t regno field as the number
++   of register operands we found in an expression. */
++
++static int
++num_reg_operands (rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = 0;
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, count_reg_operands, (void *) &data)) == 0)
++    return (data.regno);        /* contains the count */
++  else
++    return 0;
++}
++
++/* Find the SUBREG or REG rtx corresponding to regno in the given rtx.
++   Return NULL_RTX if the regno rtx is not found. */
++
++static rtx
++find_regspec_regno (unsigned int regno, rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = regno;
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, reg_or_subreg_rtx_regno, (void *) &data)) != 0)
++    return (data.exp);
++  else
++    return NULL_RTX;
++}
++
++/* Find a REG or SUBREG rtx, starting at expr x.
++   Return NULL_RTX if no REG or SUBREG rtx is found.
++   If found, the rtx returned is a REG (not SUBREG) */
++
++static rtx
++find_regspec (rtx x)
++{
++  int rv;
++  regspec_cb_data_t data;
++  data.regno = -1;              /* not used */
++  data.exp = NULL_RTX;
++
++  if ((rv = for_each_rtx (&x, reg_or_subreg_rtx, (void *) &data)) != 0)
++    return (data.exp);
++  else
++    return NULL_RTX;
++}
++
++/* Return true if the expression defines single register, regno. */
++
++static bool
++expr_defines_regno_p (rtx insn, unsigned int regno)
++{
++  rtx reg;
++  if (GET_CODE (insn) == SET)
++    {
++      reg = SET_DEST (insn);
++      if (find_regspec_regno (regno, reg) != NULL_RTX)
++        return true;
++    }
++  return false;
++}
++
++/* Return true if the insn defines a single register, regno.
++   Return false otherwise */
++
++static bool
++defines_regno_p (rtx insn_insn, unsigned int regno, int indent)
++{
++  extelim_uid_t uid = INSN_UID (insn_insn);
++  df_ref *p_def;
++
++  /* Get the operands defined */
++  p_def = DF_INSN_UID_DEFS (uid);
++
++  if (!p_def)
++    return false;
++
++  if (*(p_def + 1) != NULL)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*suid=%d defines multiple registers\n",
++                 indent, " ", uid);
++      return false;
++    }
++
++  if (DF_REF_REGNO (*p_def) != regno)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*suid=%d defines does not define %d\n",
++                 indent, " ", uid, regno);
++      return false;
++    }
++
++  return true;
++}
++
++/* The operand is already extended and the extension is compatible with
++   the originating extension with respect to type and size.
++   E.g. zero_extend:HI meets and AND r,#0xffff. Another example
++   is LSHIFT:SI left or right and zero_extend:SI, because the 
++   instruction selected is rlwinm and clears the upper 32 bits.
++   Other examples in the code. Return true if a compatible extension
++   is found, false otherwise. */
++
++static bool
++operand_is_extended (rtx dest, rtx srcexp, int indent)
++{
++  /* Output of a CALL is already extended. 
++     To ensure that the return value is not modified by the extend,
++     the extend from mode size must be at least the size of the CALL output. 
++     Example - this is redundant since output of CALL is extended.
++     X:SI = CALL ...
++     Y:DI = sign_extend:DI (X:SI) */
++  if (GET_CODE (srcexp) == CALL
++      && (GET_MODE_BITSIZE (ext_from_mode)) >=
++      GET_MODE_BITSIZE (GET_MODE (dest)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...is extended already (CALL insn output)\n", indent,
++                 " ");
++      return true;
++    }
++
++  /* Output is load immediate or load constant */
++  if (CONST_INT_P (srcexp))
++    {
++      bool is_extended;
++      if (ext_from_mode == QImode && (UINTVAL (srcexp) <= 0xff))
++        is_extended = true;
++      else if (ext_from_mode == HImode && (UINTVAL (srcexp) <= 0xffff))
++        is_extended = true;
++      else if (ext_from_mode == SImode && (UINTVAL (srcexp) <= 0xffffffff))
++        is_extended = true;
++      else
++        is_extended = false;
++
++      if (is_extended)
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s... is extended already (CONST_INT load)\n", indent,
++                     " ");
++          return true;
++        }
++    }
++
++  /* Sign extension of the same type as the originating extension.
++     Here the candidate defines the register used in the originating extension.
++     The originating extension will be replaced by a copy if it is found to be
++     redundant with respect to the candidate extension. 
++     The candidate (this extension dest,src) must write the at least the same bits as the 
++     originating extension in order to be redundant. So, we follow these rules:
++
++     cand_to_mode == machine mode of the destination for this candidate extension
++     cand_from_mode == machine mode of the source for this candidate extension
++     ext_to_mode == machine mode of the originating extension output
++     ext_from_mode == machine mode of the originating extension input
++
++     SIZE(cand_to_mode) >= SIZE(extend_to_mode) && SIZE(cand_from_mode) <= SIZE(extend_from_mode)
++
++     Example 1:
++     Candidate (HI->SI extension)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Originating (SI->DI)
++     DI       SI   HI QI 0
++     |<-------|    |  |  |
++
++     Not redundant, candidate does not cover the original bits:
++     SIZE(cand_to_mode)[SI] !>= SIZE(extend_to_mode)[DI]
++
++     Example 2:
++     Candidate (QI->DI extension)
++     DI       SI   HI QI 0
++     |<-------|----|--|  |
++
++     Originating (HI->SI)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Redundant, candidate covers the original bits:
++     SIZE(cand_to_mode) [DI] >= SIZE(extend_to_mode) [SI]
++     AND
++     SIZE(cand_from_mode) [QI] <= SIZE(extend_from_mode) [HI]
++   */
++  if (GET_CODE (srcexp) == ext_code)
++    {
++      enum machine_mode cand_from_mode = GET_MODE (XEXP (srcexp, 0));
++      enum machine_mode cand_to_mode = GET_MODE (dest);
++      if ((GET_MODE_BITSIZE (cand_to_mode) >= GET_MODE_BITSIZE (ext_to_mode))
++          && (GET_MODE_BITSIZE (cand_from_mode) <=
++              GET_MODE_BITSIZE (ext_from_mode)))
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s...is already extended (redundant extension)\n",
++                     indent, " ");
++          return true;
++        }
++    }
++
++  /* Encountered an insn with the same effect as extension, e.g.
++     AND (regspec) (const_int). E.g. AND (reg:SI) (0x7fff) is equivalent
++     to ZERO_EXTEND:DI (reg:HI) or SIGN_EXTEND:DI (reg:HI). The code selection
++     for AND zero extends the entire register, so we don't have to
++     check that srcexp extends to at least ext_to_mode size. */
++  if ((GET_CODE (srcexp) == AND) && CONST_INT_P (XEXP (srcexp, 1)))
++    {
++      if (ext_from_mode == QImode && (UINTVAL (XEXP (srcexp, 1)) <= 0x7f))
++        return true;
++      else if (ext_from_mode == HImode
++               && (UINTVAL (XEXP (srcexp, 1)) <= 0x7fff))
++        return true;
++      else if (ext_from_mode == SImode
++               && (UINTVAL (XEXP (srcexp, 1)) <= 0x7fffffff))
++        return true;
++    }
++
++  return false;
++}
++
++/* Determine if the operation allows us to continue the propagation. 
++   We kill the propagation for all operations except copy. This
++   ensures that the extended operand that we may find eventually
++   is not modified by insns in the def-use chain. It's harsh,
++   but it's safest eliminate all but the most benign (copy) operations
++   in the propagation chain. */
++
++static bool
++continue_def_propagation (rtx dest, rtx srcexp, rtx src_operand, int indent)
++{
++  /* Only continue if its a copy -- that is, the srcexp is a register expression */
++  if ( register_exp (srcexp) )
++    return true;
++
++  return false;
++}
++
++/* Helper for insn_def_analysis_result.
++   The register operand, src is set here. Recall we
++   can only handle one register operand in the src expression.
++   We one of 3 states:
++   1) Determine the operand is extended, ...DEF_EXTENDED returned.
++   2) Determine the propagation can continue, ...DEF_CONTINUE_RECURSION returned. 
++   3) Otherwise, ...DEF_STOP_RECURSION is returned. */
++static enum insn_def_results
++insn_def_analysis_result_1 (rtx insn, bool treat_as_copy,
++                            unsigned int regno_def ATTRIBUTE_UNUSED,
++                            rtx * src, int indent)
++{
++  rtx dest, srcexp;
++  int num_operands;
++
++  /* Insn has to be an expression we can analyze */
++  if (GET_CODE (insn) != SET)
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*s...is not a SET expression\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++  dest = SET_DEST (insn);
++  srcexp = SET_SRC (insn);
++
++  /* Dest must be a reg, not expression */
++  if (!REG_P (dest))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...dest is not a simple register\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* First check whether the operand is extended already. If so,
++     we can leave immediately successfully. */
++  if (operand_is_extended (dest, srcexp, indent) && !treat_as_copy)
++    return (EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED);
++
++
++  /* Failing to determine that the operand is already extended, 
++     we have to validate that we have register operands to propagate. */
++  num_operands = num_reg_operands (srcexp);
++
++  /* At least one register operand required for propagation. */
++  if (num_operands == 0)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...no register operands in RHS\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* Only one register operand is allowed in the RHS since we can't
++     can't propagate more than one register. */
++  if (num_operands > 1)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...found multiple register operands in RHS\n", indent,
++                 " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* Find the used operand in the src expression */
++  *src = find_regspec (srcexp);
++  if (*src == NULL_RTX || !mode_supported_p (*src))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...src operand reg=%d cannot be found or is unsupported mode\n",
++                 indent, " ", regno_def);
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* This is an extension, but it is previously marked to be transformed to a copy.
++     We just treat it as a copy even though it hasn't been transformed yet. So 
++     continue the propagation. */
++  if (treat_as_copy)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s is treated as a copy (marked for replace)\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (srcexp)));
++      return (EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION);
++    }
++
++  /* Validate that it's ok to continue propagation with this operand. */
++  if (continue_def_propagation (dest, srcexp, *src, indent))
++    return (EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION);
++
++  /* Else we default to halting the search for a redundant extension */
++  return (EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION);
++}
++
++/* Determine if the insn extends it's destination register in
++   a manner such that the original extension is redundant. */
++
++static enum insn_def_results
++insn_def_analysis_result (rtx insn_insn, unsigned int regno_def, rtx * src,
++                          int indent)
++{
++  bool treat_as_copy = false;
++
++  /* Insn must only define one output */
++  if (!defines_regno_p (insn_insn, regno_def, indent))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...defines more than 1 output\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++    }
++
++  /* We want to treat this extension as a copy and continue propagation.
++     Otherwise, it would be detected again as redundant. */
++  if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (insn_insn)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is marked to transform to copy\n", indent,
++                 " ", INSN_UID (insn_insn));
++      treat_as_copy = true;
++    }
++
++  /* Do the analysis */
++  return (insn_def_analysis_result_1
++          (PATTERN (insn_insn), treat_as_copy, regno_def, src, indent));
++}
++
++/* Analyze each of the expressions in a PARALLEL expression. As each of
++   the expressions may yield a different state, select the most conservative
++   state to return. */
++
++static enum insn_def_results
++insn_def_analysis_2 (rtx insn_def, unsigned int regno_def, rtx * src,
++                     int indent)
++{
++  int i;
++  rtx insn = PATTERN (insn_def);
++  enum insn_def_results action;
++  enum insn_def_results return_action =
++    EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION;
++
++  gcc_assert (GET_CODE (insn) == PARALLEL);
++
++  for (i = XVECLEN (insn, 0) - 1; i >= 0; i--)
++    {
++      rtx body = XVECEXP (insn, 0, i);
++      /* Only act on the expressions that define regno_def */
++      if (!expr_defines_regno_p (body, regno_def))
++        continue;
++      /* Determine the next action */
++      action = insn_def_analysis_result_1 (body, false /* treat_as_copy */ ,
++                                           regno_def, src, indent);
++      /* The result of this expression stops the recursion, i.e. no
++         longer reasonable to continue looking at further recursion. */
++      if (action == EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION)
++        return action;
++      /* Only return EXTENDED if there are no other different actions
++         in the series. Otherwise, CONTINUE_RECURSION is returned. */
++      if (action == EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION)
++        return_action = action;
++      else if (return_action ==
++               EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION)
++        return_action = EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION;
++      else
++        return_action = action;
++    }
++  return (return_action);
++}
++
++/* Helper 1 for insn_def_analysis */
++
++static enum insn_def_results
++insn_def_analysis_1 (rtx insn_def, unsigned int regno_def, rtx * src,
++                     int indent)
++{
++  rtx def = PATTERN (insn_def);
++  enum insn_def_results action;
++
++  switch (GET_CODE (def))
++    {
++    case PARALLEL:
++      action = insn_def_analysis_2 (insn_def, regno_def, src, indent);
++      break;
++    default:
++      action = insn_def_analysis_result (insn_def, regno_def, src, indent);
++      break;
++    }
++  return action;
++}
++
++/* We look at the definition of a register that is either the
++   sign or zero extend source register or a definition that that
++   has been propagated to here via analyze_ext_def. The objective
++   is to determine, by looking at the operation and operands, whether
++   the register is sign/zero extended by virtue of the operation and/or
++   operands. If so, the original extension is redundant.
++   The function returns one of 3 possible states after analyzing the
++   insn:
++   1. EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED - we determined that the
++   insn does indeed extend the original source extension register.
++   analyze_ext_def returns FALSE, therefore, ending the recursion
++   and propagation.
++   2. EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION - we determined that 
++   the insn does not meet the criteria to continue the recursive search.
++   Some conditions causing this may be multiple operands defining this
++   register (we only propagate on a single input operand) or the insn
++   defines more than one output or the operation does not allow
++   a previous extension to propagate, e.g. an arithmetic shift on
++   a SI value clears the upper bits using rlwinm. MUL, DIV, MOD
++   stop recursion because the result is longer than the input size,
++   thus impacting the possible previous extension.
++   3. EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION - we found an
++   operation with one register operand and the operation will not
++   affect a previous extension if one exists. ADD, SUB are examples.
++   We continue looking up the chain at the definition of the operand
++   for an extended result. 
++   If we run into a previous extension marked for replacement during
++   recursion, we treat it as a copy (CONTINUE_RECURSION since the
++   extension is preserved by the copy). */
++
++static enum insn_def_results
++insn_def_analysis (rtx insn_def, unsigned int regno_def, rtx * src,
++                   int indent)
++{
++  return (insn_def_analysis_1 (insn_def, regno_def, src, indent));
++}
++
++/* Analyze the insn defining the source of the sign extension.
++   If it can be determined that the definition is already
++   sign extended, return false. Otherwise, return true if 
++   extension is needed. */
++
++static bool
++analyze_ext_def (rtx insn_def, unsigned int regno_def, int indent)
++{
++  extelim_uid_t uid;
++  rtx def = PATTERN (insn_def);
++  rtx src;
++  df_ref df_def, *p_use;
++  bool ext_needed, indent_once;
++  struct df_link *link;
++  enum insn_def_results analysis_result;
++
++  gcc_assert (def != NULL);
++
++  uid = INSN_UID (insn_def);
++
++  /* If we seen the originating extension again, return false (ext not needed) */
++  if (current_ext_record->ext == insn_def)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef at uid=%d is original extension\n", indent, " ", uid);
++      return false;
++    }
++
++  /* The recursion has to definitively end with an operand being
++     extended (and compatible with the originating extension). If
++     we see the insn again, this could return a faulty positive (false),
++     so we return true here instead of false. See pr43017 (-funroll-loops)
++     as an example. */
++  if (insn_flag_p (EXTELIM_SEEN, uid))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef at uid=%d is visited already\n", indent, " ", uid);
++      return true;
++    }
++
++  /* Mark this insn as seen */
++  insn_flag_set (EXTELIM_SEEN, uid);
++
++  analysis_result = insn_def_analysis (insn_def, regno_def, &src, indent);
++  switch (analysis_result)
++    {
++      /* We know conclusively that the register defined in this expression
++         is already extended. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_EXTENDED:
++      if (dump_file)
++        fprintf (dump_file, "%*sdef at uid=%d is extended\n", indent, " ",
++                 uid);
++      return false;
++      break;
++      /* We know conclusively that we cannot continue the recursion. Perhaps 
++         the expression defines multiple registers, etc. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_STOP_RECURSION:
++      if (dump_file)
++        fprintf (dump_file, "%*sdef at uid=%d cannot be propagated\n", indent,
++                 " ", uid);
++      return true;
++      break;
++      /* Continue to look at the operands of this expression. They may be extended
++         already. */
++    case EXTELIM_ANALYSIS_RESULT_DEF_CONTINUE_RECURSION:
++      break;
++    default:
++      gcc_unreachable ();
++    }
++
++  /* This is the operand for which we want to find definitions. There should
++     only be one operand as we have previously checked for operations with only
++     one register operand as the src previously. */
++  p_use = DF_INSN_UID_USES (uid);
++  gcc_assert (p_use != NULL);
++
++  /* Make sure that this use is the one returned in src. Otherwise we simply
++     stop the propagation. Note the DF_INSN_UID_USES works at the insn
++     level, so a PARALLEL pattern may return many uses, hence the need
++     to validate the correct use here. */
++  if ((*p_use == NULL) || (DF_REF_REGNO (*p_use) != REGNO (src)))
++    return true;
++
++  ext_needed = true;
++  indent_once = true;
++  for (link = DF_REF_CHAIN (*p_use); link; link = link->next)
++    {
++      rtx insn_def;
++      df_def = link->ref;
++      if (!df_def)
++        continue;
++      /* Link must be to a definition of the use */
++      if (!DF_REF_REG_DEF_P (df_def))
++        continue;
++      /* Ignore ARTIFICIAL defs */
++      if (DF_REF_IS_ARTIFICIAL (df_def))
++        continue;
++      insn_def = DF_REF_INSN (df_def);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_def))
++        continue;
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdef of reg=%d at uid=%d\n", indent, " ",
++                 DF_REF_REGNO (df_def), INSN_UID (insn_def));
++      /* Set indent for dump formatting */
++      if (indent_once)
++        {
++          ++indent;
++          indent_once = false;
++        }
++      ext_needed = analyze_ext_def (insn_def, DF_REF_REGNO (df_def), indent);
++      if (ext_needed)
++        break;
++    }
++
++  if (dump_file)
++    fprintf (dump_file,
++             "%*sext %s needed\n", indent, " ", ext_needed ? "" : "not");
++
++  return ext_needed;
++}
++
++/* Determine whether the expression needs to be saved for this extension.
++   The expression will be updated in some way if the extension is ultimately
++   eliminated. */
++
++static bool
++exp_needs_update_p (rtx exp)
++{
++  if (GET_CODE (exp) == SUBREG
++      && (SUBREG_PROMOTED_VAR_P (exp)))
++    {
++      return true;
++    }
++  return false;
++}
++
++/* Some expressions may need to be updated if the originating extension
++   is eliminated. For example, SUBREG_PROMOTED flags on uses are no longer
++   valid if the extension is eliminated. Save the expression here. */
++
++static void
++save_ext_update (ext_record_t extrec, rtx exp)
++{
++  /* Save this expression to be updated if the extension is eliminated. */
++  VEC_safe_push (rtx, heap, extrec->ext_updates, exp);
++}
++
++/* Check a compare operation to determine whether the operands
++   of the compare use the upper bits of the extension. Return
++   true if the upper bits are not relevant in the compare, false
++   otherwise. */
++
++static bool
++check_compare (rtx dest, rtx src)
++{
++  /* Detect 
++     (set (reg:CC r0) (compare:CC (REGSPEC) (REGSPEC)))
++     or
++     (set (reg:CC r0) (compare:CC (REGSPEC) (CONST)))
++     where REGSPEC is (reg:mm r) or (subreg:mm (reg:MM r) n) 
++     CONST is a constant integer.
++     The mode size of compare ops must be less than the
++     mode of the original extension for the upper bits to
++     be irrelevant. 
++     An exception is made for mode sizes less than a word size.
++     For our targets, there is no 'cmph' insn, so we bail out 
++     if we see a comparison of sizes less than a word (SI). */
++  if (REG_P (dest)
++      && (GET_MODE (dest) == CCmode || GET_MODE (dest) == CCUNSmode)
++      && GET_CODE (src) == COMPARE
++      && (GET_MODE (src) == CCmode || GET_MODE (src) == CCUNSmode))
++    {
++      rtx compare_op0 = XEXP (src, 0);
++      rtx compare_op1 = XEXP (src, 1);
++
++      /* Check the first operand, op0, size. */
++      if ((REG_P (compare_op0) || GET_CODE (compare_op0) == SUBREG)
++          && (GET_MODE_BITSIZE (GET_MODE (compare_op0)) <=
++              GET_MODE_BITSIZE (ext_from_mode)))
++        {
++          /* Half word compares and smaller are performed as word compares, so upper bits are used. */
++          if (GET_MODE_BITSIZE (GET_MODE (compare_op0)) < SImode)
++            return false;
++
++          /* Now check the other operand, op1. */
++          if ((REG_P (compare_op1) || GET_CODE (compare_op1) == SUBREG)
++              && (GET_MODE_BITSIZE (GET_MODE (compare_op1)) <=
++                  GET_MODE_BITSIZE (ext_from_mode)))
++            return true;
++
++          /* Compare to constant, we know op0 already meets size constraints. */
++          if (CONST_INT_P (compare_op1))
++            return true;
++        }
++    }
++  return false;
++}
++
++/* Determine condition a, whether the upper bits are relevant to the operation.
++   Return false if we prove the upper bits are not relevant in the operation,
++   true otherwise. */
++
++static bool
++operation_uses_upper_bits (rtx dest, rtx src, unsigned int regno_use,
++                           int indent ATTRIBUTE_UNUSED)
++{
++  rtx regspec_src = find_regspec_regno (regno_use, src);
++
++  if (check_compare (dest, src))
++    return false;
++
++  /* Store of regno to mem, size stored is the same or smaller than the extended from size */
++  if (MEM_P (dest)
++      && (GET_MODE_BITSIZE (GET_MODE (dest)) <=
++          GET_MODE_BITSIZE (ext_from_mode))
++      /* Ensure the used register is being stored and not used in another capacity, say, as a pointer. */
++      && (regspec_src))
++    return false;
++
++  /* Operation operand size is the same or smaller than the extended from size */
++  if (regspec_src)
++    {
++      if (GET_MODE_BITSIZE (GET_MODE (regspec_src)) <=
++          GET_MODE_BITSIZE (ext_from_mode))
++        return false;
++    }
++
++  /* Default to the safest result */
++  return true;
++}
++
++/* Determine if this insn also extends to the size or greater of the original extension.
++   Sign extend can propagate to zero extend and vice-versa because the upper bits
++   haven't affected the low bits up to now throughout the propagation. */
++
++static bool
++operation_extends_to_upper_bits_size (rtx src, int indent ATTRIBUTE_UNUSED)
++{
++  /* Sign extension of the same type as the originating extension.
++     Here the candidate uses the register defined by the originating extension.
++     If the candidate is found to be redundant, the originating extension is
++     replaced with a copy.
++
++     We follow these rules:
++
++     dest_mode == machine mode of the destination for this candidate extension
++     (it's the same mode as the src, e,g, reg:DI = sign_extend:DI ...)
++     src_mode == machine mode of the source for this candidate extension
++     (the mode of the used register, SI in this case, e.g. reg:DI = sign_extend:DI (subreg:SI (reg:DI))
++     ext_to_mode == machine mode of the originating extension output
++     ext_from_mode == machine mode of the originating extension input
++
++     SIZE(cand_from_mode) >= SIZE(extend_from_mode) && SIZE(cand_to_mode) <= SIZE(extend_to_mode)  
++
++     Example 1:
++     Originating (SI->DI)
++     DI       SI   HI QI 0
++     |<-------|    |  |  |
++
++     Candidate (HI->SI extension)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Not redundant, candidate does not cover the original bits:
++     SIZE(dest_mode)[SI] !<= SIZE(extend_to_mode)[DI]
++
++     Example 2:
++     Originating (HI->SI)
++     DI       SI   HI QI 0
++     |        |<---|  |  |
++
++     Candidate (QI->DI extension)
++     DI       SI   HI QI 0
++     |<-------|----|--|  |
++
++     Redundant, candidate covers the original bits:
++     SIZE(cand_to_mode) [DI] >= SIZE(extend_to_mode) [SI]
++     AND
++     SIZE(cand_from_mode) [QI] <= SIZE(extend_from_mode) [HI] */
++  if (GET_CODE (src) == ext_code)
++    {
++      /* Extend is redundant if we don't overwrite the source of the
++         previous extension and extends to at least the extent of the original. */
++      enum machine_mode cand_from_mode = GET_MODE (XEXP (src, 0));
++      enum machine_mode cand_to_mode = GET_MODE (src);
++      if (GET_MODE_BITSIZE (cand_from_mode) >=
++          GET_MODE_BITSIZE (ext_from_mode)
++          && (GET_MODE_BITSIZE (cand_to_mode) <=
++              GET_MODE_BITSIZE (ext_to_mode)))
++        return true;
++    }
++
++  /* Encountered an insn with the same effect as extension, e.g.
++     AND (regspec) (const_int). E.g. AND (reg:SI) (0xffff) is equivalent
++     to ZERO_EXTEND:DI (reg:HI) */
++  if ((GET_CODE (src) == AND) && CONST_INT_P (XEXP (src, 1)))
++    {
++      /* Extends to at least the original extension size */
++      if (GET_MODE_BITSIZE (GET_MODE (src)) >= GET_MODE_BITSIZE (ext_to_mode))
++        {
++          if (ext_from_mode == QImode && (UINTVAL (XEXP (src, 1)) <= 0xff))
++            return true;
++          else if (ext_from_mode == HImode
++                   && (UINTVAL (XEXP (src, 1)) <= 0xffff))
++            return true;
++          else if (ext_from_mode == SImode
++                   && (UINTVAL (XEXP (src, 1)) <= 0xffffffff))
++            return true;
++          else
++            return false;
++        }
++    }
++  return false;
++}
++
++/* Determine whether the operation's upper bits subtly or overtly affects the low bits. */
++
++static bool
++operation_implicitly_affects_lowbits (rtx dest, rtx src,
++                                      unsigned int regno_use, int indent)
++{
++  rtx regspec = find_regspec_regno (regno_use, src);
++
++  /* First, a return expression must be assumed to affect the lowbits as the return value
++     must be extended properly. */
++  if (return_val_p (dest))
++    {
++      if (dump_file)
++        {
++          fprintf (dump_file, "%*sDestination is a return value\n", indent,
++                   " ");
++        }
++      return true;
++    }
++
++  /* These operations implicitly affect the lowbits, except where noted. */
++  switch (GET_CODE (src))
++    {
++    case MULT:
++    case DIV:
++    case UDIV:
++    case UMOD:
++    case MOD:
++      /* Normally, yes, these operations return true (affects low bits). But when the 
++         the operand size is less than or equal to the "low bits" size AND the operation size
++         is the same as the operand size, the operation is performed only on the "low bits"
++         and the "upper bits" do not contribute to the output. */
++      if (regspec
++          && (GET_MODE_BITSIZE (GET_MODE (regspec)) <=
++              GET_MODE_BITSIZE (ext_from_mode))
++          && GET_MODE_BITSIZE (GET_MODE (src)) ==
++          GET_MODE_BITSIZE (GET_MODE (regspec)))
++        return false;
++      return true;
++
++      break;
++      /* Shift rights normally affect the low bits. There can be special cases where this
++         is not true, such a the operand size is smaller than the extended from size, e.g.
++         set (reg:SI Y) (zero_extend:SI (subreg:HI (reg:SI X)))
++         set (reg:QI Z) (lshiftrt (subreg:QI (reg:SI Y))
++         The shift of the QI data is not affected by the extension of HI data unless the
++         shift is large enough to encroach into the QI bits. This seems rare and I do not
++         check for it. */
++    case LSHIFTRT:
++    case ASHIFTRT:
++      return true;
++      break;
++      /* Other operations are known not to impact the low bits */
++    default:
++      return false;
++    }
++
++}
++
++/* The operation directly defines a propagatable output. Several
++   operations do not define such output. E.g. MEM (loads) do not
++   define an output based on the operation. USE is another example,
++   as it isn't a real operation. */
++
++static bool
++operation_directly_defines_an_output (rtx dest, rtx src,
++                                      int indent ATTRIBUTE_UNUSED)
++{
++  switch (GET_CODE (src))
++    {
++    case REG:
++    case SUBREG:
++    case PLUS:
++    case MINUS:
++    case NEG:
++    case MULT:
++    case DIV:
++    case MOD:
++    case UDIV:
++    case UMOD:
++    case AND:
++    case IOR:
++    case XOR:
++    case NOT:
++    case ASHIFT:
++    case ROTATE:
++    case ASHIFTRT:
++    case LSHIFTRT:
++    case ROTATERT:
++    case SIGN_EXTEND:
++    case ZERO_EXTEND:
++    case TRUNCATE:
++      return true;
++      break;
++      /* OK to propagate if the output of IF_THEN_ELSE is a register */
++    case IF_THEN_ELSE:
++      if (REG_P (dest))
++        return true;
++      break;
++      /* All others are assumed not to generate a normal output */
++    default:
++      break;
++    }
++  return false;
++}
++
++/* Helper for insn_use_analysis_result */
++
++static enum insn_use_results
++insn_use_analysis_result_1 (rtx insn, bool treat_as_copy,
++                            unsigned int regno_use, rtx * dest, int indent)
++{
++  rtx src;
++  bool cond_a, cond_b, cond_c, cond_d;
++
++  if (GET_CODE (insn) != SET)
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  *dest = SET_DEST (insn);
++  src = SET_SRC (insn);
++
++  /* Bail out on inline assembly also */
++  if (GET_CODE (src) == ASM_INPUT || GET_CODE (src) == ASM_OPERANDS)
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  /* Bail out on non supported types */
++  if (!mode_supported_p (*dest))
++    return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++
++  /* First, we determine cond_c (is a redundant extension) because it gates the
++     other conditions. */
++  if ((cond_c = operation_extends_to_upper_bits_size (src, indent)))
++    {
++      if (treat_as_copy)
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*s...%s is treated as a copy (marked for replace)\n",
++                     indent, " ", GET_RTX_NAME (GET_CODE (src)));
++          return EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++        }
++
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s is a redundant extension\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++    }
++
++  cond_a = operation_uses_upper_bits (*dest, src, regno_use, indent);
++
++  cond_b =
++    operation_implicitly_affects_lowbits (*dest, src, regno_use, indent);
++
++  cond_d = operation_directly_defines_an_output (*dest, src, indent);
++
++  /* Operation implicitly affects low bits */
++  if (cond_b)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s implicitly affects low bits\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  /* Neither cond_a nor cond_b affects the low bits */
++  if (!cond_a)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s does not use upper bits\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++    }
++
++  /* To continue recursion, the operation must define a 
++     meaningful output. */
++  if (!cond_d)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*s...%s does not define a propagatable output\n",
++                 indent, " ", GET_RTX_NAME (GET_CODE (src)));
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  /* This leaves cond_a, meaning we need to continue down the chain
++     to see if the low bits are ultimately affected by the upper bits. */
++  return EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++}
++
++/* Determine the action based on the insn conditions. The truth table is
++   simplified using if statements. Insns previously marked for replace by copy
++   are identified, these will be essentially be treated as copies now and not
++   be detected as redundant for this use. */
++static enum insn_use_results
++insn_use_analysis_result (rtx insn_insn, unsigned int regno_use, rtx * dest,
++                          int indent)
++{
++  bool treat_as_copy = false;
++  if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (insn_insn)))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is marked to transform to copy\n", indent,
++                 " ", INSN_UID (insn_insn));
++      treat_as_copy = true;
++    }
++  return (insn_use_analysis_result_1
++          (PATTERN (insn_insn), treat_as_copy, regno_use, dest, indent));
++}
++
++/* We have to analyze each expression action in a PARALLEL series.
++   Return the appropriate action for a series of expressions in a PARALLEL insn. 
++   LOWBITS_AFFECTED stops the loop. This leaves only CONTINUE_RECURSION
++   or LOWBITS_NOT_AFFECTED. LOWBITS_NOT_AFFECTED is only returned
++   if there are no other different actions in the series (no CONTINUE_RECURSION
++   states). For each CONTINUE_RECURSION action we encounter, the destination
++   registers must be identical since we can only propagate one use (one definition
++   of dest) should CONTINUE_RECURSION be returned. */
++
++static enum insn_use_results
++analyze_action (enum insn_use_results cur_action,
++                enum insn_use_results prev_action,
++                rtx * dest, rtx * prev_dest)
++{
++  enum insn_use_results return_action;
++
++  if (cur_action == EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED)
++    return cur_action;
++
++  if (cur_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    return_action = cur_action;
++  else if (prev_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    return_action = EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION;
++  else
++    return_action = cur_action;
++
++  if (return_action == EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION)
++    {
++      if (*prev_dest)
++        {
++          /* All bets off if the series defines multiple outputs */
++          if (*prev_dest != *dest)
++            return_action = EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++        }
++    }
++  /* Set prev_dest */
++  *prev_dest = *dest;
++
++  return return_action;
++}
++
++/* Helper 2 for insn_use_analysis. Return the appropriate action
++   for a series of expressions in a PARALLEL insn. */
++
++static enum insn_use_results
++insn_use_analysis_2 (rtx insn_use, unsigned int regno_use, rtx * dest,
++                     int indent)
++{
++  int i;
++  rtx insn = PATTERN (insn_use);
++  rtx prev_dest = NULL_RTX;
++  enum insn_use_results action;
++  enum insn_use_results return_action =
++    EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED;
++
++  gcc_assert (GET_CODE (insn) == PARALLEL);
++
++  /* We make a quick decision about call_insns here. Since the use reached
++     a call, we assume it's an outgoing parameter and thus must be extended
++     as per the ABI. */
++  if (CALL_P (insn_use))
++    {
++      if (dump_file)
++        fprintf (dump_file, "%*s...is a call parameter\n", indent, " ");
++      return EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED;
++    }
++
++  for (i = XVECLEN (insn, 0) - 1; i >= 0; i--)
++    {
++      rtx body = XVECEXP (insn, 0, i);
++      /* Only act on the expressions containing a use of regno_use. */
++      if (regno_use_in (regno_use, body) == NULL_RTX)
++        continue;
++
++      /* Determine the next action */
++      action = insn_use_analysis_result_1 (body, false /* treat as copy */ ,
++                                           regno_use, dest, indent);
++
++      /* Here we make a decision on the return action based on the previous actions.
++         This is done to accomodate different actions from different elements in the
++         PARALLEL series of expressions. */
++      return_action =
++        analyze_action (action, return_action, dest, &prev_dest);
++
++      /* The result of this expression stops the recursion, i.e.  "low bits"
++         are affected by the operation. */
++      if (return_action == EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED)
++        break;
++    }
++  return (return_action);
++}
++
++/* Helper 1 for insn_use_analysis */
++
++static enum insn_use_results
++insn_use_analysis_1 (rtx insn_use, unsigned int regno_use, rtx * dest,
++                     int indent)
++{
++  rtx use = PATTERN (insn_use);
++  enum insn_use_results action;
++
++  switch (GET_CODE (use))
++    {
++    case PARALLEL:
++      action = insn_use_analysis_2 (insn_use, regno_use, dest, indent);
++      break;
++    default:
++      action = insn_use_analysis_result (insn_use, regno_use, dest, indent);
++      break;
++    }
++
++  return action;
++}
++
++/* Analyze the insn and determine the next course of action in the
++   use analysis loop.
++   There are several conditions to consider:
++
++   1. The "extended from" mode. This is an enum machine_mode value
++   that determines what is the size extended. It is derived from the
++   source of the original extension. It is the "low bits" value.
++   It is these range of bits that cannot be affected by the operation's
++   "upper bits" in order to determine whether the extend is useful or not.
++   Examples: 
++   (1) set (reg:DI Y (zero_extend:DI (subreg:QI (reg:DI X))) ==> low bits = QI
++   (2) set (reg:SI Y (sign_extend:SI (reg:HI X) ==> low bits = HI
++
++   2. The "extend to" mode. This is the size extended to in the original
++   extension. It is the "upper bits" value. The entire extended to size may 
++   be used subsequently or it may be subreg'd to a smaller or larger sizes 
++   later in the propagation.
++   For example (1) above, "upper bits" is DI, and (2) "upper bits" is SI.
++
++   3. The code, ext_code, of the original extension, either ZERO_EXTEND or SIGN_EXTEND.
++
++   4. Operation code. For an insn, the actual operation code corresponding to
++   a machine instruction. For certain codes, we know that the "low bits" of the
++   result are modified by the insn because of the values in the "upper bits" of the
++   input operand. We say the operation implicitly uses the "upper bits" to modify the
++   "low bits". For other codes, the "upper bits" do not affect the output result
++   in the "low bits". 
++
++   If the operation does implicitly use the "upper bits" to modify
++   the "low bits", it is instantly a deal killer. The original extension must be 
++   preserved. 
++
++   If the operation does not implicitly use "upper bits" to modify the "low bits",
++   then the action to take depends on the operation operand size relative to 
++   "low bits" size.
++
++   We only want to deal with codes that map to real instructions,
++   like ADD, SUB, MULT, LSHIFTRT, etc. Codes such as PARALLEL, etc. do not map to
++   instruction and must be dissected to extract the real instructions.
++
++   Furthermode, for recursion to continue, the operation and operand must define
++   an output related to the input operand (the use register). This doesn't happen
++   for operations such as "mem" where the output is indirectly related to the
++   input operand. 
++
++   5. Operation mode. The operation mode of the operation code. This sometimes impacts
++   the effect of the operation. For example MULT:SI and MULT:DI map to two different
++   machine instructions and both may have operands of SI mode. However, the MULT:SI 
++   results will be oblivious to the upper bits of the DI register whereas, SI part of
++   MULT:DI result will be affected by the upper bits of the DI register.
++
++   Several conditions determine the action to take based on the various inputs.
++
++   The truth table inputs are A, B, and C. The truth table output is the action to take. 
++
++   A. True if the used operand mode size is greater than the extended_from ("low bits") mode size.
++   B. True if the operation implicitly uses upper bits to define the low bits  
++   C. True if the operation also extends the output to upper bits size
++   D. True if the operation and input operand directly define an output operand.
++
++   Condition A. means the upper bits are in use in the operation. The extend _may_ be needed, 
++   all things being equal, so the action would be to continue recursion to the use of the
++   defined operand, i.e. return CONTINUE_RECURSION.
++
++   Condition B. means the "low bits" are modified by the extended portion of the register
++   by virtue of the operation. For example, logical shift right, where the extended
++   portion is shifted into the "low bits". Another example, multiply, where the machine
++   uses the extended portion implicitly to calculate the results, some of which are 
++   reflected in the "low bits" of the result. The extension is definitely needed in these 
++   cases for this use, so return LOWBITS_AFFECTED. Recursion is stopped and analysis of 
++   this extension is halted.
++
++   Condition C. means the operation and it's operands perform the same extension as
++   the originating extension. The operation must extend to the same size _or higher_ of
++   the original extension. In this case, the original extension is truly redundant and
++   we return LOWBITS_NOT_AFFECTED for this use.
++
++   Condtion D. means the operation and operand directly define an output operand. For most
++   arithmetic and unary operations this is true. For mem and other internal operations,
++   e.g. USE, this is false.
++
++      Condition                      Action                 Comments
++    ==================================================================
++    A.     B.     C.     D.
++    ------------------------------------------------------------------
++    X      X      true   true     LOW_BITS_NOT_AFFECTED  extend is redundant
++    ------------------------------------------------------------------
++    false  false  false  X        LOW_BITS_NOT_AFFECTED  used operand is smaller than "low bits"
++    ------------------------------------------------------------------
++    false  true   false  true     LOW_BITS_AFFECTED      "low bits" modified implicitly by operation
++    ------------------------------------------------------------------
++    true   false  false  true     CONTINUE_RECURSION     "low bits" _may_ be impacted by next uses
++    ------------------------------------------------------------------
++    true   true   false  true     LOW_BITS_AFFECTED      "low bits" modified implicitly by operation */
++
++static enum insn_use_results
++insn_use_analysis (rtx insn_use, unsigned int regno_use, rtx * dest,
++                   int indent)
++{
++  return (insn_use_analysis_1 (insn_use, regno_use, dest, indent));
++}
++
++/* Analyze the operation and operands of this use of a sign extension
++   target register. If the target register's upper bits do not
++   affect the result of the operation, then the sign extension is
++   useless. Returns true if the extension is needed, false 
++   otherwise. */
++
++static bool
++analyze_ext_use (rtx insn_use, unsigned int regno_use, int indent)
++{
++  bool ext_needed, indent_once;
++  unsigned int dest_target_regno;
++  extelim_uid_t uid;
++  rtx use = PATTERN (insn_use), dest;
++  df_ref df_use, *p_def;
++  struct df_link *link;
++  enum insn_use_results analysis_result;
++
++  gcc_assert (use != NULL);
++
++  uid = INSN_UID (insn_use);
++
++  if (insn_flag_p (EXTELIM_SEEN, uid))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d is visited already\n", indent, " ", uid);
++      return false;
++    }
++
++  /* Mark this insn as seen */
++  insn_flag_set (EXTELIM_SEEN, uid);
++
++  analysis_result = insn_use_analysis (insn_use, regno_use, &dest, indent);
++  switch (analysis_result)
++    {
++      /* We know conclusively that the "upper bits" of the extended
++         entity do not impact the "low bits" of the output of the operation. */
++    case EXTELIM_ANALYSIS_RESULT_LOWBITS_NOT_AFFECTED:
++      if (dump_file)
++        fprintf (dump_file, "%*suse at uid=%d is not affected\n", indent, " ",
++                 uid);
++      return false;
++      break;
++      /* We know conclusively that the "upper bits" of the extended
++         entity _do_ impact the "low bits" of the output of the operation. */
++    case EXTELIM_ANALYSIS_RESULT_LOWBITS_AFFECTED:
++      if (dump_file)
++        fprintf (dump_file, "%*suse at uid=%d is affected\n", indent, " ",
++                 uid);
++      return true;
++      break;
++      /* Continue to look at the uses of the result to determine the impact
++         of the "upper bits" */
++    case EXTELIM_ANALYSIS_RESULT_CONTINUE_RECURSION:
++      break;
++    default:
++      gcc_unreachable ();
++    }
++
++  /* We reach here because the action taken is CONTINUE_RECURSION.
++     Continue to look at the uses of the destination register recursively. 
++     If the propagation ultimately ends where the upper bits are not significant 
++     to the final output, then the extension can be removed. */
++  if (!REG_P (dest))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*sdest of uid=%d (SET) is not a register\n", indent, " ",
++                 uid);
++      return true;
++    }
++
++  dest_target_regno = REGNO (dest);
++
++  /* What this insn defines */
++  p_def = DF_INSN_UID_DEFS (uid);
++
++  /* Ref must be valid and there must be only one definition and it must be the
++     destination */
++  if ((*p_def == NULL) || (*(p_def + 1) != NULL))
++    return true;
++
++  gcc_assert (DF_REF_REGNO (*p_def) == dest_target_regno);
++
++  ext_needed = true;
++  indent_once = true;
++  for (link = DF_REF_CHAIN (*p_def); link; link = link->next)
++    {
++      rtx insn_use, use_exp;
++      df_use = link->ref;
++      if (!df_use)
++        continue;
++      /* Link must be a USE of the DEF */
++      if (!DF_REF_REG_USE_P (df_use))
++        continue;
++      /* Ignore ARTIFICIAL USES */
++      if (DF_REF_IS_ARTIFICIAL (df_use))
++        continue;
++      insn_use = DF_REF_INSN (df_use);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_use))
++        continue;
++      use_exp = DF_REF_REG (df_use);
++
++      if (exp_needs_update_p (use_exp))
++        {
++          if (dump_file)
++            fprintf (dump_file,
++                     "%*ssaved reg=%d expression for update\n", indent, " ", DF_REF_REGNO (df_use));
++          save_ext_update (current_ext_record, use_exp);
++        }
++
++      if (dump_file)
++        fprintf (dump_file,
++                 "%*suse at uid=%d of reg=%d\n", indent, " ",
++                 INSN_UID (insn_use), DF_REF_REGNO (df_use));
++      /* Set indent for dump formatting */
++      if (indent_once)
++        {
++          ++indent;
++          indent_once = false;
++        }
++      ext_needed = analyze_ext_use (insn_use, DF_REF_REGNO (df_use), indent);
++      if (ext_needed)
++        break;
++    }
++
++  if (dump_file)
++    fprintf (dump_file,
++             "%*sext %s needed\n", indent, " ", ext_needed ? "" : "not");
++
++  return ext_needed;
++}
++
++/* Set a flag on an insn indicating that it is
++   marked for replacement by a copy insn or for
++   deletion. */
++
++static void
++mark_replace_with_copy (rtx ext)
++{
++  extelim_uid_t uid = INSN_UID (ext);
++  insn_flag_set (EXTELIM_REPLACE_COPY, uid);
++}
++
++/* Get the mode that we are sign/zero extending from */
++
++static enum machine_mode
++get_ext_from_mode (rtx src)
++{
++  rtx regexp;
++  gcc_assert (GET_CODE (src) == ZERO_EXTEND || GET_CODE (src) == SIGN_EXTEND);
++
++  /* The SUBREG or REG mode of the extend operand */
++  regexp = XEXP (src, 0);
++  return (GET_MODE (regexp));
++}
++
++/* Perform the action on the expression. Return true
++   if any action performed, false otherwise. */
++
++static bool 
++process_ext_update (rtx exp)
++{
++  /* Reset SUBREG_PROMOTED state to false */
++  if (GET_CODE (exp) == SUBREG
++      && SUBREG_PROMOTED_VAR_P (exp))
++    {
++      SUBREG_PROMOTED_VAR_P (exp) = 0;
++      return true;
++    }
++
++  return false;
++}
++
++/* Process the current extension record, looking at all the
++   the expressions that need to be updated because this
++   extension will be replaced by a copy. */
++
++static void
++process_ext_updates (ext_record_t extrec)
++{
++  unsigned i;
++  rtx exp;
++  bool updated=false;
++
++
++  FOR_EACH_VEC_ELT (rtx, extrec->ext_updates, i, exp)
++    {
++      updated |= process_ext_update (exp);
++    }
++
++  if (dump_file && updated)
++    fprintf (dump_file, " updates processed for extension at uid=%d\n",
++             INSN_UID (extrec->ext));
++}
++
++/* Try to eliminate the sign extension by examining the
++   definitions of the extension source and the uses
++   of the extension destination. */
++
++static void
++eliminate_one_extend (rtx ext)
++{
++  rtx src, dest, regexp;
++  df_ref df_use, df_def, *ext_use, *ext_def;
++  unsigned int ext_dest_regno, ext_src_regno, def_use_count = 1;
++  bool ext_needed = true;
++  extelim_uid_t uid = INSN_UID (ext);
++  struct df_link *link;
++  const char *inserted =
++    insn_flag_p (EXTELIM_INSERTED, uid) ? "inserted" : "";
++
++  /* Reset desired per insn flags for each extension analyzed */
++  reinit_insn_flags (EXTELIM_SEEN);
++
++  gcc_assert (GET_CODE (PATTERN (ext)) == SET);
++  src = SET_SRC (PATTERN (ext));
++  dest = SET_DEST (PATTERN (ext));
++
++  /* Save the basic information about the extension in a file global */
++  ext_to_mode = GET_MODE (dest);
++  ext_from_mode = get_ext_from_mode (src);
++  ext_code = GET_CODE (src);
++
++  /* Also mark this original extension as "SEEN" so we don't recurse into it. */
++  insn_flag_set (EXTELIM_SEEN, INSN_UID (ext));
++
++  /* Find the target of the extension */
++  if (!REG_P (dest))
++    return;
++  ext_dest_regno = REGNO (dest);
++
++  /* Find the source of the extension: set (REG:MODE (sign_extend (REG|SUBREG:MODE ... */
++  if ((regexp = register_exp (XEXP (src, 0))) == NULL)
++    return;
++  ext_src_regno = REGNO (regexp);
++
++  /* Iterate through the reaching definitions of the source of the extension 
++     recursively. If the source if already sign extended, mark the 
++     extension for replacement with a copy or deletion (deletion if it was
++     inserted in the duplication pass). */
++  ext_use = DF_INSN_UID_USES (uid);
++  /* There is only one use in a sign/zero extension insn and it must be the
++     source register */
++  gcc_assert (*(ext_use + 1) == NULL);
++  gcc_assert (DF_REF_REGNO (*ext_use) == ext_src_regno);
++
++  /* Now look at all the reaching definitions of this use */
++  for (link = DF_REF_CHAIN (*ext_use); link; link = link->next)
++    {
++      rtx insn_def;
++      df_def = link->ref;
++      if (!df_def)
++        continue;
++      /* Link must be to a definition of the use */
++      if (!DF_REF_REG_DEF_P (df_def))
++        continue;
++      /* Ignore ARTIFICIAL defs */
++      if (DF_REF_IS_ARTIFICIAL (df_def))
++        continue;
++      insn_def = DF_REF_INSN (df_def);
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_def))
++        continue;
++      if (dump_file)
++        fprintf (dump_file,
++                 " analyze def #%d of reg=%d at uid=%u\n",
++                 def_use_count, DF_REF_REGNO (*ext_use), INSN_UID (insn_def));
++      ext_needed = analyze_ext_def (insn_def, DF_REF_REGNO (*ext_use), 2);
++      if (ext_needed)
++        break;
++      def_use_count++;
++    }
++
++  /* Try the def-use chains if the extension wasn't marked by the
++     previous pass. */
++  if (ext_needed)
++    {
++      /* Defs of the sign extension */
++      ext_def = DF_INSN_UID_DEFS (uid);
++      /* There is only one def in a sign extension insn and it must be the
++         destination */
++      gcc_assert (*(ext_def + 1) == NULL);
++      gcc_assert (DF_REF_REGNO (*ext_def) == ext_dest_regno);
++
++      /* Counter for debug dump */
++      def_use_count = 1;
++      /* Reset desired per insn flags for each extension analyzed */
++      reinit_insn_flags (EXTELIM_SEEN);
++      /* Also mark this original extension as "SEEN" so we don't recurse into it. */
++      insn_flag_set (EXTELIM_SEEN, INSN_UID (ext));
++
++      /* Iterate over the reached uses of extension destination register recursively.
++         If the destination register's upper bits are ultimately not
++         relevant, the extension can be marked for replacement with a
++         copy. */
++      for (link = DF_REF_CHAIN (*ext_def); link; link = link->next)
++        {
++          rtx insn_use, use_exp;
++          df_use = link->ref;
++          if (!df_use)
++            continue;
++          /* Link must be a USE of the DEF */
++          if (!DF_REF_REG_USE_P (df_use))
++            continue;
++          /* Ignore ARTIFICIAL USES */
++          if (DF_REF_IS_ARTIFICIAL (df_use))
++            continue;
++          insn_use = DF_REF_INSN (df_use);
++          /* Don't consider debug_insns */
++          if (!NONDEBUG_INSN_P (insn_use))
++            continue;
++          use_exp = DF_REF_REG (df_use);
++
++          if (exp_needs_update_p (use_exp))
++            {
++              if (dump_file)
++                fprintf (dump_file,
++                         " saved reg=%d expression for update\n", DF_REF_REGNO (df_use));
++              save_ext_update (current_ext_record, use_exp);
++            }
++            
++          if (dump_file)
++            fprintf (dump_file,
++                     " analyze use #%d at uid=%u of reg=%d\n",
++                     def_use_count, INSN_UID (insn_use),
++                     DF_REF_REGNO (*ext_def));
++          ext_needed = analyze_ext_use (insn_use, DF_REF_REGNO (*ext_def), 2);
++          if (ext_needed)
++            break;
++          def_use_count++;
++        }
++    }
++
++  /* The extension is not needed. The rtl for the extension is marked
++     for replace by copy. */
++  if (!ext_needed)
++    {
++      process_ext_updates (current_ext_record);
++
++      if (dump_file)
++        fprintf (dump_file,
++                 ":) mark %s extension insn uid=%d for copy replacement\n",
++                 inserted, INSN_UID (ext));
++      mark_replace_with_copy (ext);
++      num_cand_transformed++;
++    }
++  else
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 ":( %s extension insn uid=%d is needed\n", inserted,
++                 INSN_UID (ext));
++    }
++}
++
++/* Replace the sign extension with a copy instruction
++
++   example 1:
++   from:
++        dest              src
++   (set (reg:DI destreg) (sign_extend:DI (reg:SI srcreg)))
++   to:
++   (clobber (reg:DI destreg))
++   (set (subreg:SI (reg:DI destreg) 4) (reg:SI srcreg)) 
++
++   or
++
++   example 2:
++   from:
++        dest             src
++   (set (reg:DI destreg) (sign_extend:DI (subreg:SI (reg:DI srcreg) 4)))
++   to:
++   (clobber (reg:DI destreg))
++   (set (subreg:SI (reg:DI destreg) 4) (subreg:SI (reg:DI srcreg) 4)) 
++
++   or
++
++   example 3:
++   from:
++        dest             src
++   (set (reg:SI destreg) (sign_extend:SI (subreg:HI (reg:SI srcreg) 2)))
++   to:
++   (clobber (reg:SI destreg))
++   (set (subreg:HI (reg:SI destreg) 2) (subreg:HI (reg:SI srcreg) 2)) */
++
++static void
++replace_with_copy (rtx ext)
++{
++  rtx extension = PATTERN (ext);
++  rtx ext_op, src, dest, insns, cp_dest, cp_src;
++  enum machine_mode inner_mode;
++  gcc_assert (GET_CODE (extension) == SET);
++
++  dest = SET_DEST (extension);
++  src = SET_SRC (extension);
++
++  /* The sign extension operand */
++  ext_op = XEXP (src, 0);
++  /* Get the inner mode */
++  inner_mode = GET_MODE (ext_op);
++  gcc_assert (inner_mode == SImode || inner_mode == HImode
++              || inner_mode == QImode);
++
++  /* Make dest a SUBREG:mm */
++  cp_dest = gen_lowpart_SUBREG (inner_mode, dest);
++
++  /* Copy src is the sign extension target register */
++  cp_src = ext_op;
++
++  /* ??? clobber is needed for rtl consistency, don't know why */
++  start_sequence ();
++  emit_clobber (dest);
++  emit_move_insn (cp_dest, cp_src);
++  insns = get_insns ();
++  end_sequence ();
++  emit_insn_before (insns, ext);
++
++  delete_insn (ext);
++}
++
++/* Iterate through extensions, replace those extensions
++   that are marked as so with a copy insn. */
++
++static void
++replace_ext_with_copy (void)
++{
++  ext_record_t extrec;
++  unsigned i;
++
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    const char *inserted = insn_flag_p (EXTELIM_INSERTED,
++                                        INSN_UID (extrec->
++                                                  ext)) ? "inserted" : "";
++    if (insn_flag_p (EXTELIM_REPLACE_COPY, INSN_UID (extrec->ext)))
++      {
++        if (dump_file)
++          fprintf (dump_file,
++                   " replace %s extension uid=%d with a copy\n", inserted,
++                   INSN_UID (extrec->ext));
++        replace_with_copy (extrec->ext);
++      }
++  }
++}
++
++
++/* Copy the RTX flags from old to new */
++
++static void
++copy_flags (rtx oldrtx, rtx newrtx)
++{
++  if (RTX_FLAG (oldrtx, in_struct))
++    RTX_FLAG (newrtx, in_struct) = true;
++
++  if (RTX_FLAG (oldrtx, volatil))
++    RTX_FLAG (newrtx, volatil) = true;
++
++  if (RTX_FLAG (oldrtx, unchanging))
++    RTX_FLAG (newrtx, unchanging) = true;
++
++  if (RTX_FLAG (oldrtx, frame_related))
++    RTX_FLAG (newrtx, frame_related) = true;
++
++  if (RTX_FLAG (oldrtx, jump))
++    RTX_FLAG (newrtx, jump) = true;
++
++  if (RTX_FLAG (oldrtx, call))
++    RTX_FLAG (newrtx, call) = true;
++
++  if (RTX_FLAG (oldrtx, return_val))
++    RTX_FLAG (newrtx, return_val) = true;
++}
++
++/* Iterate through the insn notes looking for 'kind'. If 
++   found replace the register rtx with the new rtx. */
++
++static void
++update_notes (enum reg_note kind, rtx insn, rtx reg, rtx new_reg)
++{
++  rtx link;
++  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
++    if (REG_NOTE_KIND (link) == kind)
++      {
++        rtx op0 = XEXP (link, 0);
++        if (kind == REG_DEAD)
++          if (REG_P (op0) && op0 == reg)
++            XEXP (link, 0) = new_reg;
++      }
++}
++
++
++
++#if EXTELIM_DUPLICATE_EXTS_AT_USES
++/* Insert a duplicate sign extension at the use point.
++   Add a flag indicating this extension is algorithmically
++   added. Since the "inserted" extensions have the form
++   regX = sign_extend (subreg:mm (reg:MM regX), offset), 
++   they can simply be deleted if they are redundant since we 
++   are at a reaching use of the original definition. We also 
++   mark the use insn where the insert occurs so we don't insert 
++   the same extension from another def at this use. */
++
++static void
++insert_duplicate_ext_at_use (rtx ext_insn, rtx use_insn)
++{
++  rtx ext = PATTERN (ext_insn), ext_src, ext_dest;
++  rtx new_ext_src_inner, new_ext_src_outer, new_ext_part;
++  rtx new_ext_dest, new_ext_insn;
++  extelim_uid_t new_uid;
++  df_ref *p_df_uses;
++  unsigned int ext_dest_regno;
++  enum machine_mode inner_mode;
++  bool sign_extend_p =
++    GET_CODE (SET_SRC (PATTERN (ext_insn))) == SIGN_EXTEND ? true : false;
++
++  /* This new extension must be of the form:
++     set (reg:MM X (sign_extend:MM (subreg:mm (reg:MM X)))) 
++     where mm is smaller than MM. */
++  ext_dest = SET_DEST (ext);
++  ext_src = SET_SRC (ext);
++
++  gcc_assert (REG_P (register_exp (ext_dest)));
++
++  /* A copy of the extend destination register to a new virtual register */
++  new_ext_dest = gen_reg_rtx (GET_MODE (ext_dest));
++  /* A copy of the extend source (same reg as dest), REG_P */
++  new_ext_src_inner = copy_rtx (ext_dest);
++  /* Get inner mode, either mm for SUBREG:mm (REG:MM) or MM for (REG:MM) */
++  if (GET_CODE (XEXP (ext_src, 0)) == SUBREG)
++    inner_mode = GET_MODE (XEXP (ext_src, 0));
++  else if (REG_P (XEXP (ext_src, 0)))
++    inner_mode = GET_MODE (XEXP (ext_src, 0));
++  else
++    /* Can't determine sign_extend operand */
++    gcc_unreachable ();
++
++  /* Make a subreg rtx */
++  new_ext_src_outer = gen_lowpart_SUBREG (inner_mode, new_ext_src_inner);
++  /* Make a sign/zero extend insn */
++  new_ext_part = sign_extend_p
++    ? gen_rtx_SIGN_EXTEND (GET_MODE (ext_dest), new_ext_src_outer)
++    : gen_rtx_ZERO_EXTEND (GET_MODE (ext_dest), new_ext_src_outer);
++  /* (set (new:MM (sign_extend:MM (subreg:mm (reg:MM ext_dest))))) */
++  new_ext_insn = gen_rtx_SET (VOIDmode, new_ext_dest, new_ext_part);
++
++  /* Now update the use */
++  /* Operands used by this the use_insn */
++  ext_dest_regno = REGNO (register_exp (ext_dest));
++  for (p_df_uses = DF_INSN_UID_USES (INSN_UID (use_insn)); *p_df_uses;
++       p_df_uses++)
++    {
++      if (DF_REF_REGNO (*p_df_uses) == ext_dest_regno)
++        {
++          rtx use_reg = DF_REF_REG (*p_df_uses);
++
++          /*  Replace the register use in use_insn with the new register. If the use
++             is a subreg pattern, replace the innermost reg. */
++          replace_rtx (PATTERN (use_insn), register_exp (use_reg),
++                       new_ext_dest);
++          /* Update flags on new dest reg */
++          copy_flags (register_exp (use_reg), new_ext_dest);
++          /* Update any notes associated with use reg and use_insn */
++          update_notes (REG_DEAD, use_insn, register_exp (use_reg), new_ext_dest);
++          /* DF info must be updated since existing insn is changed */
++          df_insn_rescan (use_insn);
++        }
++    }
++
++  new_uid = extelim_emit_before (new_ext_insn, use_insn);
++  insn_flag_set (EXTELIM_INSERTED, new_uid);
++}
++
++/* Allow the duplication of the extension even if the extension
++   and the duplication use are in the same block. */
++
++static bool
++allow_same_block_duplication_p (rtx ext_insn, rtx use_insn)
++{
++  rtx ext = PATTERN (ext_insn);
++  rtx use = PATTERN (use_insn);
++
++  if (GET_CODE (SET_SRC (use)) == ASHIFT && GET_CODE (SET_SRC (ext)) == ZERO_EXTEND)
++    return true;
++  return false;
++}
++
++/* Determine if the extension should be duplicated at this use point.
++   Return true if yes, false otherwise. */
++
++static bool
++save_ext_use_p (ext_record_t extrec, rtx use_insn)
++{
++  rtx ext_insn, ext, ext_dest, use = PATTERN (use_insn), use_src;
++  df_ref df_use;
++
++  ext_insn = extrec->ext;
++  ext = PATTERN (ext_insn);
++  ext_dest = SET_DEST (ext);
++
++  if (GET_CODE (use) != SET)
++    {
++      if (dump_file)
++        fprintf (dump_file, "  no -- use is not a SET code\n");
++      return false;
++    }
++
++  /* Check for obviousness */
++  /* 1. The use is only reached by the a single definition of the extension.
++     Otherwise, it wouldn't be legal to insert a duplicate extension
++     as other defs reaching this use may not need it. Certainly not all
++     other defs may reach here, but this is the conservative approximation. 
++     Found in nof/muldf3.c */
++  df_use = df_find_use (use_insn, ext_dest);
++  if ( df_use && DF_REF_CHAIN (df_use)->next)
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "  no -- there are multiple definitions of reg=%d reaching this use\n",
++                 (REGNO (register_exp (ext_dest))));
++      return false;
++    }
++
++  /* 2. The extension and use are in the same block. Since
++     this is a reached use, it's obvious we don't need another
++     extension. The exception is this -- we are trying to set
++     up a specific extension,insn pattern that will be recognized
++     by the insn selector. This pattern will also be ignored when
++     the next extension candidate list is created in the next pass. */
++  if (INSN_P (ext_insn) && INSN_P (use_insn))
++    {
++      if (BLOCK_FOR_INSN (ext_insn) == BLOCK_FOR_INSN (use_insn))
++        {
++          if (allow_same_block_duplication_p (ext_insn, use_insn))
++            ;
++          else
++            {
++              if (dump_file)
++                fprintf (dump_file,
++                         "  no -- ext and use are in the same block\n");
++              return false;
++            }
++        }
++    }
++
++  /* 3. The use is a sign extension of the extension destination reg */
++  use_src = SET_SRC (use);
++  if (GET_CODE (use_src) == SIGN_EXTEND
++      && REG_P (register_exp (XEXP (use_src, 0)))
++      && REG_P (register_exp (ext_dest)))
++    if (GET_MODE (use_src) == GET_MODE (ext_dest)
++        && REGNO (register_exp (XEXP (use_src, 0))) ==
++        REGNO (register_exp (ext_dest)))
++      {
++        if (dump_file)
++          fprintf (dump_file,
++                   "  no -- the use is a sign extension of reg=%d\n",
++                   REGNO (register_exp (XEXP (use_src, 0))));
++        return false;
++      }
++
++  /* 4. The use already has an extension inserted and one of the use's operands
++     is a register matching the reaching definition. So don't reinsert the same
++     extension. */
++  if (insn_flag_p (EXTELIM_INSERTED_FOR, INSN_UID (use_insn)))
++    {
++      df_ref *p_df_uses;
++      /* Operands used by this the use_insn */
++      for (p_df_uses = DF_INSN_UID_USES (INSN_UID (use_insn)); *p_df_uses;
++           p_df_uses++)
++        {
++          if (REG_P (register_exp (ext_dest)) &&
++              DF_REF_REGNO (*p_df_uses) == REGNO (register_exp (ext_dest)))
++            {
++              if (dump_file)
++                fprintf (dump_file,
++                         "  no -- this use is marked for sign extension insertion already\n");
++              return false;
++            }
++        }
++    }
++
++  /* 5. There is also a definition of the ext dest register at this use (as can occur in self assignment). */
++  if (register_exp (SET_DEST (use)) && REG_P (ext_dest) 
++       && REGNO (register_exp (SET_DEST (use))) == REGNO (ext_dest))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "  no -- this use also assigns the used register\n");
++      return false;
++    }
++
++
++  if (dump_file)
++    fprintf (dump_file, "  yes\n");
++  return true;
++}
++
++/* Save the use insn in the extension records list of
++   uses. At the next phase, we will duplicate the extension
++   at these use points. */
++
++static void
++save_ext_use (ext_record_t extrec, rtx use_insn)
++{
++  /* Mark the use insn, it will have a duplicate inserted */
++  insn_flag_set (EXTELIM_INSERTED_FOR, INSN_UID (use_insn));
++  /* Save use to the list of uses to be duplicated for this extension. */
++  VEC_safe_push (rtx, heap, extrec->ext_uses, use_insn);
++}
++
++
++/* Save the qualified use of an extension to a list */
++
++static void
++gather_ext_uses_info (ext_record_t extrec)
++{
++  rtx ext;
++  df_ref *ext_def, df_use;
++  unsigned int def_use_count = 1;
++  extelim_uid_t uid;
++  struct df_link *link;
++
++  gcc_assert (extrec != NULL);
++  ext = extrec->ext;
++  uid = INSN_UID (ext);
++
++  /* Insn level defs of the sign extension */
++  ext_def = DF_INSN_UID_DEFS (uid);
++  /* There is only one def in a sign extension insn */
++  gcc_assert (*(ext_def + 1) == NULL);
++
++  /* Iterate over the reached uses of extension destination register.
++     Duplicate the extension at the use point. */
++  for (link = DF_REF_CHAIN (*ext_def); link; link = link->next)
++    {
++      rtx insn_use;
++      df_use = link->ref;
++      if (!df_use)
++        continue;
++      /* Link must be a USE of the DEF */
++      if (!DF_REF_REG_USE_P (df_use))
++        continue;
++      /* Ignore ARTIFICIAL USES */
++      if (DF_REF_IS_ARTIFICIAL (df_use))
++        continue;
++      insn_use = DF_REF_INSN (df_use);
++
++      /* Don't consider debug_insns */
++      if (!NONDEBUG_INSN_P (insn_use))
++        continue;
++
++      if (dump_file)
++        fprintf (dump_file,
++                 " use #%d duplicate ext of reg=%d at uid=%u?\n",
++                 def_use_count, DF_REF_REGNO (*ext_def), INSN_UID (insn_use));
++      if (save_ext_use_p (extrec, insn_use))
++        save_ext_use (extrec, insn_use);
++      def_use_count++;
++    }
++}
++
++/* At each use point of the sign extension, unless the 
++   use is obviously already sign extended, insert a 
++   sign extension insn before the use. We do this in two
++   passes to avoid confusing the dataflow information. */
++
++static void
++duplicate_exts_at_uses (void)
++{
++  unsigned i, j;
++  ext_record_t extrec;
++  rtx use_insn;
++
++  /* Get the uses where the extensions will be duplicated */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    if (dump_file)
++      fprintf (dump_file, "gathering extension uid=%u use information\n",
++               INSN_UID (extrec->ext));
++    gather_ext_uses_info (extrec);
++  }
++
++  /* Now duplicate the extensions at the appropriate use points */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, extrec)
++  {
++    if (dump_file)
++      fprintf (dump_file, "extension uid=%u\n", INSN_UID (extrec->ext));
++
++    FOR_EACH_VEC_ELT (rtx, extrec->ext_uses, j, use_insn)
++    {
++      if (dump_file)
++        fprintf (dump_file, " duplicated at use uid=%u\n",
++                 INSN_UID (use_insn));
++      insert_duplicate_ext_at_use (extrec->ext, use_insn);
++    }
++  }
++}
++#endif /* EXTELIM_DUPLICATE_EXTS_AT_USES */
++
++/* Determine if an instruction is a return insn */
++
++static rtx
++return_p (rtx rtn_insn)
++{
++  rtx rtn = PATTERN (rtn_insn), dest;
++  int i;
++
++  if (GET_CODE (rtn) != SET)
++    return false;
++
++  dest = SET_DEST (rtn);
++
++  /* Is a return value? */
++  if ((REG_P (dest) || GET_CODE (dest) == PARALLEL) &&
++      REG_FUNCTION_VALUE_P (dest))
++    {
++      /* Simple SET, return the insn */
++      if (REG_P (dest))
++        return rtn_insn;
++      /* PARALLEL, find the embedded rtx */
++      if (GET_CODE (dest) == PARALLEL)
++        for (i = XVECLEN (rtn_insn, 0) - 1; i >= 0; i--)
++          {
++            rtx body = XVECEXP (rtn_insn, 0, i);
++            if (GET_CODE (body) == SET)
++              {
++                dest = SET_DEST (body);
++                if (REG_FUNCTION_VALUE_P (dest))
++                  return body;
++              }
++          }
++    }
++  /* Not a return */
++  return NULL;
++}
++
++/* Find all return RTLs in the function and save them in
++   a list. */
++
++static bool
++find_returns (void)
++{
++  basic_block bb;
++  rtx insn, rtn_insn;
++  bool found = false;
++
++  /* For all insns  */
++  FOR_EACH_BB (bb)
++  {
++    FOR_BB_INSNS (bb, insn)
++    {
++      if (!NONDEBUG_INSN_P (insn))
++        continue;
++
++      if ((rtn_insn = return_p (insn)) == NULL)
++        {
++          continue;
++        }
++      if (dump_file)
++        fprintf (dump_file, " found return at uid=%u\n", INSN_UID (rtn_insn));
++
++      VEC_safe_push (rtx, heap, returns, rtn_insn);
++      found = true;
++    }
++  }
++
++  return (found);
++}
++
++/* Get the signedness and machine mode of the function */
++
++static bool
++get_return_info (bool * signed_p, enum machine_mode *return_mode)
++{
++  tree rtninfo;
++
++  if ((rtninfo = DECL_RESULT (current_function_decl)) != NULL)
++    {
++      *signed_p = !TYPE_UNSIGNED (TREE_TYPE (rtninfo));
++      *return_mode = DECL_MODE (rtninfo);
++      return true;
++    }
++  return false;
++}
++
++/* If the dest mode of the return is larger than
++   the function return mode, we can subreg the return
++   insn to the return mode and extend to the destination.
++   E.g. unsigned, return mode: HImode
++   set (reg/i:DI Y) (reg:DI X) 
++   becomes
++   set (reg:DI new) (zero_extend:DI (subreg:HI (reg:DI X)))
++   set (reg/i:DI Y) (reg:DI new) */
++
++static void
++make_ext_at_rtn (rtx rtn_insn, bool fun_signed_p, enum machine_mode fun_mode)
++{
++  rtx rtn = PATTERN (rtn_insn);
++  rtx dest, src, new_ext_dest, new_ext_src, new_ext_outer, new_ext_part,
++    new_ext_insn;
++  extelim_uid_t new_uid;
++  gcc_assert (GET_CODE (rtn) == SET);
++
++  dest = SET_DEST (rtn);
++  src = SET_SRC (rtn);
++
++  /* Deal with scalar rtn values only */
++  if (fun_mode != DImode
++      && fun_mode != SImode && fun_mode != HImode && fun_mode != QImode)
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- not scalar return mode\n");
++      return;
++    }
++
++  /* Dest and src have to have the same mode. This should always be
++     true for well formed rtl, but we check anyway. */
++  if (GET_MODE (dest) != GET_MODE (src))
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- dest and src modes differ\n");
++      return;
++    }
++
++  /* Also check that we are dealing with simple regs here. */
++  if (!REG_P (dest) || !REG_P (src))
++    {
++      if (dump_file)
++        fprintf (dump_file, "failed-- dest or src is not REG_P\n");
++      return;
++    }
++
++  /* The return reg mode should never be smaller than fun return mode. If the
++     same size, however, we can't subreg either, so return */
++  if (GET_MODE_BITSIZE (GET_MODE (dest)) <= GET_MODE_BITSIZE (fun_mode))
++    {
++      if (dump_file)
++        fprintf (dump_file,
++                 "failed-- dest size mode is smaller or equal to function mode size\n");
++      return;
++    }
++
++  /* From here we should be able to build a subreg since the function return mode
++     size is smaller than the return register mode size */
++  new_ext_dest = gen_reg_rtx (GET_MODE (src));  /*  set (reg:MM new) */
++  new_ext_src = copy_rtx (src); /*  copy of X, copyX */
++  new_ext_outer = gen_lowpart_SUBREG (fun_mode, new_ext_src);   /*  subreg:mm (reg:MM copyX) */
++  new_ext_part = fun_signed_p   /*  extend:MM (subreg:mm (reg:MM copyX)) */
++    ? gen_rtx_SIGN_EXTEND (GET_MODE (src), new_ext_outer)
++    : gen_rtx_ZERO_EXTEND (GET_MODE (src), new_ext_outer);
++  /* Put it together */
++  new_ext_insn = gen_rtx_SET (VOIDmode, new_ext_dest, new_ext_part);
++
++  /* Modify src of return insn to use new pseudo */
++  replace_rtx (PATTERN (rtn_insn), src, new_ext_dest);
++  /* Update flags on new dest reg */
++  copy_flags (src, new_ext_dest);
++  /* Update any notes associated with replaced register */
++  update_notes (REG_DEAD, rtn_insn, src, new_ext_dest);
++  /* Rescan the modified insn */
++  df_insn_rescan (rtn_insn);
++  /* Insert the new insn */
++  new_uid = extelim_emit_before (new_ext_insn, rtn_insn);
++
++  if (dump_file)
++    fprintf (dump_file, "success\n");
++}
++
++/* Insert extensions at return points. Scan the RTL
++   for the return statements. Determine if the RTL 
++   can be modified to insert an extension. Modify the
++   return to insert the extension. */
++
++static void
++insert_ext_at_returns (void)
++{
++  bool signed_p;
++  enum machine_mode return_mode;
++  rtx rtn_insn;
++  int i;
++
++  /* Generate list of return rtls for the function */
++  if (dump_file)
++    fprintf (dump_file, "gathering return insns...\n");
++
++  if (!find_returns ())
++    return;
++
++  if (!get_return_info (&signed_p, &return_mode))
++    return;
++
++  /* For each return instruction, generate a sign/zero extend
++     if the current return size is larger than the function
++     return mode. */
++  FOR_EACH_VEC_ELT (rtx, returns, i, rtn_insn)
++  {
++    if (dump_file)
++      fprintf (dump_file, " making extension at return uid=%u...",
++               INSN_UID (rtn_insn));
++    make_ext_at_rtn (rtn_insn, signed_p, return_mode);
++  }
++}
++
++/* Compare two extension records by loop depth.
++   Used by VEC_qsort to sort the order in which extensions
++   are processed. */
++
++static int
++ext_record_compare (const void *p_er1, const void *p_er2)
++{
++  const ext_record_t er1 = *(const ext_record_t *) p_er1;
++  const ext_record_t er2 = *(const ext_record_t *) p_er2;
++  basic_block bb1, bb2;
++  rtx ext1, ext2;
++
++  if (er1 == er2)
++    return 0;
++
++  ext1 = er1->ext;
++  ext2 = er2->ext;
++
++  bb1 = BLOCK_FOR_INSN (ext1);
++  bb2 = BLOCK_FOR_INSN (ext2);
++
++  /* Sort high to low */
++  return (bb2->loop_depth - bb1->loop_depth);
++}
++
++/* The main interface to this optimization. */
++
++static void
++extension_elimination (void)
++{
++  ext_record_t ext;
++  unsigned i;
++
++  init_pass ();
++
++  /* Find initial sign extension candidates */
++  if (!find_extensions ())
++    {
++      finish_pass ();
++      return;
++    }
++
++  /* Insert sign extension at return points in
++     the function. */
++  insert_ext_at_returns ();
++
++  /* Duplicate the sign extensions at their use
++     points unless the use is already obviously sign
++     extended or extension is already added. */
++#if EXTELIM_DUPLICATE_EXTS_AT_USES
++  duplicate_exts_at_uses ();
++#endif
++
++  /* Update DF information since now have new insns. */
++  df_finish_pass (true);
++  df_chain_add_problem (DF_DU_CHAIN + DF_UD_CHAIN);
++  df_analyze ();
++
++#if EXTELIM_DF_DUMP
++  if (dump_file)
++    df_dump (dump_file);
++#endif
++
++  /* Init statistics */
++  num_cand = 0;
++  num_cand_ignored = 0;
++  num_cand_transformed = 0;
++
++  /* Free old extensions list, generate new one that includes
++     the new extensions. */
++  free_extensions ();
++
++ if (!find_extensions ())
++    {
++      finish_pass ();
++      return;
++    }
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "\nRTL After Extension Duplication\n");
++      print_rtl (dump_file, get_insns ());
++    }
++
++  if (dump_file)
++    fprintf (dump_file, "Begin extension elimination analysis\n");
++
++  /* Sort the extensions by loop depth. We want to try to eliminate
++     those in innermost loops (highest loop depth) first. */
++  VEC_qsort (ext_record_t, extensions, ext_record_compare);
++
++  /* Iterate through extension worklist */
++  FOR_EACH_VEC_ELT (ext_record_t, extensions, i, ext)
++  {
++    rtx ext_insn = ext->ext;
++    rtx ext_src = SET_SRC (PATTERN (ext_insn));
++    const char *ext_name =
++      GET_CODE (ext_src) == SIGN_EXTEND ? "sign" : "zero";
++    const char *inserted =
++      insn_flag_p (EXTELIM_INSERTED, INSN_UID (ext_insn)) ? "inserted" : "";
++    extelim_uid_t uid = INSN_UID (ext_insn);
++
++    if (dump_file)
++      fprintf (dump_file,
++               "<analyzing %s %s extension uid=%u> (loop_depth=%d)\n",
++               inserted, ext_name, uid,
++               BLOCK_FOR_INSN (ext_insn)->loop_depth);
++
++    current_ext_record = ext;
++    eliminate_one_extend (ext->ext);
++  }
++
++  if (dump_file)
++    fprintf (dump_file, "Begin extension elimination transformations\n");
++
++  replace_ext_with_copy ();
++
++  if (dump_file)
++    fprintf (dump_file, "\nRTL After Extension Elimination\n");
++
++  finish_pass ();
++
++  /* Print statistics */
++  if (dump_file)
++    {
++      fprintf (dump_file,
++               "Number of extensions ignored: %d (of %d candidiates)\nDETECTION EFFECTIVENESS: %f%%\n",
++               num_cand_ignored, num_cand,
++               ((float) (num_cand - num_cand_ignored) / (float) num_cand) *
++               100);
++      fprintf (dump_file,
++               "Number of extensions converted to copy: %d (of %d candidiates)\nCONVERSION EFFECTIVENESS: %f%%\n",
++               num_cand_transformed, num_cand,
++               ((float) num_cand_transformed / (float) num_cand) * 100);
++    }
++}
++
++/* Remove redundant extensions.  */
++
++static unsigned int
++rest_of_handle_extelim (void)
++{
++  extension_elimination ();
++  return 0;
++}
++
++/* Run extelim pass when flag_extelim is set at optimization level > 0.  */
++
++static bool
++gate_handle_extelim (void)
++{
++  return (optimize > 0 && flag_extelim);
++}
++
++struct rtl_opt_pass pass_rtl_extelim = {
++  {
++   RTL_PASS,
++   "extelim",                   /* name */
++   gate_handle_extelim,         /* gate */
++   rest_of_handle_extelim,      /* execute */
++   NULL,                        /* sub */
++   NULL,                        /* next */
++   0,                           /* static_pass_number */
++   TV_EXTELIM,                  /* tv_id */
++   0,                           /* properties_required */
++   0,                           /* properties_provided */
++   0,                           /* properties_destroyed */
++   0,                           /* todo_flags_start */
++   TODO_ggc_collect | TODO_dump_func | TODO_df_finish | TODO_verify_rtl_sharing,        /* todo_flags_finish */
++   }
++};
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_MTWX51204-dwarf-vector-reg.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_MTWX51204-dwarf-vector-reg.patch
new file mode 100644 (file)
index 0000000..cb34859
--- /dev/null
@@ -0,0 +1,9 @@
+diff -Naur gcc-4.6.2/gcc/config/rs6000/sysv4.h gcc-4.6.2-MTWX51204-dwarf-vector-reg/gcc/config/rs6000/sysv4.h
+--- gcc-4.6.2/gcc/config/rs6000/sysv4.h        2011-03-07 01:50:23.000000000 -0600
++++ gcc-4.6.2-MTWX51204-dwarf-vector-reg/gcc/config/rs6000/sysv4.h     2011-12-16 09:44:18.469039002 -0600
+@@ -1035,5 +1035,3 @@
+ /* This target uses the sysv4.opt file.  */
+ #define TARGET_USES_SYSV4_OPT 1
+-
+-#undef DBX_REGISTER_NUMBER
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_SSIZE_MAX_undefine_issue.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_SSIZE_MAX_undefine_issue.patch
new file mode 100644 (file)
index 0000000..51dc558
--- /dev/null
@@ -0,0 +1,11 @@
+--- gcc-4_6-branch/gcc/config/host-linux.c.orig        2012-03-08 02:18:57.282190580 -0600
++++ gcc-4_6-branch/gcc/config/host-linux.c     2012-03-08 02:19:30.930158694 -0600
+@@ -17,6 +17,8 @@
+    along with GCC; see the file COPYING3.  If not see
+    <http://www.gnu.org/licenses/>.  */
++#include <bits/posix1_lim.h>
++
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_build-with-cxx.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_build-with-cxx.patch
new file mode 100644 (file)
index 0000000..cfceafd
--- /dev/null
@@ -0,0 +1,39 @@
+gcc.fix_build-with-cxx
+
+On native builds, when linking cc1 with static libraries (ppl cloog,
+gmp, mpfr), there is c++ code brought in by libppl. Normally cc1 is
+linked through "gcc", but in this case it should be linked with "g++".
+
+To work around this, gcc is configured with --enable-build-with-cxx,
+which compiles and links the entire compiler with g++. Since g++ is
+more rigorous about the use of the "const" keyword, there is a couple
+of places that we get syntax errors. This patch fixes them.
+
+--- gcc-4.6.0/gcc/config/rs6000/rs6000.c-orig  2011-05-09 10:35:55.627190744 -0500
++++ gcc-4.6.0/gcc/config/rs6000/rs6000.c       2011-05-09 10:39:09.232814653 -0500
+@@ -22502,11 +22502,12 @@
+ rs6000_xcoff_strip_dollar (const char *name)
+ {
+   char *strip, *p;
++  const char *q;
+   int len;
+-  p = strchr (name, '$');
++  q = strchr (name, '$');
+-  if (p == 0 || p == name)
++  if (q == 0 || q == name)
+     return name;
+   len = strlen (name);
+--- gcc-4.6.0/gcc/objc/objc-next-runtime-abi-02.c-orig 2011-05-11 13:46:44.559065173 -0500
++++ gcc-4.6.0/gcc/objc/objc-next-runtime-abi-02.c      2011-05-11 13:48:34.956939829 -0500
+@@ -1878,7 +1878,7 @@
+ static const char *
+ newabi_append_ro (const char *name)
+ {
+-  char *dollar;
++  const char *dollar;
+   char *p;
+   static char string[BUFSIZE];
+   dollar = strchr (name, '$');
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_cloogstatic2.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_cloogstatic2.patch
new file mode 100644 (file)
index 0000000..afa29d9
--- /dev/null
@@ -0,0 +1,18 @@
+gcc.fix_cloogstatic2
+
+When only static libraries are available (so we can build cc1 without
+depending on extras libraries), we get a bunch of undefined symbols
+that are defined in libpwl. This patch explicitly adds libpwl to the
+linker command.
+
+--- gcc-trunk/configure.orig   2011-03-10 12:48:29.433528020 -0600
++++ gcc-trunk/configure        2011-03-10 12:52:11.342145967 -0600
+@@ -5770,7 +5770,7 @@
+     LDFLAGS="$saved_LDFLAGS"
+   fi
+-  ppllibs="$ppllibs -lppl_c -lppl $pwllib -lgmpxx"
++  ppllibs="$ppllibs -lppl_c -lppl -lpwl $pwllib -lgmpxx"
+   if test "$enable_ppl_version_check" != no; then
+     saved_CFLAGS="$CFLAGS"
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_constvector.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_constvector.patch
new file mode 100644 (file)
index 0000000..c4a2776
--- /dev/null
@@ -0,0 +1,43 @@
+For altivec targets, 32 bits, the spec2k-gap bmk does not build.  The
+reason is that at some point the vectorizer creates an CONST_VECTOR
+rtl, where the elements are SYMBOL_REFs.
+
+Gcc ICE on simplify_immed_subreg, where it checks that CONST_VECTORS
+can be only made of CONST_INT, CONST_DOUBLE, or CONST_FIXED.
+
+I really don't understand what that function does, but since the
+vectorizer will bailout later anyway, I think it is safe to treat
+SYMBOL_REFs as CONST_INT. (NOT for FSF submission, as I really don't
+have a clue)
+
+This problem does not exists on gcc-4.5
+
+This problem does not exists on 64 bits, since there is no altivec
+type that can support 64bit elements.
+
+Here is a simplified test case:
+
+typedef void f_t (void);
+extern f_t f;
+extern f_t *A[12];
+extern f_t *B[12];
+void bad_vector ()
+{                                                                                                                                                    
+  int i;                                                                                                                                             
+                                                                                                                                                     
+  for (i = 0; i < 12; i++ ) {                                                                                                                        
+    A[i] = f;                                                                                                                                        
+    B[i] = f;                                                                                                                                        
+  }                                                                                                                                                  
+}                                                                                                                                                    
+
+--- gcc-4.6.2/gcc/simplify-rtx.c~      2011-12-28 12:28:01.700039002 -0600
++++ gcc-4.6.2/gcc/simplify-rtx.c       2011-12-28 12:38:22.287039002 -0600
+@@ -5001,6 +5001,7 @@
+       switch (GET_CODE (el))
+       {
+       case CONST_INT:
++        case SYMBOL_REF:
+         for (i = 0;
+              i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
+              i += value_bit)
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_header_issue.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_header_issue.patch
new file mode 100644 (file)
index 0000000..e2b9f7f
--- /dev/null
@@ -0,0 +1,12 @@
+--- gcc-4_6-branch/gcc/limitx.h.orig   2012-03-08 01:11:23.024440826 -0600
++++ gcc-4_6-branch/gcc/limitx.h        2012-03-08 01:13:44.372515706 -0600
+@@ -30,6 +30,7 @@
+ #define _GCC_LIMITS_H_
+ #ifndef _LIBC_LIMITS_H_
+-/* Use "..." so that we find syslimits.h only in this same directory.  */
+-#include "syslimits.h"
++#define _GCC_NEXT_LIMITS_H              /* tell gcc's limits.h to recurse */
++#include_next <limits.h>
++#undef _GCC_NEXT_LIMITS_H
+ #endif
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_ira-loop-pressure.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_ira-loop-pressure.patch
new file mode 100644 (file)
index 0000000..86ad32a
--- /dev/null
@@ -0,0 +1,12 @@
+diff -Naur gcc-4.6.2/gcc/config/rs6000/rs6000.c gcc-4.6.2-loop_invariant/gcc/config/rs6000/rs6000.c
+--- gcc-4.6.2/gcc/config/rs6000/rs6000.c       2011-11-24 00:03:49.709144001 -0600
++++ gcc-4.6.2-loop_invariant/gcc/config/rs6000/rs6000.c        2011-12-12 23:49:27.901487730 -0600
+@@ -2723,7 +2723,7 @@
+      calculation works better for RTL loop invariant motion on targets
+      with enough (>= 32) registers.  It is an expensive optimization.
+      So it is on only for peak performance.  */
+-  if (optimize >= 3 && global_init_p)
++  if (optimize >= 3 && global_init_p && !global_options_set.x_flag_ira_loop_pressure)
+     flag_ira_loop_pressure = 1;
+   /* Set the pointer size.  */
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_longversionstring.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_longversionstring.patch
new file mode 100644 (file)
index 0000000..2d7fae7
--- /dev/null
@@ -0,0 +1,16 @@
+gcc.fix_longversionstring
+
+Freescale version string is really long, and it can overflow a
+buffer. This patch extends the size of the buffer.
+
+--- gcc-4.6.0/gcc/dwarf2out.c-orig     2011-03-18 11:22:01.000000000 -0500
++++ gcc-4.6.0/gcc/dwarf2out.c  2011-05-06 10:24:24.114277925 -0500
+@@ -20005,7 +20005,7 @@
+ gen_compile_unit_die (const char *filename)
+ {
+   dw_die_ref die;
+-  char producer[250];
++  char producer[2500];
+   const char *language_string = lang_hooks.name;
+   int language;
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_mingw32.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_mingw32.patch
new file mode 100644 (file)
index 0000000..0d8c00e
--- /dev/null
@@ -0,0 +1,11 @@
+--- gcc-4.6.0/gcc/configure~   2011-02-28 09:36:37.000000000 -0600
++++ gcc-4.6.0/gcc/configure    2011-06-28 10:07:22.430630818 -0500
+@@ -10898,7 +10898,7 @@
+       saved_CFLAGS="${CFLAGS}"
+       CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
+       LDFLAGS="${LDFLAGS_FOR_BUILD}" \
+-      ${realsrcdir}/configure \
++      ${realsrcdir}/configure --with-gnu-ld --with-gnu-as --enable-targets=all \
+               --enable-languages=${enable_languages-all} \
+               --target=$target_alias --host=$build_alias --build=$build_alias
+       CFLAGS="${saved_CFLAGS}"
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.ld_unaligned-460.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.ld_unaligned-460.patch
new file mode 100644 (file)
index 0000000..2eb270e
--- /dev/null
@@ -0,0 +1,32 @@
+gcc.ld_unaligned-460
+
+Optimization:
+Allows a "ld" of an address that is world aligned. There is a penalty
+performance, but it still beats a pair of "lwz".
+
+Index: gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c
+===================================================================
+--- gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c       (revision 137727)
++++ gcc-4.4-e500mc64-20090322/gcc/config/rs6000/rs6000.c       (working copy)
+@@ -10640,7 +10667,9 @@
+       else if (bytes >= 8 && TARGET_POWERPC64
+              /* 64-bit loads and stores require word-aligned
+                 displacements.  */
+-             && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
++             && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)
++                 || rs6000_cpu == PROCESSOR_PPCE5500
++                 || rs6000_cpu == PROCESSOR_PPCE6500))
+       {
+         clear_bytes = 8;
+         mode = DImode;
+@@ -10775,7 +10808,9 @@
+       else if (bytes >= 8 && TARGET_POWERPC64
+              /* 64-bit loads and stores require word-aligned
+                 displacements.  */
+-             && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
++             && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)
++                 || rs6000_cpu == PROCESSOR_PPCE5500
++                 || rs6000_cpu == PROCESSOR_PPCE6500))
+       {
+         move_bytes = 8;
+         mode = DImode;
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.load_on_store_bypass-462.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.load_on_store_bypass-462.patch
new file mode 100644 (file)
index 0000000..a03a7ff
--- /dev/null
@@ -0,0 +1,138 @@
+
+ This patch implements option -fbypass-load-on-store
+
+ A load on store collision causes the load to to be replayed if the store has not completed.
+ Under -fbypass-load-on-store, GCC will attempt to avoid a load on store collision by trying
+ to space the load away from the store by scheduling upto 14 instructions in between, to 
+ prevent the load from executing too early.
+
+ -fbypass-load-on-store is enabled under -fschedule-insns
+
+ Cores supported: e5500, e6500, e500mc
+
+ Ref: Load-on-Store Collision Avoidance by Software Stall of Load. James Yang. May 18, 2010
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/common.opt fsl-gcc-4.6.2-new-bypass/gcc/common.opt
+--- fsl-gcc-4.6.2-sans-bypass/gcc/common.opt   2011-11-29 11:10:18.967872292 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/common.opt    2011-11-29 14:02:46.765994436 -0600
+@@ -840,6 +840,10 @@
+ Common Report Var(flag_btr_bb_exclusive) Optimization
+ Restrict target load migration not to re-use registers in any basic block
++fbypass-load-on-store
++Common Report Var(flag_bypass_load_on_store) Optimization
++Bypass load on store collision
++
+ fcall-saved-
+ Common Joined RejectNegative Var(common_deferred_options) Defer
+ -fcall-saved-<register>       Mark <register> as being preserved across functions
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e500mc64.md fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e500mc64.md
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e500mc64.md    2011-11-29 11:11:38.454868780 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e500mc64.md     2011-11-29 17:10:39.849869060 -0600
+@@ -189,3 +189,5 @@
+   (and (eq_attr "type" "ddiv")
+        (eq_attr "cpu" "ppce500mc64"))
+   "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34")
++
++(define_bypass 15 "e500mc64_store" "e500mc64_load" "rs6000_bypass_load_on_store_collision_p")
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e500mc.md fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e500mc.md
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e500mc.md      2011-11-29 11:11:38.479869032 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e500mc.md       2011-11-29 17:10:27.810997020 -0600
+@@ -198,3 +198,5 @@
+   (and (eq_attr "type" "ddiv")
+        (eq_attr "cpu" "ppce500mc"))
+   "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65")
++
++(define_bypass 15 "e500mc_store" "e500mc_load" "rs6000_bypass_load_on_store_collision_p")
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e5500.md fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e5500.md
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e5500.md       2011-11-29 11:11:38.321744639 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e5500.md        2011-11-29 17:10:47.255997293 -0600
+@@ -174,3 +174,5 @@
+   (and (eq_attr "type" "cr_logical,delayed_cr")
+        (eq_attr "cpu" "ppce5500"))
+   "e5500_decode,e5500_bu")
++
++(define_bypass 15 "e5500_store" "e5500_load" "rs6000_bypass_load_on_store_collision_p")
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e6500.md fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e6500.md
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/e6500.md       2011-11-29 11:11:37.831996567 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/e6500.md        2011-11-29 17:11:00.902869709 -0600
+@@ -211,3 +211,5 @@
+   (and (eq_attr "type" "vecperm")
+        (eq_attr "cpu" "ppce6500"))
+   "e6500_decode,e6500_vecperm")
++
++(define_bypass 15 "e6500_store" "e6500_load" "rs6000_bypass_load_on_store_collision_p")
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/rs6000.c fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/rs6000.c
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/rs6000.c       2011-11-29 11:11:38.393748363 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/rs6000.c        2011-11-29 17:10:15.740745470 -0600
+@@ -28719,3 +28719,20 @@
+ #include "gt-rs6000.h"
++
++bool
++rs6000_bypass_load_on_store_collision_p (rtx out_insn, rtx in_insn)
++{
++  /* The out_insn is a store and the in_insn is a load */
++  if (flag_bypass_load_on_store &&
++      (GET_CODE (PATTERN (out_insn)) == SET &&
++       GET_CODE (SET_DEST (PATTERN (out_insn))) == MEM &&
++       GET_CODE (SET_SRC (PATTERN (out_insn))) == REG) &&
++      (GET_CODE (PATTERN (in_insn)) == SET &&
++       GET_CODE (SET_DEST (PATTERN (in_insn))) == REG &&
++       GET_CODE (SET_SRC (PATTERN (in_insn))) == MEM))
++    return rtx_equal_p (SET_DEST (PATTERN (out_insn)),
++                        SET_SRC  (PATTERN (in_insn)));
++  else
++    return false;
++}
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/rs6000-protos.h fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/rs6000-protos.h
+--- fsl-gcc-4.6.2-sans-bypass/gcc/config/rs6000/rs6000-protos.h        2011-11-29 11:11:37.783996630 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/config/rs6000/rs6000-protos.h 2011-11-29 17:42:51.443119385 -0600
+@@ -174,6 +174,8 @@
+ extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
++extern bool rs6000_bypass_load_on_store_collision_p (rtx out_insn, rtx in_insn);
++
+ /* Declare functions in rs6000-c.c */
+ extern void rs6000_pragma_longcall (struct cpp_reader *);
+diff -ruN fsl-gcc-4.6.2-sans-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c fsl-gcc-4.6.2-new-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c
+--- fsl-gcc-4.6.2-sans-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c  1969-12-31 18:00:00.000000000 -0600
++++ fsl-gcc-4.6.2-new-bypass/gcc/testsuite/gcc.target/powerpc/bypass-load-on-store.c   2011-11-30 16:36:55.168869498 -0600
+@@ -0,0 +1,34 @@
++/* { dg-do compile { target { powerpc*-*-* } } } */
++/* { dg-options "-O0 -fschedule-insns -fbypass-load-on-store -fdump-rtl-sched1 -fsched-verbose=2" } */
++
++void nescaf(void)
++{
++      long a, b, c, d,
++             e, f, g, h,
++           i, j, k, l,
++             m, n, o, p,
++             q, r, s, t,
++
++           z, w;
++
++      a = 41; b = 79; c = 20; d = 11;
++      e = 13; f = 43; g = 13; h = 21;
++      i = 12; j = 45; k = 55; l = 90;
++      m = 23; n = 61; o = 89; p = 53;
++      q = 83; r = 52; s = 76; t = 99;
++
++      /* Now, we have a store followed by a load. The assignments to a-t are
++       * all independent of the store-load computation below. The question is:
++       * Under -fschedule-insns -fbypass-load-on-store, are 14 of the above
++       * instructions moved between the store-load?
++       */
++      z = 121;
++      w = z;
++}
++
++/* Note: There is going to be exactly one insn that will be assigned cost 15.
++ *       Since its insn-number will likely change, we do not include the insn
++ *       number in the scan - just the part of the dump that'll be invariant.
++ */
++/* { dg-final { scan-rtl-dump "into queue with cost=15" "sched1" { target powerpc*-*-* } } } */
++/* { dg-final { cleanup-rtl-dump "sched1" } } */
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.local_unaligned_altivec.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.local_unaligned_altivec.patch
new file mode 100644 (file)
index 0000000..feee54a
--- /dev/null
@@ -0,0 +1,18 @@
+gcc.local_unaligned_altivec
+
+Optimization:
+On Altivec targets, make all char arrays 128 bits aligned (instead of
+32 bits aligned)
+
+--- gcc-4.5.0/gcc/config/rs6000/rs6000.h-orig  2010-10-20 10:23:52.000000000 -0500
++++ gcc-4.5.0/gcc/config/rs6000/rs6000.h       2010-10-20 10:39:14.000000000 -0500
+@@ -768,7 +768,8 @@
+       ? 64                                                            \
+       : (TREE_CODE (TYPE) == ARRAY_TYPE                                       \
+        && TYPE_MODE (TREE_TYPE (TYPE)) == QImode                      \
+-       && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN)))
++       && (ALIGN) < (TARGET_ALTIVEC ? 128 : BITS_PER_WORD))           \
++            ? (TARGET_ALTIVEC ? 128 : BITS_PER_WORD) : (ALIGN)))
+ /* Nonzero if move instructions will actually fail to work
+    when given unaligned data.  */
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.opt-array-offset.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.opt-array-offset.patch
new file mode 100644 (file)
index 0000000..7cdc6f7
--- /dev/null
@@ -0,0 +1,350 @@
+Implements a GIMPLE pass to optimize array access by factoring
+out expressions that calculate address offset from
+multiple array access. Controls with flag -fopt-array-offset
+diff -ruN XLMe500mc/gcc/common.opt XLMe5500/gcc/common.opt
+--- XLMe500mc/gcc/common.opt   2011-10-18 14:49:23.026644000 -0500
++++ XLMe5500/gcc/common.opt    2011-10-05 12:39:26.242644101 -0500
+@@ -1992,6 +1992,10 @@
+ Common Report Var(flag_tree_vrp) Init(0) Optimization
+ Perform Value Range Propagation on trees
++fopt-array-offset
++Common Report Var(flag_opt_array_offset)
++Expand array offset address calculations
++
+ funit-at-a-time
+ Common Report Var(flag_unit_at_a_time) Init(1) Optimization
+ Compile whole compilation unit at a time
+diff -ruN XLMe500mc/gcc/Makefile.in XLMe5500/gcc/Makefile.in
+--- XLMe500mc/gcc/Makefile.in  2011-10-18 14:49:23.028644000 -0500
++++ XLMe5500/gcc/Makefile.in   2011-10-05 12:08:28.104643898 -0500
+@@ -1306,6 +1306,7 @@
+       omp-low.o \
+       optabs.o \
+       options.o \
++      opt-array-offset.o \
+       opts-common.o \
+       opts-global.o \
+       opts.o \
+@@ -2629,7 +2630,10 @@
+    $(FLAGS_H) $(CGRAPH_H) $(PLUGIN_H) \
+    $(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) \
+    $(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H) $(REGSET_H)
+-
++opt-array-offset.o : opt-array-offset.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
++   $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_FLOW_H) $(TIMEVAR_H) \
++   $(TREE_PASS_H) alloc-pool.h $(BASIC_BLOCK_H) $(TARGET_H) \
++   $(DIAGNOSTIC_H) gimple-pretty-print.h tree-pretty-print.h
+ widen-types.o : widen-types.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
+    $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
+    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
+diff -ruN XLMe500mc/gcc/opt-array-offset.c XLMe5500/gcc/opt-array-offset.c
+--- XLMe500mc/gcc/opt-array-offset.c   1969-12-31 18:00:00.000000000 -0600
++++ XLMe5500/gcc/opt-array-offset.c    2011-11-01 15:24:21.746039000 -0500
+@@ -0,0 +1,283 @@
++/* Optimizing array element access
++   Copyright (C) 2011
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it
++under the terms of the GNU General Public License as published by the
++Free Software Foundation; either version 3, or (at your option) any
++later version.
++
++GCC is distributed in the hope that it will be useful, but WITHOUT
++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++
++/* This is a GIMPLE pass over basic block which coverts the stmts:
++        
++        a = b +/- c1;
++      c = a * c2;
++        
++   to:
++   
++        a = b * c2;
++        c = a +/- c1 * c2;
++
++   in effect expanding the multiplication across addition/substraction.
++
++   Motivating example:
++   Consider the following simple integer array access:
++   
++        a[i] = c;
++        a[i + 1] = c;
++
++   The following GIMPLE equivalent will be generated:
++
++        off_1 = i * 4;
++        a_i = a + off_1;
++      *a_i = c;
++
++      off_1 = i + 1;
++      off_2 = off_1 * 4;
++      a_i1 = a + off_2;
++      *a_i1 = c;
++
++   Notice that a_i1 could simply be a_i + 4. But the calcuation of i+1
++   is preventing CSE to perform. This pass will essentially convert the
++   second expr into:
++
++        off_1 = i * 4;
++        off_2 = off_1 + 4;
++        a_i1 = a + off_2;
++        ....
++
++   Thus allowing the previous index i calculation to be reuse. off_1 + 4
++   would also be combined into a_i if offset addressing mode is available.
++   This also have side effect of avoiding redundant sign extension on
++   i+1 for LP64 model where native integer size is different from pointer size.
++
++   The algorithm iterates through all the basic blocks looking for
++   the above pattern. Care is taken to make sure off_1 only
++   has the single use otherwise the transformation cannot be perform.
++*/
++
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "flags.h"
++#include "tree.h"
++#include "tree-flow.h"
++#include "timevar.h"
++#include "tree-pass.h"
++#include "alloc-pool.h"
++#include "basic-block.h"
++#include "target.h"
++#include "gimple-pretty-print.h"
++#include "tree-pretty-print.h"
++
++
++/*
++  We are looking for:
++  a = b +/- c1
++  c = a * c2 (stmt incoming)
++  d = &arr + c
++*/
++static bool
++is_candidate (gimple stmt)
++{
++  tree mul_result = gimple_get_lhs (stmt);
++  tree rhs1, rhs2;
++  gimple rhs1_stmt, use_stmt;
++  use_operand_p use_p;
++  imm_use_iterator imm_iter;
++
++  /* check for a * c2 */
++  if (gimple_assign_rhs_code (stmt) != MULT_EXPR)
++    return false;
++
++  rhs1 = gimple_assign_rhs1 (stmt);
++  rhs2 = gimple_assign_rhs2 (stmt);
++
++  if (TREE_CODE (rhs2) != INTEGER_CST)
++    return false;
++  
++  /* check for b + c1 */
++  if (TREE_CODE (rhs1) == SSA_NAME)
++    {
++      rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
++      if (is_gimple_assign (rhs1_stmt))
++      {
++        tree rhs1_2;
++        tree plusminus_result;
++
++        if (gimple_assign_rhs_code (rhs1_stmt) != PLUS_EXPR
++            && gimple_assign_rhs_code (rhs1_stmt) != MINUS_EXPR)
++          return false;
++
++        rhs1_2 = gimple_assign_rhs2 (rhs1_stmt);
++        if (TREE_CODE (rhs1_2) != INTEGER_CST)
++          return false;
++
++        /* make sure there are no other uses of a 
++           e.g. if a is used as an indcution variable 
++           we cannot modified it
++        */
++        plusminus_result = gimple_get_lhs (rhs1_stmt);
++        FOR_EACH_IMM_USE_FAST (use_p, imm_iter, plusminus_result)
++          {
++            use_stmt = USE_STMT (use_p);
++            
++            /* ignore PHI node */
++            if (is_gimple_assign (use_stmt) &&
++                (gimple_assign_rhs_code (use_stmt) == GIMPLE_PHI))
++              continue;
++            if (use_stmt != stmt)
++              return false;
++          }
++
++#if 0
++        if (gimple_bb(rhs1_stmt) != gimple_bb(stmt))
++          return false;
++#endif
++        }
++      else
++      return false;
++    }
++  else
++    return false;
++
++  /* now look for uses of c that is a pointer use */
++  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
++    {
++      enum tree_code use_code;
++
++      use_stmt = USE_STMT (use_p);
++      
++      if (is_gimple_debug (use_stmt))
++      continue;
++      
++      if (gimple_bb (use_stmt) != gimple_bb (stmt))
++      return false;
++
++      if (!is_gimple_assign (use_stmt))
++      return false;
++
++      use_code = gimple_assign_rhs_code (use_stmt);
++      if (use_code != POINTER_PLUS_EXPR)
++      return false;
++    }
++
++  if (dump_file)
++    {
++      fprintf (dump_file, "Found candidate:\n");
++      print_gimple_stmt (dump_file, rhs1_stmt, 0, TDF_SLIM);
++      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
++      print_gimple_stmt (dump_file, use_stmt, 0, TDF_SLIM);
++    }
++
++  return true;
++}
++
++/* Do the actual transformation:
++  a = b + c1 ==> a = b * c2
++  c = a * c2 ==> c = a + c1*c2
++*/
++static bool
++expand_plusminus_mult (gimple stmt)
++{
++  tree c1, c2, mul_result;
++  gimple rhs1_stmt;
++
++  /* get c2 */
++  c2 = gimple_assign_rhs2 (stmt);
++
++  /* get c1 */
++  rhs1_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
++  c1 = gimple_assign_rhs2 (rhs1_stmt);
++
++  /* form c1 * c2 */
++  mul_result = double_int_to_tree (TREE_TYPE(c2), double_int_mul 
++                    (tree_to_double_int (c1), tree_to_double_int (c2)));
++
++  /* a = b + c1 ==> a = b * c2 */
++  gimple_assign_set_rhs2 (rhs1_stmt, c2);
++  gimple_assign_set_rhs_code (rhs1_stmt, MULT_EXPR);
++  update_stmt (rhs1_stmt);
++
++  /* c = a * c2 ==> c = a + c1*c2 */
++  gimple_assign_set_rhs2 (stmt, mul_result);
++  /* MINUS_EXPR has already been embedded into c1*c2 */
++  gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
++  update_stmt (stmt);
++
++  return true;
++}
++
++
++static unsigned int
++execute_opt_array_offset (void)
++{
++  basic_block bb;
++  tree fndecl;
++
++  FOR_EACH_BB (bb)
++    {
++      gimple_stmt_iterator gsi;
++
++      for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next(&gsi))
++      {
++        gimple stmt = gsi_stmt (gsi);
++      tree lhs,rhs1,rhs2,rhs3;
++        enum tree_code code;
++        
++        /* only interested in assign statement */
++        if (is_gimple_assign (stmt))
++        {
++         /* find stmts calculating array offset */
++        if (is_candidate (stmt))
++          /* convert stmt */
++          expand_plusminus_mult(stmt);
++          
++        }
++      }
++    }
++
++  return 0;
++}
++
++static bool
++gate_opt_array_offset (void)
++{
++  return flag_opt_array_offset && optimize;
++}
++
++struct gimple_opt_pass pass_opt_array_offset =
++{
++ {
++  GIMPLE_PASS,
++  "opt_array_offset",                 /* name */
++  gate_opt_array_offset,              /* gate */
++  execute_opt_array_offset,           /* execute */
++  NULL,                                       /* sub */
++  NULL,                                       /* next */
++  0,                                  /* static_pass_number */
++  TV_NONE,                            /* tv_id */
++  PROP_ssa,                           /* properties_required */
++  0,                                  /* properties_provided */
++  0,                                  /* properties_destroyed */
++  0,                                  /* todo_flags_start */
++  TODO_verify_ssa
++  | TODO_verify_stmts
++  | TODO_update_ssa
++  | TODO_dump_func                      /* todo_flags_finish */
++ }
++};
++
+diff -ruN XLMe500mc/gcc/passes.c XLMe5500/gcc/passes.c
+--- XLMe500mc/gcc/passes.c     2011-10-18 14:49:23.029644000 -0500
++++ XLMe5500/gcc/passes.c      2011-10-05 11:19:01.168644127 -0500
+@@ -937,6 +937,7 @@
+       NEXT_PASS (pass_phiopt);
+       NEXT_PASS (pass_fold_builtins);
+       NEXT_PASS (pass_optimize_widening_mul);
++      NEXT_PASS (pass_opt_array_offset);
+       NEXT_PASS (pass_tail_calls);
+       NEXT_PASS (pass_rename_ssa_copies);
+       NEXT_PASS (pass_uncprop);
+diff -ruN XLMe500mc/gcc/tree-pass.h XLMe5500/gcc/tree-pass.h
+--- XLMe500mc/gcc/tree-pass.h  2011-10-18 14:49:23.029644000 -0500
++++ XLMe5500/gcc/tree-pass.h   2011-10-05 11:19:59.665643705 -0500
+@@ -421,6 +421,7 @@
+ extern struct gimple_opt_pass pass_cse_sincos;
+ extern struct gimple_opt_pass pass_optimize_bswap;
+ extern struct gimple_opt_pass pass_optimize_widening_mul;
++extern struct gimple_opt_pass pass_opt_array_offset;
+ extern struct gimple_opt_pass pass_warn_function_return;
+ extern struct gimple_opt_pass pass_warn_function_noreturn;
+ extern struct gimple_opt_pass pass_cselim;
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.remove_CCUNSmode_reference.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.remove_CCUNSmode_reference.patch
new file mode 100644 (file)
index 0000000..03e3ce9
--- /dev/null
@@ -0,0 +1,24 @@
+--- gcc-4_6-branch/gcc/extelim.c.orig  2012-03-05 21:42:53.984215949 -0600
++++ gcc-4_6-branch/gcc/extelim.c       2012-03-05 21:43:27.884394659 -0600
+@@ -922,8 +922,7 @@
+       && GET_MODE (exp) != HImode
+       && GET_MODE (exp) != SImode 
+       && GET_MODE (exp) != DImode
+-      && GET_MODE (exp) != CCmode
+-      && GET_MODE (exp) != CCUNSmode)
++      && GET_MODE (exp) != CCmode)
+     return false;
+   return true;
+@@ -1653,9 +1652,9 @@
+      For our targets, there is no 'cmph' insn, so we bail out 
+      if we see a comparison of sizes less than a word (SI). */
+   if (REG_P (dest)
+-      && (GET_MODE (dest) == CCmode || GET_MODE (dest) == CCUNSmode)
++      && (GET_MODE (dest) == CCmode)
+       && GET_CODE (src) == COMPARE
+-      && (GET_MODE (src) == CCmode || GET_MODE (src) == CCUNSmode))
++      && (GET_MODE (src) == CCmode))
+     {
+       rtx compare_op0 = XEXP (src, 0);
+       rtx compare_op1 = XEXP (src, 1);
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.rm_slow_tests.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.rm_slow_tests.patch
new file mode 100644 (file)
index 0000000..b02b755
--- /dev/null
@@ -0,0 +1,67 @@
+diff -urN gcc-4.6.0/gcc/testsuite/gfortran.dg/cray_pointers_8.f90 gcc-4.6.0-fixed/gcc/testsuite/gfortran.dg/cray_pointers_8.f90
+--- gcc-4.6.0/gcc/testsuite/gfortran.dg/cray_pointers_8.f90    2009-02-13 15:12:34.000000000 -0600
++++ gcc-4.6.0-fixed/gcc/testsuite/gfortran.dg/cray_pointers_8.f90      1969-12-31 18:00:00.000000000 -0600
+@@ -1,63 +0,0 @@
+-! { dg-do run }
+-! { dg-options "-fcray-pointer" }
+-!
+-! Test the fix for PR36528 in which the Cray pointer was not passed
+-! correctly to 'euler' so that an undefined reference to fcn was
+-! generated by the linker.
+-!
+-! Reported by Tobias Burnus  <burnus@gcc.gnu.org>
+-! from http://groups.google.com/group/comp.lang.fortran/msg/86b65bad78e6af78
+-!
+-real function p1(x)
+-  real, intent(in) :: x
+-  p1 = x
+-end
+-
+-real function euler(xp,xk,dx,f)
+-  real, intent(in) :: xp, xk, dx
+-  interface
+-    real function f(x)
+-      real, intent(in) :: x
+-    end function
+-  end interface
+-  real x, y
+-  y = 0.0
+-  x = xp
+-  do while (x .le. xk)
+-    y = y + f(x)*dx
+-    x = x + dx
+-  end do
+-  euler = y
+-end
+-program main
+-  interface
+-    real function p1 (x)
+-      real, intent(in) :: x
+-    end function
+-    real function fcn (x)
+-      real, intent(in) :: x
+-    end function
+-    real function euler (xp,xk,dx,f)
+-      real, intent(in) :: xp, xk ,dx
+-      interface
+-        real function f(x)
+-          real, intent(in) :: x
+-        end function
+-      end interface
+-    end function
+-  end interface
+-  real x, xp, xk, dx, y, z
+-  pointer (pfcn, fcn)
+-  pfcn = loc(p1)
+-  xp = 0.0
+-  xk = 1.0
+-  dx = 0.0005
+-  y = 0.0
+-  x = xp
+-  do while (x .le. xk)
+-    y = y + fcn(x)*dx
+-    x = x + dx
+-  end do
+-  z = euler(0.0,1.0,0.0005,fcn)
+-  if (abs (y - z) .gt. 1e-6) call abort
+-end
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.soft_float-460.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.soft_float-460.patch
new file mode 100644 (file)
index 0000000..eafa6ab
--- /dev/null
@@ -0,0 +1,190 @@
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_data_map_rand.cc   2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_data_map_rand.cc        2011-05-11 20:03:39.000000000 -0500
+@@ -46,17 +46,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_no_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_no_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_no_data_map_rand.cc        2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/hash_no_data_map_rand.cc     2011-05-11 20:04:00.000000000 -0500
+@@ -46,17 +46,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_data_map_rand.cc    2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_data_map_rand.cc 2011-05-11 20:02:23.000000000 -0500
+@@ -47,7 +47,7 @@
+   using namespace __gnu_pbds::test;
+   typedef lu_map_tl_t map_tl_t;
+-  return rand_regression_test(50, 10, 
++  return rand_regression_test(2, 5, 
+                             "lu_data_map_rand_regression_test",
+                             map_tl_t());
+ }
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_no_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_no_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_no_data_map_rand.cc 2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/list_update_no_data_map_rand.cc      2011-05-11 20:02:23.000000000 -0500
+@@ -47,7 +47,7 @@
+   using namespace __gnu_pbds::test;
+   typedef lu_set_tl_t map_tl_t;
+-  return rand_regression_test(50, 10,
++  return rand_regression_test(2, 5,
+                             "lu_no_data_map_rand_regression_test",
+                             map_tl_t());
+ }
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc  2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/priority_queue_rand.cc       2011-05-11 20:02:23.000000000 -0500
+@@ -45,10 +45,10 @@
+ #include <regression/common_type.hpp>
+ #ifndef ITERATIONS
+-#define ITERATIONS 5000
++#define ITERATIONS 2
+ #endif
+ #ifndef KEYS
+-#define KEYS 10000
++#define KEYS 5
+ #endif
+ int
+ main(int argc, char* a_p_argv[])
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc   2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc        2011-05-11 20:04:21.000000000 -0500
+@@ -46,17 +46,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_no_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_no_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_no_data_map_rand.cc        2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_no_data_map_rand.cc     2011-05-11 20:04:41.000000000 -0500
+@@ -47,17 +47,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_data_map_rand.cc   2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_data_map_rand.cc        2011-05-11 20:05:34.000000000 -0500
+@@ -46,17 +46,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
+diff -u gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_no_data_map_rand.cc gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_no_data_map_rand.cc
+--- gcc-4.6.0-orig/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_no_data_map_rand.cc        2011-05-11 20:01:58.000000000 -0500
++++ gcc-4.6.0/libstdc++-v3/testsuite/ext/pb_ds/regression/trie_no_data_map_rand.cc     2011-05-11 20:05:50.000000000 -0500
+@@ -46,17 +46,17 @@
+ #ifndef ITERATIONS
+ # ifdef _GLIBCXX_DEBUG
+-#  define ITERATIONS 100
++#  define ITERATIONS 2
+ # else
+-#  define ITERATIONS 5000
++#  define ITERATIONS 2
+ #endif
+ #endif
+ #ifndef KEYS
+ # ifdef _GLIBCXX_DEBUG
+-#  define KEYS 200
++#  define KEYS 5
+ # else
+-#  define KEYS 10000
++#  define KEYS 5
+ # endif
+ #endif
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.widen_types-46.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.widen_types-46.patch
new file mode 100644 (file)
index 0000000..0590560
--- /dev/null
@@ -0,0 +1,1534 @@
+diff -ruN gcc-4.6.0-orig/gcc/common.opt gcc-4.6.0-new/gcc/common.opt
+--- gcc-4.6.0-orig/gcc/common.opt      2011-03-05 18:38:13.000000000 -0600
++++ gcc-4.6.0-new/gcc/common.opt       2011-08-25 13:16:36.408937475 -0500
+@@ -1797,6 +1797,10 @@
+ Common Report Var(flag_strict_overflow)
+ Treat signed overflow as undefined
++fwiden-types
++Common Report Var(flag_widen_types)
++Widen signed integral variables (local, whose address has not been taken, non-volatile and having precision less than that of long) to long (retaining original qualifiers)
++
+ fsyntax-only
+ Common Report Var(flag_syntax_only)
+ Check for syntax errors, then stop
+diff -ruN gcc-4.6.0-orig/gcc/Makefile.in gcc-4.6.0-new/gcc/Makefile.in
+--- gcc-4.6.0-orig/gcc/Makefile.in     2011-01-25 22:19:58.000000000 -0600
++++ gcc-4.6.0-new/gcc/Makefile.in      2011-08-25 13:16:36.411937390 -0500
+@@ -1245,6 +1245,7 @@
+       gimple-fold.o \
+       gimple-low.o \
+       gimple-pretty-print.o \
++      widen-types.o \
+       gimplify.o \
+       godump.o \
+       graph.o \
+@@ -2628,6 +2629,12 @@
+    $(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) \
+    $(TREE_PASS_H) $(CFGLOOP_H) $(EXCEPT_H) $(REGSET_H)
++widen-types.o : widen-types.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
++   $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
++   $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
++   coretypes.h $(EXCEPT_H) $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
++   $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(OPTABS_H) \
++   $(SPLAY_TREE_H) $(VEC_H) tree-iterator.h tree-pass.h tree-pretty-print.h
+ gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
+    $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h \
+    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
+@@ -3733,6 +3740,7 @@
+   $(srcdir)/tree-cfg.c \
+   $(srcdir)/tree-dfa.c \
+   $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
++  $(srcdir)/widen-types.c \
+   $(srcdir)/tree-chrec.h \
+   $(srcdir)/tree-scalar-evolution.c \
+   $(srcdir)/tree-ssa-operands.h \
+diff -ruN gcc-4.6.0-orig/gcc/passes.c gcc-4.6.0-new/gcc/passes.c
+--- gcc-4.6.0-orig/gcc/passes.c        2011-02-17 10:18:24.000000000 -0600
++++ gcc-4.6.0-new/gcc/passes.c 2011-08-25 13:16:36.413937342 -0500
+@@ -719,6 +719,7 @@
+     backend might produce already lowered functions that are not processed
+     by these passes.  */
+   p = &all_lowering_passes;
++  NEXT_PASS (pass_widen_types_stmts);
+   NEXT_PASS (pass_warn_unused_result);
+   NEXT_PASS (pass_diagnose_omp_blocks);
+   NEXT_PASS (pass_mudflap_1);
+@@ -741,6 +742,7 @@
+       NEXT_PASS (pass_fixup_cfg);
+       NEXT_PASS (pass_init_datastructures);
+       NEXT_PASS (pass_expand_omp);
++      NEXT_PASS (pass_widen_types_bbs);
+       NEXT_PASS (pass_referenced_vars);
+       NEXT_PASS (pass_build_ssa);
+diff -ruN gcc-4.6.0-orig/gcc/tree-pass.h gcc-4.6.0-new/gcc/tree-pass.h
+--- gcc-4.6.0-orig/gcc/tree-pass.h     2011-02-01 09:12:26.000000000 -0600
++++ gcc-4.6.0-new/gcc/tree-pass.h      2011-08-25 13:16:36.406937543 -0500
+@@ -349,6 +349,7 @@
+ extern void tree_lowering_passes (tree decl);
++extern struct gimple_opt_pass pass_widen_types_stmts;
+ extern struct gimple_opt_pass pass_mudflap_1;
+ extern struct gimple_opt_pass pass_mudflap_2;
+ extern struct gimple_opt_pass pass_lower_cf;
+@@ -409,6 +410,7 @@
+ extern struct gimple_opt_pass pass_lower_omp;
+ extern struct gimple_opt_pass pass_diagnose_omp_blocks;
+ extern struct gimple_opt_pass pass_expand_omp;
++extern struct gimple_opt_pass pass_widen_types_bbs;
+ extern struct gimple_opt_pass pass_expand_omp_ssa;
+ extern struct gimple_opt_pass pass_object_sizes;
+ extern struct gimple_opt_pass pass_fold_builtins;
+diff -ruN gcc-4.6.0-orig/gcc/widen-types.c gcc-4.6.0-new/gcc/widen-types.c
+--- gcc-4.6.0-orig/gcc/widen-types.c   1969-12-31 18:00:00.000000000 -0600
++++ gcc-4.6.0-new/gcc/widen-types.c    2011-08-25 17:27:31.372937392 -0500
+@@ -0,0 +1,1446 @@
++/*
++ Type Widening:
++  
++ Locals and temporaries having signed integral types, whose address has
++ not been taken, are not volatile qualified, and having type precision
++ less than that of type long are widened to type long (with any other
++ qualifiers retained).
++ 
++   Copyright (C) 2011
++   Free Software Foundation, Inc.
++
++This file is part of GCC.
++
++GCC is free software; you can redistribute it and/or modify it under
++the terms of the GNU General Public License as published by the Free
++Software Foundation; either version 3, or (at your option) any later
++version.
++
++GCC is distributed in the hope that it will be useful, but WITHOUT ANY
++WARRANTY; without even the implied warranty of MERCHANTABILITY or
++FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
++for more details.
++
++You should have received a copy of the GNU General Public License
++along with GCC; see the file COPYING3.  If not see
++<http://www.gnu.org/licenses/>.  */
++
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "tree.h"
++#include "tm_p.h"
++#include "gimple.h"
++#include "basic-block.h"
++#include "tree-iterator.h"
++#include "tree-inline.h"
++#include "langhooks.h"
++#include "tree-pretty-print.h"
++#include "gimple-pretty-print.h"
++#include "langhooks.h"
++#include "tree-flow.h"
++#include "cgraph.h"
++#include "timevar.h"
++#include "hashtab.h"
++#include "flags.h"
++#include "function.h"
++#include "output.h"
++#include "ggc.h"
++#include "tree-dump.h"
++#include "tree-pass.h"
++#include "diagnostic-core.h"
++#include "target.h"
++#include "pointer-set.h"
++#include "splay-tree.h"
++#include "vec.h"
++#include "gimple.h"
++#include "tree-pass.h"
++
++#include "langhooks-def.h"
++#include "expr.h"
++
++#include "except.h"
++#include "value-prof.h"
++#include "pointer-set.h"
++
++/* define TW_FINALIZE_STMTS to 1, if you want to run the widening
++ * pass just after gimplification - over the sequence of statements.
++ */
++#define TW_FINALIZE_STMTS 1
++
++#define TW_DEBUG 0
++#if TW_DEBUG
++
++#define TWDBG_STMT(stmt) fprintf (stderr, "%s: ", __FUNCTION__); \
++                         debug_gimple_stmt (stmt);
++
++#define TWDBG_TREE(tree)            \
++{                                   \
++  fprintf (stderr, "%s:\n", #tree); \
++  debug_tree (tree);                \
++  fprintf (stderr, "\n");           \
++}
++
++#define TWDBG_MSG(fmt) \
++fprintf (stderr, "%s: ", __FUNCTION__); \
++fprintf (stderr, fmt)
++
++#define TWDBG_MSG1(fmt, msg) \
++fprintf (stderr, "%s: ", __FUNCTION__); \
++fprintf (stderr, fmt, msg)
++
++#else
++#define TWDBG_STMT(stmt)
++#define TWDBG_TREE(tree)
++#define TWDBG_MSG(fmt)
++#define TWDBG_MSG1(fmt, msg)
++#endif
++
++#if TW_DEBUG
++static void tw_dump_candidate_list (void);
++static bool tw_debug_candidate (const void *t, void **candidacy, void *data);
++#endif
++static void tw_init (void);
++static void tw_reset (void);
++static long tw_candidate (tree node);
++static long tw_candidate_const (tree node);
++static long *tw_log_candidate (tree node);
++static long tw_candidacy_valid (tree node);
++static void tw_candidacy (tree node, long value);
++static long tw_in_candidate_list (tree node);
++static tree tw_widen_constant (tree node);
++static tree tw_widen_variable (tree node);
++#ifdef TW_FINALIZE_STMTS
++static long tw_fn_has_openmp (gimple_seq stmts);
++#endif
++static void tw_log_parms (tree fndecl);
++#ifdef TW_FINALIZE_STMTS
++static void tw_log_vars (gimple_seq stmts);
++#endif
++static void tw_log_local_decls (void);
++#ifdef TW_FINALIZE_STMTS
++static unsigned int tw_finalize_stmts (void);
++#endif
++static unsigned int tw_finalize_bbs (void);
++static long tw_gimple_in_seq (gimple_seq stmts, long widen);
++static long tw_gimple_in_bb (basic_block bb, long widen);
++static long tw_switch (gimple stmt, long widen);
++static long tw_gimple_stmt (gimple stmt, long widen);
++static long tw_gimple_assign (gimple stmt, long widen);
++static long tw_gimple_assign_single (gimple stmt, long widen);
++static long tw_gimple_assign_unary (gimple stmt, long widen);
++static long tw_gimple_assign_binary (gimple stmt, long widen);
++static long tw_gimple_assign_ternary (gimple stmt, long widen);
++static bool is_formatted_IO_fn (tree decl);
++static long tw_gimple_call (gimple stmt, long widen);
++static long tw_gimple_comparison (gimple stmt, long widen);
++static long tw_gimple_switch (gimple stmt, long widen);
++static long tw_gimple_return (gimple stmt, long widen);
++static long tw_gimple_asm (gimple stmt, long widen);
++static long tw_gimple_debug (gimple stmt, long widen);
++
++static struct pointer_map_t *tw_candidate_list;
++
++#if TW_DEBUG
++static void
++tw_dump_candidate_list (void)
++{
++  TWDBG_MSG ("Dumping candidate list:\n"); 
++  pointer_map_traverse (tw_candidate_list, tw_debug_candidate, NULL);
++  TWDBG_MSG ("Done dumping candidate list\n"); 
++}
++
++static
++bool tw_debug_candidate (const void *t, void **candidacy, void *data)
++{
++  debug_tree (t);
++  fprintf(stderr, "candidacy: %ld\n data (ignore): %p", *((long *) candidacy), data);
++  return true;
++}
++#endif
++
++static void
++tw_init (void)
++{
++  gcc_assert (tw_candidate_list == NULL);
++  tw_candidate_list = pointer_map_create ();
++}
++
++static void
++tw_reset (void)
++{
++  if (tw_candidate_list)
++    {
++      pointer_map_destroy (tw_candidate_list);
++      tw_candidate_list = NULL;
++    }
++}
++
++/* gcc.dg/torture/pr43879_[12].c
++ * Initialized statics should not be widened:
++ *
++ * void bar(int c)
++ * {
++ *  static int x = 1; // if widened, x gets initialized to (2^32)
++ *  if (c != x) __builtin_abort();
++ *   x--;
++ * }
++ *
++ *  int main()
++ *  {
++ *   int c = 1;
++ *   bar (1);
++ *   return 0;
++ *  }
++ *
++ * Likely, the initial value is laid out/translated to RTL way before
++ * the rest of the code is translated to GIMPLE; so when we widen the
++ * type, it's already too late.
++ */
++
++/* tw_candidate() has no way to tell if it was passed a local variable
++ * (or not) - so make sure it is passed local variables or parameters only.
++ */
++static long
++tw_candidate (tree node)
++{
++  long rv = 0;
++
++  if (!node || TREE_TYPE (node) == error_mark_node)
++    return 0;
++
++  if (node && TREE_TYPE (node) != error_mark_node &&
++      ((TREE_CODE (node) == VAR_DECL &&
++        /* See note: Initialized statics should not be widened. */
++        (!TREE_STATIC (node) || !DECL_INITIAL (node))) ||
++       TREE_CODE (node) == PARM_DECL ||
++       TREE_CODE (node) == DEBUG_EXPR_DECL) &&
++      !TYPE_VOLATILE (TREE_TYPE (node)) &&
++      !TREE_ADDRESSABLE (node) &&
++      !POINTER_TYPE_P (TREE_TYPE (node)) &&
++      INTEGRAL_TYPE_P (TREE_TYPE (node)) &&
++      !TYPE_UNSIGNED (TREE_TYPE (node))  &&
++      (TYPE_PRECISION (TREE_TYPE (node)) < TYPE_PRECISION (long_integer_type_node)))
++    rv = 1;
++  return rv;
++}
++
++static long
++tw_candidate_const (tree node)
++{
++  long rv = 0;
++
++  if (node && TREE_TYPE (node) != error_mark_node &&
++      INTEGRAL_TYPE_P (TREE_TYPE (node)) &&
++      TREE_CONSTANT (node) &&
++      (TYPE_PRECISION (TREE_TYPE (node)) < TYPE_PRECISION (long_integer_type_node)))
++    rv = 1;
++  return rv;
++}
++
++static long *
++tw_log_candidate (tree node)
++{
++  long *pval = NULL;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    {
++      pval = (long *) pointer_map_contains (tw_candidate_list, node);
++      if (!pval)
++        {
++          pval = (long *) pointer_map_insert (tw_candidate_list, node);
++          *pval = 1;
++          TWDBG_MSG ("Logged variable:\n");
++          TWDBG_TREE (node);
++        }
++    }
++  return pval; 
++}
++
++static long
++tw_candidacy_valid (tree node)
++{
++  long rval = 0;
++  long *pval = NULL;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    pval = (long *) pointer_map_contains (tw_candidate_list, node); 
++  if (pval)
++    rval = *pval ? 1 : 0;
++  return rval;
++}
++
++static void
++tw_candidacy (tree node, long value)
++{
++  long *pval;
++
++  if (tw_candidate_list && node)
++    {
++      pval = (long *) pointer_map_contains (tw_candidate_list, node);
++      if (pval)
++        {
++          *pval = value;
++#if TW_DEBUG
++          fprintf (stderr, "Setting candidacy of node:\n");
++          TWDBG_TREE (node);
++          fprintf (stderr, "to: %ld\n", value);
++#endif
++        }
++    }
++}
++
++static long
++tw_in_candidate_list (tree node)
++{
++  long *pval;
++  long rval = 0;
++
++  if (tw_candidate_list && node && TREE_TYPE (node) != error_mark_node)
++    {
++     pval = (long *) pointer_map_contains (tw_candidate_list, node);
++     rval = pval ? 1 : 0;
++    }
++  return rval;
++}
++
++static tree
++tw_widen_constant (tree node)
++{
++  if (node && tw_candidate_const (node))
++    node = build_int_cst (long_integer_type_node, TREE_INT_CST_LOW (node));
++
++  return node;
++}
++
++static tree
++tw_widen_variable (tree node)
++{
++  if (node && tw_candidacy_valid (node))
++  {
++    TWDBG_MSG ("Widening:\n");
++    TWDBG_TREE(node);
++
++    TREE_TYPE (node) = build_qualified_type (long_integer_type_node,
++                                             TYPE_QUALS (TREE_TYPE (node)));
++
++    if (TREE_CODE (node) != DEBUG_EXPR_DECL)
++      relayout_decl (node);
++  }
++  return node;
++}
++
++#ifdef TW_FINALIZE_STMTS
++static long
++tw_fn_has_openmp (gimple_seq stmts)
++{
++  gimple_stmt_iterator ittr;
++  long found_openmp = 0;
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr) && !found_openmp; gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++
++      switch (gimple_code (stmt))
++        {
++      case GIMPLE_BIND:
++        found_openmp = tw_fn_has_openmp (gimple_bind_body (stmt));
++        break;
++
++      case GIMPLE_TRY:
++        found_openmp = tw_fn_has_openmp (gimple_try_eval (stmt));
++        found_openmp = tw_fn_has_openmp (gimple_try_cleanup (stmt));
++        break;
++
++      case GIMPLE_EH_FILTER:
++        found_openmp = tw_fn_has_openmp (gimple_eh_filter_failure (stmt));
++        break;
++
++      case GIMPLE_CATCH:
++        found_openmp = tw_fn_has_openmp (gimple_catch_handler (stmt));
++        break;
++
++      default:
++          switch (gimple_code (stmt))
++            {
++            CASE_GIMPLE_OMP:
++            found_openmp = 1;
++            break;
++            default:
++            break;
++            }
++      }
++    }
++  return found_openmp;  
++}
++#endif
++
++/* Originally, we implemented type widening over the emitted GIMPLE
++ * sequence. Later on, we discovered that we needed to wait till
++ * after OpenMP expansion, so we implemented type widening over the
++ * CFG-BB form.
++ */
++#ifdef TW_FINALIZE_STMTS
++struct gimple_opt_pass pass_widen_types_stmts =
++{
++ {
++  GIMPLE_PASS,
++  "tw-stmts",                         /* name */
++  NULL,                                       /* gate */
++  tw_finalize_stmts,                  /* execute */
++  NULL,                                       /* sub */
++  NULL,                                       /* next */
++  0,                                  /* static_pass_number */
++  TV_NONE,                            /* tv_id */
++  PROP_gimple_any,                    /* properties_required */
++  0,                                  /* properties_provided */
++  0,                                  /* properties_destroyed */
++  0,                                  /* todo_flags_start */
++  TODO_dump_func                        /* todo_flags_finish */
++ }
++};
++#endif
++
++struct gimple_opt_pass pass_widen_types_bbs =
++{
++ {
++  GIMPLE_PASS,
++  "tw-bbs",                           /* name */
++  NULL,                                       /* gate */
++  tw_finalize_bbs,                    /* execute */
++  NULL,                                       /* sub */
++  NULL,                                       /* next */
++  0,                                  /* static_pass_number */
++  TV_NONE,                            /* tv_id */
++  PROP_gimple_any,                    /* properties_required */
++  0,                                  /* properties_provided */
++  0,                                  /* properties_destroyed */
++  0,                                  /* todo_flags_start */
++  TODO_dump_func                        /* todo_flags_finish */
++ }
++};
++
++static
++void
++tw_log_parms (tree fndecl)
++{
++  tree parm;
++
++  if (!fndecl)
++    return;
++  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
++    if (tw_candidate (parm))
++      tw_log_candidate (parm);
++  return;
++}
++
++#ifdef TW_FINALIZE_STMTS
++static
++void
++tw_log_vars (gimple_seq stmts)
++{
++  gimple_stmt_iterator ittr;
++  tree vars, vindex;
++
++  if (!stmts)
++    return;
++
++  gcc_assert (tw_candidate_list != NULL);
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++
++      switch (gimple_code (stmt))
++        {
++      case GIMPLE_BIND:
++          vars = gimple_bind_vars (stmt);
++          for (vindex = vars; vindex; vindex = DECL_CHAIN (vindex))
++            if (tw_candidate (vindex))
++              tw_log_candidate (vindex);
++          tw_log_vars (gimple_bind_body (stmt));
++        break;
++
++      case GIMPLE_TRY:
++        tw_log_vars (gimple_try_eval (stmt));
++        tw_log_vars (gimple_try_cleanup (stmt));
++        break;
++
++      case GIMPLE_EH_FILTER:
++        tw_log_vars (gimple_eh_filter_failure (stmt));
++        break;
++
++      case GIMPLE_CATCH:
++        tw_log_vars (gimple_catch_handler (stmt));
++        break;
++
++      default:
++          break;
++      }
++    }
++
++  return;
++}
++#endif
++
++static
++void
++tw_log_local_decls (void)
++{
++  tree decl;
++  unsigned ix;
++
++  FOR_EACH_LOCAL_DECL (cfun, ix, decl)
++    {
++      TWDBG_MSG ("Testing decl:\n");
++      TWDBG_TREE (decl);
++      if (tw_candidate (decl))
++        tw_log_candidate (decl);
++    }
++}
++
++/* Widen types. tw_finalize_stmts () can be run anytime immediately after
++ * gimplification but before the CFG pass (see comment * accompanying
++ * gimple_body ()).
++ *
++ * After gimplification has occurred, the emitted GIMPLE is
++ * scanned to check if these variables are only used among
++ * themselves (with the exception of being cast to unsigned long);
++ * invalidating the candidacy of any variable that is used with
++ * another outside this set (and so on recursively). The variables
++ * that remain after this process all occur in operations with other
++ * such candidate variables, (or with constants) - the type of all
++ * such residual candidate variables (and of constants that appear
++ * with these in operations) is changed to long (along with the
++ * original accompannying qualifiers on the type).
++ *
++ * void
++ * init_optimization_passes (void)
++ *
++ * p = &all_lowering_passes;
++ * NEXT_PASS (pass_widen_types_stmts);
++ * NEXT_PASS (pass_warn_unused_result);
++ */
++#ifdef TW_FINALIZE_STMTS
++static
++unsigned int
++tw_finalize_stmts (void)
++{
++  long iv = 0;
++  gimple_seq stmts;
++  tree fndecl = current_function_decl; 
++
++  if (strcmp (lang_hooks.name, "GNU C") != 0 ||
++      seen_error () ||
++      !flag_strict_overflow ||
++      !flag_widen_types)
++    {
++      TWDBG_MSG ("Skipping: Language not C or seen error or -fno-strict-overflow or -fno-widen-types\n");
++      return 0;
++    }
++
++  /* gcc.dg/pr23518.c execution test */ 
++  if (flag_wrapv)
++    {
++      TWDBG_MSG ("Skipping: -fwrapv specified.\n");
++      return 0;
++    }
++
++  if (debug_info_level == DINFO_LEVEL_NONE)
++    {
++      /* PS: That we cannot call relayout_decl () on DEBUG_EXPR_DECL is an
++      * issue: Debug information is generated after lowering from tree to 
++      * GIMPLE; unless we widen before debug information is generated, the
++      * debug information will record pre-widening information - and that
++      * cannot be changed because relayout_decl () cannot be invoked on 
++      * DEBUG_EXPR_DECL. expand_debug_locations () during cfgexpand will
++      * fail gcc_assert ()'s on the DEBUG_INSN's since e.g. the modes will
++      * not agree, etc. So if we are compiling -g, we ought to run the 
++      * pass_widen_types_stmts.
++      *
++      * In short: pass_widen_types_stmts runs iff we're generating debug
++      *           information.
++      */
++      TWDBG_MSG ("Skipping: Debug level none.\n");
++      return 0;
++    }
++  gcc_assert (debug_info_level != DINFO_LEVEL_NONE);
++
++  if (!fndecl)
++    {
++      TWDBG_MSG ("Skipping: !fndecl.\n");
++      return 0;
++    }
++
++  TWDBG_MSG ("Widening function:\n");
++  TWDBG_TREE (fndecl);
++
++  stmts = gimple_body (fndecl);
++
++  if (!stmts)
++    {
++      TWDBG_MSG ("Skipping: !stmts.\n");
++      return 0;
++    }
++
++  if (tw_fn_has_openmp (stmts))
++    {
++      TWDBG_MSG ("Skipping: OpenMP stmts found.\n");
++      return 0;
++    }
++
++  /* Assume for now that we do not need to check for nested functions:
++   * (cgraph_get_node (fndecl) && cgraph_get_node (fndecl)->nested != NULL) ||
++   * TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL ||
++   * Well, turns out that a nested function is processed only if it is 
++   * actually invoked from within the function, so we are in good shape.
++   */
++
++  tw_init ();
++  tw_log_parms (fndecl);
++  tw_log_vars (stmts);
++#if TW_DEBUG
++  tw_dump_candidate_list ();
++#endif
++
++  do
++    {
++      iv = tw_gimple_in_seq (stmts, 0);
++    } while (iv);
++  tw_gimple_in_seq (stmts, 1);
++  verify_types_in_gimple_seq (stmts);
++
++  tw_reset ();
++
++  return 0;
++}
++#endif
++
++static
++unsigned int
++tw_finalize_bbs (void)
++{
++  long iv = 0;
++  basic_block bb;
++  tree fndecl;
++
++  if (strcmp (lang_hooks.name, "GNU C") != 0 ||
++      seen_error () ||
++      !flag_strict_overflow ||
++      !flag_widen_types)
++    {
++      TWDBG_MSG ("Skipping: Language not C or seen error or -fno-strict-overflow or -fno-widen-types\n");
++      return 0;
++    }
++ 
++  /* gcc.dg/pr23518.c execution test */ 
++  if (flag_wrapv)
++    {
++      TWDBG_MSG ("Skipping: -fwrapv specified.\n");
++      return 0;
++    }
++
++  if (debug_info_level != DINFO_LEVEL_NONE && flag_openmp)
++    {
++      /* Cannot run this pass as the debug information has already
++       * been recorded; If we type widen now, it'll lead to assert
++       * failures during RTL expansion in expandcfg.c since the
++       * debug information would all be prewidening and would
++       * mismatch with the postwidening information for the variables
++       * that got widened (but whoose debug information was already
++       * generated). This is all because we cannot call relayout_decl ()
++       * on DEBUG_EXPR_DECL's - see note elsewhere.
++       */
++      TWDBG_MSG ("Skipping: Non-zero debug level and -fopenmp specified.\n");
++      return 0;
++    }
++
++  if (!cfun || !(fndecl = cfun->decl) || !(cfun->cfg))
++    {
++      TWDBG_MSG ("Skipping: !cfun or !fndecl or !(cfun->cfg).\n");
++      return 0;
++    }
++
++  TWDBG_MSG ("Widening function:\n");
++  TWDBG_TREE (fndecl);
++
++  /* Assume for now that we do not need to check for nested functions:
++   * (cgraph_get_node (fndecl) && cgraph_get_node (fndecl)->nested != NULL) ||
++   * TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL ||
++   * Well, turns out that a nested function is processed only if it is 
++   * actually invoked from within the function, so we are in good shape.
++   */
++
++  tw_init ();
++  tw_log_parms (fndecl);
++  tw_log_local_decls (); 
++#if TW_DEBUG
++  tw_dump_candidate_list ();
++#endif
++
++  do
++    {
++      iv = 0;
++      FOR_EACH_BB (bb)
++        iv += tw_gimple_in_bb (bb, 0);
++    } while (iv);
++  FOR_EACH_BB (bb)
++    tw_gimple_in_bb (bb, 1);
++  FOR_EACH_BB (bb)
++    verify_types_in_gimple_seq (bb_seq (bb));
++
++  tw_reset ();
++
++  return 0;
++}
++
++/* Assumes that we have run verify_gimple_in_seq (stmts)
++ * i.e. that we have valid gimple.
++ */
++static long
++tw_gimple_in_seq (gimple_seq stmts, long widen)
++{
++  gimple_stmt_iterator ittr;
++  long iv = 0;
++
++  for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++      iv += tw_switch (stmt, widen);
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_in_bb (basic_block bb, long widen)
++{
++  gimple_stmt_iterator ittr;
++  long iv = 0;
++
++#if TW_DEBUG
++  fprintf (stderr, "Dumping basic block (widen = %ld):\n", widen);
++  debug_bb (bb);
++  fprintf (stderr, "Done dumping basic block (widen = %ld)\n", widen);
++#endif
++  for (ittr = gsi_start_bb (bb); !gsi_end_p (ittr); gsi_next (&ittr))
++    {
++      gimple stmt = gsi_stmt (ittr);
++      iv += tw_switch (stmt, widen);
++    }
++  return iv;  
++}
++
++static long
++tw_switch (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_code (stmt))
++    {
++    case GIMPLE_BIND:
++      iv += tw_gimple_in_seq (gimple_bind_body (stmt), widen);
++      break;
++
++    case GIMPLE_TRY:
++      iv += tw_gimple_in_seq (gimple_try_eval (stmt), widen);
++      iv += tw_gimple_in_seq (gimple_try_cleanup (stmt), widen);
++      break;
++
++    case GIMPLE_EH_FILTER:
++      iv += tw_gimple_in_seq (gimple_eh_filter_failure (stmt), widen);
++      break;
++
++    case GIMPLE_CATCH:
++      iv += tw_gimple_in_seq (gimple_catch_handler (stmt), widen);
++      break;
++
++    default:
++      iv += tw_gimple_stmt (stmt, widen);
++      break;
++    }
++  return iv;  
++}
++
++/* tw_gimple_stmt () mimics verify_gimple_stmt ()
++ */
++static long
++tw_gimple_stmt (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_code (stmt))
++    {
++    case GIMPLE_ASSIGN:
++      iv = tw_gimple_assign (stmt, widen);
++      break;
++
++    case GIMPLE_CALL:
++      iv = tw_gimple_call (stmt, widen);
++      break;
++
++    case GIMPLE_COND:
++      iv = tw_gimple_comparison (stmt, widen);
++      break;
++
++    case GIMPLE_SWITCH:
++      iv = tw_gimple_switch (stmt, widen);
++      break;
++
++    case GIMPLE_RETURN:
++      iv = tw_gimple_return (stmt, widen);
++      break;
++
++    case GIMPLE_LABEL:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_GOTO:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_ASM:
++      iv = tw_gimple_asm (stmt, widen);
++      break;
++
++    /* Tuples that do not have tree operands.  */
++    case GIMPLE_NOP:
++    case GIMPLE_PREDICT:
++    case GIMPLE_RESX:
++    case GIMPLE_EH_DISPATCH:
++    case GIMPLE_EH_MUST_NOT_THROW:
++      TWDBG_STMT(stmt);
++      break;
++
++    CASE_GIMPLE_OMP:
++      TWDBG_STMT(stmt);
++      break;
++
++    case GIMPLE_DEBUG:
++      iv = tw_gimple_debug (stmt, widen);
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_assign (gimple stmt, long widen)
++{
++  long iv = 0;
++
++  switch (gimple_assign_rhs_class (stmt))
++    {
++    case GIMPLE_SINGLE_RHS:
++      iv = tw_gimple_assign_single (stmt, widen);
++      break;
++
++    case GIMPLE_UNARY_RHS:
++      iv = tw_gimple_assign_unary (stmt, widen);
++      break;
++
++    case GIMPLE_BINARY_RHS:
++      iv = tw_gimple_assign_binary (stmt, widen);
++      break;
++
++    case GIMPLE_TERNARY_RHS:
++      iv = tw_gimple_assign_ternary (stmt, widen);
++      break;
++
++    default:
++      gcc_unreachable ();
++    }
++  return iv;  
++}
++
++static long
++tw_gimple_assign_single (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree value;
++  long iv = 0;
++  unsigned int idx;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (TREE_CODE (rhs1) == ARRAY_REF &&
++          tw_candidacy_valid (TREE_OPERAND (rhs1, 1)))
++        {
++          /* Note that we are widening the array index, hence no 
++           * gimple_assign_set_rhs1 () */
++          tw_widen_variable (TREE_OPERAND (rhs1, 1));
++        }
++      else if (TREE_CODE (lhs) == ARRAY_REF &&
++          tw_candidacy_valid (TREE_OPERAND (lhs, 1)))
++        {
++          /* Note that we are widening the array index, hence no 
++           * gimple_assign_set_lhs () */
++          tw_widen_variable (TREE_OPERAND (lhs, 1));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs1))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_constant (rhs1));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs1))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1))
++        return iv;
++      if (TREE_CODE (lhs) == VAR_DECL && TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE &&
++          TREE_CODE (rhs1) == CONSTRUCTOR && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
++        { 
++          FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs1), idx, value)
++            {
++              if (tw_candidacy_valid (value))
++                {
++                  TWDBG_MSG ("Invalidating candidacy of constructor element:\n");
++                  TWDBG_TREE (value);
++                  tw_candidacy (value, 0);
++                  iv++;
++                }
++            }
++        }
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_assign_unary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (gimple_assign_rhs_code (stmt) == NOP_EXPR &&
++          tw_candidacy_valid (rhs1) &&
++          (TREE_TYPE (lhs) == long_unsigned_type_node ||
++           TREE_TYPE (lhs) == long_integer_type_node))
++        gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (gimple_assign_rhs_code (stmt) == NOP_EXPR &&
++          tw_candidacy_valid (rhs1) &&
++          (TREE_TYPE (lhs) == long_unsigned_type_node ||
++           TREE_TYPE (lhs) == long_integer_type_node))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++    }
++    return iv;
++}
++
++static long
++tw_gimple_assign_binary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree rhs2 = gimple_assign_rhs2 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  TWDBG_TREE(rhs2);
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidate_const (rhs2))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++          gimple_assign_set_rhs2 (stmt, tw_widen_constant (rhs2));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidacy_valid (rhs2))
++        {
++          gimple_assign_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_assign_set_rhs1 (stmt, tw_widen_variable (rhs1));
++          gimple_assign_set_rhs2 (stmt, tw_widen_variable (rhs2));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidate_const (rhs2))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs1) && tw_candidacy_valid (rhs2))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs1))
++        {
++          tw_candidacy (rhs1, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs2))
++        {
++          tw_candidacy (rhs2, 0);
++          iv++;
++        }
++    }
++    return iv;
++}
++
++static long
++tw_gimple_assign_ternary (gimple stmt, long widen)
++{
++  tree lhs = gimple_assign_lhs (stmt);
++  tree rhs1 = gimple_assign_rhs1 (stmt);
++  tree rhs2 = gimple_assign_rhs2 (stmt);
++  tree rhs3 = gimple_assign_rhs3 (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs);
++  TWDBG_TREE(rhs1);
++  TWDBG_TREE(rhs2);
++  TWDBG_TREE(rhs3);
++
++  if (widen)
++    {
++     TWDBG_MSG ("Widening run.\n");
++     return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (tw_candidacy_valid (lhs))
++    {
++      tw_candidacy (lhs, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs1))
++    {
++      tw_candidacy (rhs1, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs2))
++    {
++      tw_candidacy (rhs2, 0);
++      iv++;
++    }
++  if (tw_candidacy_valid (rhs3))
++    {
++      tw_candidacy (rhs3, 0);
++      iv++;
++    }
++  return iv;
++}
++
++/* Ref. WG14/N1256 Committee Draft - September 7, 2007 ISO/IEC 9899:TC3
++ * 7.19.6 Formatted input/output functions
++ * Sec. 17.19.6.[1 ... 14]
++ */
++#define IO_FN_COUNT 14
++static const char *IO_fn_names[IO_FN_COUNT] =
++{
++  "fprintf", "fscanf",
++  "printf",  "scanf",
++  "snprintf",
++  "sprintf", "sscanf",
++  "vfprintf", "vfscanf",
++  "vprintf", "vscanf",
++  "vsnprintf",
++  "vsprintf", "vsscanf",
++};
++
++static bool
++is_formatted_IO_fn (tree decl)
++{
++  const char *fn_name;
++  long i;
++
++  if (decl && TREE_CODE (decl) == FUNCTION_DECL &&
++      DECL_NAME (decl) /* TREE_CODE (decl) == IDENTIFIER_NODE */ &&
++      (fn_name = IDENTIFIER_POINTER (DECL_NAME (decl))))
++    {
++      for (i = 0; i < IO_FN_COUNT; i++)
++        if (strcmp (IO_fn_names[i], fn_name) == 0)
++          return true;
++    }
++  return false;
++}
++
++/* TODO: If you have:
++ * 
++ *  int i, n, f();
++ *
++ *  n = f();
++ *
++ *  for (i = 0; i < n; i++) 
++ *    // stuff
++ *
++ *  then (after the candidate set stabilizes) do:
++ *
++ *  int n, f();
++ *  long twl.n;
++ *
++ *  n = f();
++ *  twl.n = (long) n;
++ *
++ *  for (i = 0; i < twl.n; i++) 
++ *    // stuff
++ *
++ *  only if adding twl.n does not decrease the size of the stabilized
++ *  candidate set or "cause any other damage".
++ *
++ * This should help in benchmarks where parameters are set via function
++ * calls to prevent them from being optimized away.
++ *
++ */
++static long
++tw_gimple_call (gimple stmt, long widen)
++{
++#if TW_DEBUG
++  tree fn = gimple_call_fn (stmt);
++#endif
++  long iv = 0;
++  unsigned i;
++  tree arg;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(fn);
++  TWDBG_TREE(gimple_call_fndecl (stmt));
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      for (i = 0; i < gimple_call_num_args (stmt); i++)
++        {
++          arg = gimple_call_arg (stmt, i);
++          if (arg && tw_candidacy_valid (arg))
++            gimple_call_set_arg (stmt, i, tw_widen_variable (arg));
++        }
++      return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (gimple_call_lhs (stmt) && tw_candidacy_valid (gimple_call_lhs (stmt)))
++    {
++      tw_candidacy (gimple_call_lhs (stmt), 0);
++      iv++;
++    }
++  if (gimple_call_fndecl (stmt) &&
++      (is_builtin_fn (gimple_call_fndecl (stmt)) ||
++       is_formatted_IO_fn (gimple_call_fndecl (stmt))))
++    {
++      /* Certain types of function (printf-scanf family,
++       * formatted IO functions, builtin functions) ought
++       * not to have their args widened.
++       *
++       * e.g. A call to printf () such as:
++       * int x;
++       * printf ("%d", x);
++       * because, we cannot change the %d to a %ld.
++       *
++       * or e.g. in:
++       *
++       * int D.2852;
++       * int si;
++       *
++       * si = 2;
++       * __builtin_altivec_dst (&vi, si, 0);
++       * D.2852 = 0;
++       *
++       * si should not be widened.
++       *
++       * PS: We could generate code for casts to their original types in the
++       *     call, but that would slow-down performance and we do not expect
++       *     a loop index to be used in a call to a formatted IO function.
++       */
++      for (i = 0; i < gimple_call_num_args (stmt); i++)
++        {
++          arg = gimple_call_arg (stmt, i);
++          if (arg && tw_candidacy_valid (arg))
++            {
++              tw_candidacy (arg, 0);
++              iv++;
++            }
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_comparison (gimple stmt, long widen)
++{
++  tree lhs = gimple_cond_lhs (stmt);
++  tree rhs = gimple_cond_rhs (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(lhs); 
++  TWDBG_TREE(rhs); 
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_constant (rhs));
++        }
++      else if (tw_candidate_const (lhs) && tw_candidacy_valid (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_constant (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_variable (rhs));
++        }
++      else if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs))
++        {
++          gimple_cond_set_lhs (stmt, tw_widen_variable (lhs));
++          gimple_cond_set_rhs (stmt, tw_widen_variable (rhs));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++      if (tw_candidacy_valid (lhs) && tw_candidate_const (rhs))
++        return iv;
++      if (tw_candidate_const (lhs) && tw_candidacy_valid (rhs))
++        return iv;
++      if (tw_candidacy_valid (lhs) && tw_candidacy_valid (rhs))
++        return iv;
++      if (tw_candidacy_valid (lhs))
++        {
++          tw_candidacy (lhs, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (rhs))
++        {
++          tw_candidacy (rhs, 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_switch (gimple stmt, long widen)
++{
++  tree index = gimple_switch_index (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(index); 
++
++  if (widen && tw_candidacy_valid (index))
++    {
++      TWDBG_MSG ("Widening run.\n");
++      gimple_switch_set_index (stmt, tw_widen_variable (index));
++      return iv;
++    }
++   
++  TWDBG_MSG ("Validating run.\n");
++  return iv;
++}
++
++static long
++tw_gimple_return (gimple stmt, long widen)
++{
++  tree op = gimple_return_retval (stmt);
++  long iv = 0;
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(op); 
++
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      return iv;
++    }
++
++  TWDBG_MSG ("Validating run.\n");
++  if (tw_candidacy_valid (op))
++    {
++      tw_candidacy (op, 0);
++      iv++;
++    }
++  return iv;
++}
++
++static long
++tw_gimple_asm (gimple stmt, long widen)
++{
++  long iv = 0;
++  unsigned int ninputs = gimple_asm_ninputs (stmt);
++  unsigned int noutputs = gimple_asm_noutputs (stmt);
++  unsigned int nclobbers = gimple_asm_nclobbers (stmt);
++  unsigned int i;
++
++  TWDBG_STMT(stmt);
++  TWDBG_MSG("Inputs:\n");
++  for (i = 0; i < ninputs; i++)
++    {
++      TWDBG_MSG1 ("input %d\n", i);
++      TWDBG_TREE (gimple_asm_input_op (stmt, i));
++    }
++  TWDBG_MSG("Outputs:\n");
++  for (i = 0; i < noutputs; i++)
++    {
++      TWDBG_MSG1 ("output %d\n", i);
++      TWDBG_TREE (gimple_asm_output_op (stmt, i));
++    }
++  TWDBG_MSG("Clobbers:\n");
++  for (i = 0; i < nclobbers; i++)
++    {
++      TWDBG_MSG1 ("clobber %d\n", i);
++      TWDBG_TREE (gimple_asm_clobber_op (stmt, i));
++    }
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      return iv;
++    }
++  TWDBG_MSG ("Validating run.\n");
++  for (i = 0; i < ninputs; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_input_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_input_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  for (i = 0; i < noutputs; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_output_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_output_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  for (i = 0; i < nclobbers; i++)
++    {
++      if (tw_candidacy_valid (gimple_asm_clobber_op (stmt, i)))
++        {
++          tw_candidacy (gimple_asm_clobber_op (stmt, i), 0);
++          iv++;
++        }
++    }
++  return iv;
++}
++
++static long
++tw_gimple_debug (gimple stmt, long widen)
++{
++  long iv = 0;
++  tree var, value;
++
++  var = gimple_debug_bind_get_var (stmt);
++  value = gimple_debug_bind_get_value (stmt);
++
++  TWDBG_STMT(stmt);
++  TWDBG_TREE(var);
++  TWDBG_TREE(value);
++
++  /* TODO: What if the value is a constant? */
++ 
++  if (widen)
++    {
++      TWDBG_MSG ("Widening run.\n");
++      if (tw_candidacy_valid (var) && tw_candidacy_valid (value))
++        {
++          gimple_debug_bind_set_var (stmt, tw_widen_variable (var));
++          gimple_debug_bind_set_value (stmt, tw_widen_variable (value));
++        }
++      else if (tw_candidacy_valid (var) && tw_candidate_const (value))
++        {
++          gimple_debug_bind_set_var (stmt, tw_widen_variable (var));
++          gimple_debug_bind_set_value (stmt, tw_widen_constant (value));
++        }
++    }
++  else
++    {
++      TWDBG_MSG ("Validating run.\n");
++
++      if (var && !tw_in_candidate_list (var) && tw_candidate (var))
++        tw_log_candidate (var);
++      if (value && !tw_in_candidate_list (value) && tw_candidate (value))
++        tw_log_candidate (value);
++      if (tw_candidacy_valid (var) && tw_candidacy_valid (value))
++        return iv;
++      if (tw_candidacy_valid (var))
++        {
++          tw_candidacy (var, 0);
++          iv++;
++        }
++      if (tw_candidacy_valid (value))
++        {
++          tw_candidacy (value, 0);
++          iv++;
++        }
++    }
++   
++  return iv;
++}
++
++/* Notes:
++ * ------
++ *
++ * Limitations to be documented:
++ * 0. -g -fopenmp not supported.
++ *
++ * Known DejaGNU failures:
++ * 0. FAIL: gcc.dg/pr38245-2.c scan-tree-dump-not optimized "link_error"
++ *    This failure is because the optimization is dependent on the type of the variable;
++ *    once the type of the variable has changed from int to long, the inequalities in
++ *    this test case no longer hold and the code cannot be optimized anymore, consequently,
++ *    the test fails.
++ *
++ * DejaGNU failures that are not due to type-widening:
++ * 0. gcc.dg/vect/vect-120.c scan-tree-dump-times vect "vectorized 1 loops" 1
++ * 1.gcc.dg/vect/vect-120.c -flto scan-tree-dump-times vect "vectorized 1 loops" 1
++ *
++ * DejaGNU PASS'es with -fwiden-types (but FAIL's in the baseline - the baseline needs
++ * to be fixed - it just so happens that the debug information happens to be better in
++ * the type-converted case. We have verified that the generated assembly is the same in
++ * either case (or has extsw eliminated)):
++ * gcc.dg/guality/pr45882.c
++ * gcc.dg/guality/pr43177.c
++ *
++ */
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/files/optional_libstdc.patch b/meta-fsl-ppc/recipes-devtools/gcc/files/optional_libstdc.patch
new file mode 100644 (file)
index 0000000..fe157a8
--- /dev/null
@@ -0,0 +1,86 @@
+Upstream-Status: Inappropriate [embedded specific]
+
+gcc-runtime builds libstdc++ separately from gcc-cross-*. Its configure tests using g++ 
+will not run correctly since by default the linker will try to link against libstdc++
+which shouldn't exist yet. We need an option to disable -lstdc++
+option whilst leaving -lc, -lgcc and other automatic library dependencies added by gcc 
+driver. This patch adds such an option which only disables the -lstdc++.
+
+A "standard" gcc build uses xgcc and hence avoids this. We should ask upstream how to 
+do this officially, the likely answer is don't build libstdc++ separately.
+
+RP 29/6/10
+
+Index: gcc-4.6.0/gcc/cp/g++spec.c
+===================================================================
+--- gcc-4.6.0.orig/gcc/cp/g++spec.c
++++ gcc-4.6.0/gcc/cp/g++spec.c
+@@ -127,6 +127,7 @@ lang_specific_driver (struct cl_decoded_
+       switch (decoded_options[i].opt_index)
+       {
+       case OPT_nostdlib:
++      case OPT_nostdlib__:
+       case OPT_nodefaultlibs:
+         library = -1;
+         break;
+Index: gcc-4.6.0/gcc/doc/invoke.texi
+===================================================================
+--- gcc-4.6.0.orig/gcc/doc/invoke.texi
++++ gcc-4.6.0/gcc/doc/invoke.texi
+@@ -193,7 +193,7 @@ in the following sections.
+ -fno-pretty-templates @gol
+ -frepo  -fno-rtti  -fstats  -ftemplate-depth=@var{n} @gol
+ -fno-threadsafe-statics -fuse-cxa-atexit  -fno-weak  -nostdinc++ @gol
+--fno-default-inline  -fvisibility-inlines-hidden @gol
++-nostdlib++ -fno-default-inline  -fvisibility-inlines-hidden @gol
+ -fvisibility-ms-compat @gol
+ -Wabi  -Wconversion-null  -Wctor-dtor-privacy @gol
+ -Wnoexcept -Wnon-virtual-dtor  -Wreorder @gol
+@@ -431,7 +431,7 @@ Objective-C and Objective-C++ Dialects}.
+ @gccoptlist{@var{object-file-name}  -l@var{library} @gol
+ -nostartfiles  -nodefaultlibs  -nostdlib -pie -rdynamic @gol
+ -s  -static  -static-libgcc  -static-libstdc++ -shared  @gol
+--shared-libgcc  -symbolic @gol
++-shared-libgcc  -symbolic -nostdlib++ @gol
+ -T @var{script}  -Wl,@var{option}  -Xlinker @var{option} @gol
+ -u @var{symbol}}
+@@ -9069,6 +9069,11 @@ These entries are usually resolved by en
+ libc.  These entry points should be supplied through some other
+ mechanism when this option is specified.
++@item -nostdlib++
++@opindex nostdlib++
++Do not use the standard system C++ runtime libraries when linking.
++Only the libraries you specify will be passed to the linker.
++
+ @cindex @option{-lgcc}, use with @option{-nostdlib}
+ @cindex @option{-nostdlib} and unresolved references
+ @cindex unresolved references and @option{-nostdlib}
+Index: gcc-4.6.0/gcc/c-family/c.opt
+===================================================================
+--- gcc-4.6.0.orig/gcc/c-family/c.opt
++++ gcc-4.6.0/gcc/c-family/c.opt
+@@ -1111,6 +1111,10 @@ nostdinc++
+ C++ ObjC++
+ Do not search standard system include directories for C++
++nostdlib++
++Driver
++Do not link standard C++ runtime library
++
+ o
+ C ObjC C++ ObjC++ Joined Separate
+ ; Documented in common.opt
+Index: gcc-4.6.0/gcc/gcc.c
+===================================================================
+--- gcc-4.6.0.orig/gcc/gcc.c
++++ gcc-4.6.0/gcc/gcc.c
+@@ -666,6 +666,7 @@ proper position among the other output f
+     %(mflib) " STACK_SPLIT_SPEC "\
+     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
+     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
++    %{!nostdlib++:}\
+     %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}"
+ #endif
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-canadian_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-canadian_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-initial_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-initial_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-intermediate_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-intermediate_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-initial_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-initial_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-intermediate_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-intermediate_4.6.bbappend
new file mode 100644 (file)
index 0000000..ed27db0
--- /dev/null
@@ -0,0 +1,22 @@
+require gcc-fsl.inc
+
+do_install () {
+        oe_runmake 'DESTDIR=${D}' install
+        install -d ${D}${target_base_libdir}/
+        cp -rf ${D}${exec_prefix}/${TARGET_SYS}/${baselib}/ ${D}${target_base_libdir}/
+
+        # We don't really need this (here shares/ contains man/, info/, locale/).
+        rm -rf ${D}${datadir}/
+
+        # We use libiberty from binutils
+        find ${D}${exec_prefix}/lib -name libiberty.a | xargs rm -f
+        find ${D}${exec_prefix}/lib -name libiberty.h | xargs rm -f
+
+        # Insert symlinks into libexec so when tools without a prefix are searched for, the correct ones are
+        # found. These need to be relative paths so they work in different locations.
+        dest=${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/
+        install -d $dest
+        for t in ar as ld nm objcopy objdump ranlib strip g77 gcc cpp gfortran; do
+               ln -sf ${BINRELPATH}/${TARGET_PREFIX}$t $dest$t
+        done
+}
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-fsl.inc b/meta-fsl-ppc/recipes-devtools/gcc/gcc-fsl.inc
new file mode 100644 (file)
index 0000000..83d519c
--- /dev/null
@@ -0,0 +1,44 @@
+#LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
+#                   file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 \
+#                   file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
+#                   file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
+#                   file://COPYING.RUNTIME;md5=fe60d87048567d4fe8c8a0ed2448bcc8"
+
+BINV = "4.6.2"
+
+SRCREV = "180516"
+# ignore linaro backports since we are changing the SRCREV
+GCC-4_6-BRANCH-LINARO-BACKPORTS = ""
+
+SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH};proto=http \
+           file://gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \
+           file://gcc.fix_longversionstring.patch \
+           file://gcc.rm_slow_tests.patch \
+           file://gcc.fix_mingw32.patch \
+           file://gcc.fix_cloogstatic2.patch \
+           file://gcc.fix_build-with-cxx.patch \
+          file://gcc.e6500-FSF46.patch \
+           file://gcc.ld_unaligned-460.patch \
+           file://gcc.local_unaligned_altivec.patch \
+           file://gcc.soft_float-460.patch \
+           file://gcc.case_values.patch \
+           file://gcc.builtin_isel.patch \
+           file://gcc.experimental_move.patch \
+           file://gcc.widen_types-46.patch \
+           file://gcc.extelim-v3.patch \
+           file://gcc.e5500_mfocr.patch \
+           file://gcc.opt-array-offset.patch \
+           file://gcc.load_on_store_bypass-462.patch \
+           file://gcc.fix_constvector.patch \
+           file://gcc.fix_MTWX51204-dwarf-vector-reg.patch \
+           file://gcc.fix_ira-loop-pressure.patch \
+          file://optional_libstdc.patch \
+          file://gcc.remove_CCUNSmode_reference.patch \
+          file://gcc.check_path_validity.patch \
+          file://gcc.fix_header_issue.patch \
+          file://gcc.fix_SSIZE_MAX_undefine_issue.patch \
+"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+PR .= "+${DISTRO}.0"
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc-runtime_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc-runtime_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/gcc_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/gcc_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc
diff --git a/meta-fsl-ppc/recipes-devtools/gcc/libgcc_4.6.bbappend b/meta-fsl-ppc/recipes-devtools/gcc/libgcc_4.6.bbappend
new file mode 100644 (file)
index 0000000..1c725f2
--- /dev/null
@@ -0,0 +1 @@
+require gcc-fsl.inc