From: Zhenhua Luo Date: Fri, 9 Mar 2012 10:57:35 +0000 (+0000) Subject: integrate fsl toolchain patches X-Git-Tag: 2.1~534^2~513 X-Git-Url: https://code.ossystems.io/gitweb?a=commitdiff_plain;h=d1657529d217e6a9d66a04f9ce971de458ff3c39;p=meta-freescale.git integrate fsl toolchain patches 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 --- 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 index 00000000..135f2678 --- /dev/null +++ b/meta-fsl-ppc/recipes-append/gettext/files/gettext.fix_testcase.patch @@ -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 index 00000000..937be226 --- /dev/null +++ b/meta-fsl-ppc/recipes-append/gettext/gettext_0.18.1.1.bbappend @@ -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 index 00000000..d46b87a8 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross-canadian_2.21.1a.bbappend @@ -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 index 00000000..d46b87a8 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/binutils-cross_2.21.1a.bbappend @@ -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 index 00000000..d46b87a8 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/binutils-crosssdk_2.21.1a.bbappend @@ -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 index 00000000..e425d42a --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/binutils-fsl.inc @@ -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 index 00000000..d46b87a8 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/binutils_2.21.1a.bbappend @@ -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 index 00000000..9c9d52ca --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e500mc_nop.patch @@ -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 : ++ 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 : ++ 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 : ++ 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 index 00000000..800590c3 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e5500.patch @@ -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 index 00000000..e8633233 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/binutils/files/bin.e6500-2.patch @@ -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 : ++ 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) + +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 + + /* 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 index 00000000..f7540110 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-fsl.inc @@ -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 index 00000000..4f61361b --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-initial_2.13.bbappend @@ -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 index 00000000..4f61361b --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc-locale_2.13.bbappend @@ -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 index 00000000..4f61361b --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/eglibc_2.13.bbappend @@ -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 index 00000000..e69de29b 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 index 00000000..d2a28c2d --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/generate-supported.mk @@ -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 index 00000000..6feb76ef --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.e500mc_subspecies_of_powerpc_is_not_supported.patch @@ -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 index 00000000..966e9e3c --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_prof.patch @@ -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 +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 index 00000000..a648b4ff --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fix_sqrt.patch @@ -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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++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 index 00000000..42887694 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.fixgcc4.6.patch @@ -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 index 00000000..fbeee699 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.readv_proto.patch @@ -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 + + /* 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 index 00000000..aba52855 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/eglibc/files/glibc.undefined_static.patch @@ -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 index 00000000..10e59999 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.builtin_isel.patch @@ -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); ++} ++ ++/* 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); ++} ++ ++/* 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" ++ ++ ++/* 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" } */ ++} ++ ++/* 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" } */ ++} ++ ++/* 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. */ ++ ++/* 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); ++} ++ ++/* 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); ++} ++ ++/* 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. */ ++ ++/* 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" } */ ++} ++ ++/* 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" } */ ++} ++ ++/* 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 index 00000000..5be766d9 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.case_values.patch @@ -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); + + + /* 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; + + +@@ -28179,6 +28182,12 @@ + } + + ++static unsigned int ++rs6000_case_values_threshold (void) ++{ ++ return PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD); ++} ++ + /* 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 index 00000000..5d70a397 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.check_path_validity.patch @@ -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 index 00000000..16b3538a --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e5500_mfocr.patch @@ -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" +- [(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_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" +@@ -15345,9 +15347,9 @@ + "") + + (define_insn "*neg_gtu" +- [(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 index 00000000..f9fa33de --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.e6500-FSF46.patch @@ -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 "add3" + [(set (match_operand:VI 0 "register_operand" "=v") +@@ -1741,6 +1787,15 @@ + "lvewx %0,%y1" + [(set_attr "type" "vecload")]) + ++(define_insn "altivec_lvexx" ++ [(parallel ++ [(set (match_operand:VI 0 "register_operand" "=v") ++ (match_operand:VI 1 "memory_operand" "Z")) ++ (unspec [(const_int 0)] UNSPEC_LVEX)])] ++ "TARGET_ALTIVEC2" ++ "lvexx %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_stvexx" ++ [(set (match_operand: 0 "memory_operand" "=Z") ++ (unspec: [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVEX))] ++ "TARGET_ALTIVEC2" ++ "stvexx %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 ++;; . ++;; ++;; 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 ++;; . ++;; ++;; 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 @@ + + ;; 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 "popcntd2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] + "TARGET_POPCNTD" +- "popcnt %0,%1") ++ "popcnt %0,%1" ++ [(set_attr "length" "4") ++ (set_attr "type" "popcnt")]) + + (define_expand "popcount2" + [(set (match_operand:GPR 0 "gpc_reg_operand" "") +@@ -5957,10 +5963,10 @@ + && ((TARGET_PPC_GFXOPT + && !HONOR_NANS (mode) + && !HONOR_SIGNED_ZEROS (mode)) +- || TARGET_CMPB ++ || TARGET_LFIWAX + || VECTOR_UNIT_VSX_P (mode))" + { +- if (TARGET_CMPB || VECTOR_UNIT_VSX_P (mode)) ++ if (TARGET_LFIWAX || VECTOR_UNIT_VSX_P (mode)) + { + emit_insn (gen_copysign3_fcpsgn (operands[0], operands[1], + operands[2])); +@@ -5979,7 +5985,7 @@ + (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "") + (match_operand:SFDF 2 "gpc_reg_operand" "")] + UNSPEC_COPYSIGN))] +- "TARGET_CMPB && !VECTOR_UNIT_VSX_P (mode)" ++ "TARGET_LFIWAX && !VECTOR_UNIT_VSX_P (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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 ++ ++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 index 00000000..b9642ed6 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.experimental_move.patch @@ -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 index 00000000..e124b187 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.extelim-v3.patch @@ -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 ++. */ ++ ++/* ++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, ++ " (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 index 00000000..cb34859a --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_MTWX51204-dwarf-vector-reg.patch @@ -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 index 00000000..51dc5586 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_SSIZE_MAX_undefine_issue.patch @@ -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 + . */ + ++#include ++ + #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 index 00000000..cfceafd3 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_build-with-cxx.patch @@ -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 index 00000000..afa29d93 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_cloogstatic2.patch @@ -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 index 00000000..c4a27766 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_constvector.patch @@ -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 index 00000000..e2b9f7f2 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_header_issue.patch @@ -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 ++#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 index 00000000..86ad32a1 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_ira-loop-pressure.patch @@ -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 index 00000000..2d7fae78 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_longversionstring.patch @@ -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 index 00000000..0d8c00ef --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.fix_mingw32.patch @@ -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 index 00000000..2eb270eb --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.ld_unaligned-460.patch @@ -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 index 00000000..a03a7ff2 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.load_on_store_bypass-462.patch @@ -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- Mark 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 index 00000000..feee54a1 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.local_unaligned_altivec.patch @@ -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 index 00000000..7cdc6f79 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.opt-array-offset.patch @@ -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 ++. */ ++ ++ ++/* 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 index 00000000..03e3ce9c --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.remove_CCUNSmode_reference.patch @@ -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 index 00000000..b02b7555 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.rm_slow_tests.patch @@ -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 +-! 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 index 00000000..eafa6ab0 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.soft_float-460.patch @@ -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 + + #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 index 00000000..05905607 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/gcc.widen_types-46.patch @@ -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 ++. */ ++ ++#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 index 00000000..fe157a89 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/files/optional_libstdc.patch @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-canadian_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-initial_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross-intermediate_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-cross_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-initial_4.6.bbappend @@ -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 index 00000000..ed27db03 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk-intermediate_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-crosssdk_4.6.bbappend @@ -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 index 00000000..83d519c6 --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-fsl.inc @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc-runtime_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/gcc_4.6.bbappend @@ -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 index 00000000..1c725f2f --- /dev/null +++ b/meta-fsl-ppc/recipes-devtools/gcc/libgcc_4.6.bbappend @@ -0,0 +1 @@ +require gcc-fsl.inc