https://gcc.gnu.org/g:e63430a924fecdd76e8860b761d940b7d007e3dd

commit e63430a924fecdd76e8860b761d940b7d007e3dd
Author: Michael Meissner <meiss...@linux.ibm.com>
Date:   Thu Jan 2 18:10:44 2025 -0500

    PR target/117251: Add PowerPC XXEVAL support to speed up SHA3 calculations
    
    The multibuff.c benchmark attached to the PR target/117251 compiled for 
Power10
    PowerPC that implement SHA3 has a slowdown in the current trunk and GCC 14
    compared to GCC 11 - GCC 13, due to excessive amounts of spilling.
    
    The main function for the multibuf.c file has 3,747 lines, all of which are
    using vector unsigned long long.  There are 696 vector rotates (all rotates 
are
    constant), 1,824 vector xor's and 600 vector andc's.
    
    In looking at it, the main thing that steps out is the reason for either
    spilling or moving variables is the support in fusion.md (generated by
    genfusion.pl) that tries to fuse the vec_andc feeding into vec_xor, and 
other
    vec_xor's feeding into vec_xor.
    
    On the powerpc for power10, there is a special fusion mode that happens if 
the
    machine has a VANDC or VXOR instruction that is adjacent to a VXOR 
instruction
    and the VANDC/VXOR feeds into the 2nd VXOR instruction.
    
    While the Power10 has 64 vector registers (which uses the XXL prefix to do
    logical operations), the fusion only works with the older Altivec 
instruction
    set (which uses the V prefix).  The Altivec instruction only has 32 vector
    registers (which are overlaid over the VSX vector registers 32-63).
    
    By having the combiner patterns fuse_vandc_vxor and fuse_vxor_vxor to do 
this
    fusion, it means that the register allocator has more register pressure for 
the
    traditional Altivec registers instead of the VSX registers.
    
    In addition, since there are vector rotates, these rotates only work on the
    traditional Altivec registers, which adds to the Altivec register pressure.
    
    Finally in addition to doing the explicit xor, andc, and rotates using the
    Altivec registers, we have to also load vector constants for the rotate 
amount
    and these registers also are allocated as Altivec registers.
    
    Current trunk and GCC 12-14 have more vector spills than GCC 11, but GCC 11 
has
    many more vector moves that the later compilers.  Thus even though it has 
way
    less spills, the vector moves are why GCC 11 have the slowest results.
    
    There is an instruction that was added in power10 (XXEVAL) that does provide
    fusion between VSX vectors that includes ANDC->XOR and XOR->XOR fusion.
    
    The latency of XXEVAL is slightly more than the fused VANDC/VXOR or 
VXOR/VXOR,
    so I have written the patch to prefer doing the Altivec instructions if they
    don't need a temporary register.
    
    Here are the results for adding support for XXEVAL for the multibuff.c
    benchmark attached to the PR.  Note that we essentially recover the speed 
with
    this patch that were lost with GCC 14 and the current trunk:
    
                                  XXEVAL    Trunk   GCC14   GCC13   GCC12    
GCC11
                                  ------    -----   -----   -----   -----    
-----
    Benchmark time in seconds       5.53     6.15    6.26    5.57    5.61     
9.56
    
    Fuse VANDC -> VXOR               209     600      600     600     600      
600
    Fuse VXOR -> VXOR                  0     240      240     120     120      
120
    XXEVAL to fuse ANDC -> XOR       391       0        0       0       0       
 0
    XXEVAL to fuse XOR -> XOR        240       0        0       0       0       
 0
    
    Spill vector to stack             78     364      364     172     184      
110
    Load spilled vector from stack   431     962      962     713     723      
166
    Vector moves                      10     100      100      70      72    
3,055
    
    Vector rotate right              696     696      696     696     696      
696
    XXLANDC or VANDC                 209     600      600     600     600      
600
    XXLXOR or VXOR                   953   1,824    1,824   1,824   1,824    
1,825
    XXEVAL                           631       0        0       0       0       
 0
    
    Load vector rotate constants      24      24       24      24      24       
24
    
    Here are the results for adding support for XXEVAL for the singlebuff.c
    benchmark attached to the PR.  Note that adding XXEVAL greatly speeds up 
this
    particular benchmark:
    
                                  XXEVAL    Trunk   GCC14   GCC13   GCC12    
GCC11
                                  ------    -----   -----   -----   -----    
-----
    Benchmark time in seconds       4.46     5.40    5.40    5.35    5.36     
7.54
    
    Fuse VANDC -> VXOR               210      600     600     600     600      
600
    Fuse VXOR -> VXOR                  0      240     240     120     120      
120
    XXEVAL to fuse ANDC -> XOR       390        0       0       0      0        
 0
    XXEVAL to fuse XOR -> XOR        240        0       0       0      0        
 0
    
    Spill vector to stack            113      379     379     382    382        
63
    Load spilled vector from stack   333      796     796     757    757        
68
    Vector moves                      34       80      80     119    119     
2,409
    
    Vector rotate right              696      696     696     696    696       
696
    XXLANDC or VANDC                 210      600     600     600    600       
600
    XXLXOR or VXOR                   954    1,824   1,824   1,824  1,824     
1,824
    XXEVAL                           630        0       0       0      0        
 0
    
    Load vector rotate constants      96       96      96      96     96        
96
    
    These patches add the following fusion patterns:
    
            xxland  => xxland       xxlandc => xxland       xxlxor  => xxland
            xxlor   => xxland       xxlnor  => xxland       xxleqv  => xxland
            xxlorc  => xxland       xxlandc => xxlandc      xxlnand => xxland
            xxlnand => xxlnor       xxland  => xxlxor       xxland  => xxlor
            xxlandc => xxlxor       xxlandc => xxlor        xxlorc  => xxlnor
            xxlorc  => xxleqv       xxlorc  => xxlorc       xxleqv  => xxlnor
            xxlxor  => xxlxor       xxlxor  => xxlor        xxlnor  => xxlnor
            xxlor   => xxlxor       xxlor   => xxlor        xxlor   => xxlnor
            xxlnor  => xxlxor       xxlnor  => xxlor        xxlxor  => xxlnor
            xxleqv  => xxlxor       xxleqv  => xxlor        xxlorc  => xxlxor
            xxlorc  => xxlor        xxlandc => xxlnor       xxlandc => xxleqv
            xxland  => xxlnor       xxlnand => xxlxor       xxlnand => xxlor
            xxlnand => xxlnand      xxlorc  => xxlnand      xxleqv  => xxlnand
            xxlnor  => xxlnand      xxlor   => xxlnand      xxlxor  => xxlnand
            xxlandc => xxlnand      xxland  => xxlnand
    
    2025-01-02  Michael Meissner  <meiss...@linux.ibm.com>
    
    gcc/
    
            PR target/117251
            * config/rs6000/fusion.md: Regenerate.
            * config/rs6000/genfusion.pl (gen_logical_addsubf): Add support to
            generate vector/vector logical fusion if XXEVAL supports the fusion.
            * config/rs6000/predicates.md (vector_fusion_operand): New 
predicate.
            * config/rs6000/rs6000.cc (rs6000_opt_vars): Add -mxxeval.
            * config/rs6000/rs6000.md (isa attribute): Add xxeval.
            (enabled attribute): Add support for -mxxeval.
            * config/rs6000/rs6000.opt (-mxxeval): New switch.
    
    gcc/testsuite/
    
            PR target/117251
            * gcc.target/powerpc/p10-vector-fused-1.c: New test.
            * gcc.target/powerpc/p10-vector-fused-2.c: Likewise.

Diff:
---
 gcc/config/rs6000/fusion.md                        | 660 +++++++++------
 gcc/config/rs6000/genfusion.pl                     | 102 ++-
 gcc/config/rs6000/predicates.md                    |  14 +-
 gcc/config/rs6000/rs6000.cc                        |   3 +
 gcc/config/rs6000/rs6000.md                        |   7 +-
 gcc/config/rs6000/rs6000.opt                       |   4 +
 .../gcc.target/powerpc/p10-vector-fused-1.c        | 409 +++++++++
 .../gcc.target/powerpc/p10-vector-fused-2.c        | 936 +++++++++++++++++++++
 8 files changed, 1865 insertions(+), 270 deletions(-)

diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md
index 621b346f9eb9..61d66129da65 100644
--- a/gcc/config/rs6000/fusion.md
+++ b/gcc/config/rs6000/fusion.md
@@ -1871,146 +1871,170 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vand
 (define_insn "*fuse_vand_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"%v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"%v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vand %3,%3,%2
    vand %3,%1,%0\;vand %3,%3,%2
    vand %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,1
    vand %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vand
 (define_insn "*fuse_vandc_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vand %3,%3,%2
    vandc %3,%1,%0\;vand %3,%3,%2
    vandc %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,2
    vandc %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vand
 (define_insn "*fuse_veqv_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vand %3,%3,%2
    veqv %3,%1,%0\;vand %3,%3,%2
    veqv %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,9
    veqv %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vand
 (define_insn "*fuse_vnand_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vand %3,%3,%2
    vnand %3,%1,%0\;vand %3,%3,%2
    vnand %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,14
    vnand %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vand
 (define_insn "*fuse_vnor_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vand %3,%3,%2
    vnor %3,%1,%0\;vand %3,%3,%2
    vnor %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,8
    vnor %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vor -> vand
 (define_insn "*fuse_vor_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vand %3,%3,%2
    vor %3,%1,%0\;vand %3,%3,%2
    vor %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,7
    vor %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vand
 (define_insn "*fuse_vorc_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vand %3,%3,%2
    vorc %3,%1,%0\;vand %3,%3,%2
    vorc %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,11
    vorc %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vand
 (define_insn "*fuse_vxor_vand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vand %3,%3,%2
    vxor %3,%1,%0\;vand %3,%3,%2
    vxor %3,%1,%0\;vand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,6
    vxor %4,%1,%0\;vand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vandc
@@ -2033,20 +2057,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vandc
 (define_insn "*fuse_vandc_vandc"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vandc %3,%3,%2
    vandc %3,%1,%0\;vandc %3,%3,%2
    vandc %3,%1,%0\;vandc %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,13
    vandc %4,%1,%0\;vandc %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vandc
@@ -2177,20 +2204,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> veqv
 (define_insn "*fuse_vandc_veqv"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (not:VM (xor:VM (and:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (not:VM (xor:VM (and:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;veqv %3,%3,%2
    vandc %3,%1,%0\;veqv %3,%3,%2
    vandc %3,%1,%0\;veqv %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,210
    vandc %4,%1,%0\;veqv %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> veqv
@@ -2267,20 +2297,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> veqv
 (define_insn "*fuse_vorc_veqv"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (not:VM (xor:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (not:VM (xor:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;veqv %3,%3,%2
    vorc %3,%1,%0\;veqv %3,%3,%2
    vorc %3,%1,%0\;veqv %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,75
    vorc %4,%1,%0\;veqv %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> veqv
@@ -2303,434 +2336,506 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vnand
 (define_insn "*fuse_vand_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vnand %3,%3,%2
    vand %3,%1,%0\;vnand %3,%3,%2
    vand %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,254
    vand %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vnand
 (define_insn "*fuse_vandc_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vnand %3,%3,%2
    vandc %3,%1,%0\;vnand %3,%3,%2
    vandc %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,253
    vandc %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vnand
 (define_insn "*fuse_veqv_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vnand %3,%3,%2
    veqv %3,%1,%0\;vnand %3,%3,%2
    veqv %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,246
    veqv %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vnand
 (define_insn "*fuse_vnand_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vnand %3,%3,%2
    vnand %3,%1,%0\;vnand %3,%3,%2
    vnand %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,241
    vnand %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vnand
 (define_insn "*fuse_vnor_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vnand %3,%3,%2
    vnor %3,%1,%0\;vnand %3,%3,%2
    vnor %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,247
    vnor %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vor -> vnand
 (define_insn "*fuse_vor_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vnand %3,%3,%2
    vor %3,%1,%0\;vnand %3,%3,%2
    vor %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,248
    vor %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vnand
 (define_insn "*fuse_vorc_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vnand %3,%3,%2
    vorc %3,%1,%0\;vnand %3,%3,%2
    vorc %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,244
    vorc %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vnand
 (define_insn "*fuse_vxor_vnand"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vnand %3,%3,%2
    vxor %3,%1,%0\;vnand %3,%3,%2
    vxor %3,%1,%0\;vnand %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,249
    vxor %4,%1,%0\;vnand %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vnor
 (define_insn "*fuse_vand_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vnor %3,%3,%2
    vand %3,%1,%0\;vnor %3,%3,%2
    vand %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,224
    vand %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vnor
 (define_insn "*fuse_vandc_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vnor %3,%3,%2
    vandc %3,%1,%0\;vnor %3,%3,%2
    vandc %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,208
    vandc %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vnor
 (define_insn "*fuse_veqv_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vnor %3,%3,%2
    veqv %3,%1,%0\;vnor %3,%3,%2
    veqv %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,96
    veqv %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vnor
 (define_insn "*fuse_vnand_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vnor %3,%3,%2
    vnand %3,%1,%0\;vnor %3,%3,%2
    vnand %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,16
    vnand %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vnor
 (define_insn "*fuse_vnor_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v"))))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vnor %3,%3,%2
    vnor %3,%1,%0\;vnor %3,%3,%2
    vnor %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,112
    vnor %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vor -> vnor
 (define_insn "*fuse_vor_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vnor %3,%3,%2
    vor %3,%1,%0\;vnor %3,%3,%2
    vor %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,128
    vor %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vnor
 (define_insn "*fuse_vorc_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"altivec_register_operand" "v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 
"vector_fusion_operand" "v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vnor %3,%3,%2
    vorc %3,%1,%0\;vnor %3,%3,%2
    vorc %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,64
    vorc %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vnor
 (define_insn "*fuse_vxor_vnor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (and:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (and:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vnor %3,%3,%2
    vxor %3,%1,%0\;vnor %3,%3,%2
    vxor %3,%1,%0\;vnor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,144
    vxor %4,%1,%0\;vnor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vor
 (define_insn "*fuse_vand_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vor %3,%3,%2
    vand %3,%1,%0\;vor %3,%3,%2
    vand %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,31
    vand %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vor
 (define_insn "*fuse_vandc_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vor %3,%3,%2
    vandc %3,%1,%0\;vor %3,%3,%2
    vandc %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,47
    vandc %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vor
 (define_insn "*fuse_veqv_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vor %3,%3,%2
    veqv %3,%1,%0\;vor %3,%3,%2
    veqv %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,159
    veqv %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vor
 (define_insn "*fuse_vnand_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vor %3,%3,%2
    vnand %3,%1,%0\;vor %3,%3,%2
    vnand %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,239
    vnand %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vor
 (define_insn "*fuse_vnor_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vor %3,%3,%2
    vnor %3,%1,%0\;vor %3,%3,%2
    vnor %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,143
    vnor %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vor -> vor
 (define_insn "*fuse_vor_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"%v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"%v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vor %3,%3,%2
    vor %3,%1,%0\;vor %3,%3,%2
    vor %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,127
    vor %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vor
 (define_insn "*fuse_vorc_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vor %3,%3,%2
    vorc %3,%1,%0\;vor %3,%3,%2
    vorc %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,191
    vorc %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vor
 (define_insn "*fuse_vxor_vor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vor %3,%3,%2
    vxor %3,%1,%0\;vor %3,%3,%2
    vxor %3,%1,%0\;vor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,111
    vxor %4,%1,%0\;vor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vorc
@@ -2843,20 +2948,23 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vorc
 (define_insn "*fuse_vorc_vorc"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (not:VM (match_operand:VM 2 "altivec_register_operand" 
"v,v,v,v"))))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (not:VM (match_operand:VM 2 "vector_fusion_operand" 
"v,v,v,wa,v"))))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vorc %3,%3,%2
    vorc %3,%1,%0\;vorc %3,%3,%2
    vorc %3,%1,%0\;vorc %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,79
    vorc %4,%1,%0\;vorc %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vorc
@@ -2879,146 +2987,170 @@
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vand -> vxor
 (define_insn "*fuse_vand_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (and:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vand %3,%1,%0\;vxor %3,%3,%2
    vand %3,%1,%0\;vxor %3,%3,%2
    vand %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,30
    vand %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vandc -> vxor
 (define_insn "*fuse_vandc_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vandc %3,%1,%0\;vxor %3,%3,%2
    vandc %3,%1,%0\;vxor %3,%3,%2
    vandc %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,45
    vandc %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector veqv -> vxor
 (define_insn "*fuse_veqv_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    veqv %3,%1,%0\;vxor %3,%3,%2
    veqv %3,%1,%0\;vxor %3,%3,%2
    veqv %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,150
    veqv %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnand -> vxor
 (define_insn "*fuse_vnand_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnand %3,%1,%0\;vxor %3,%3,%2
    vnand %3,%1,%0\;vxor %3,%3,%2
    vnand %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,225
    vnand %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vnor -> vxor
 (define_insn "*fuse_vnor_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (not:VM (match_operand:VM 1 
"altivec_register_operand" "v,v,v,v")))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (not:VM (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v")))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vnor %3,%1,%0\;vxor %3,%3,%2
    vnor %3,%1,%0\;vxor %3,%3,%2
    vnor %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,135
    vnor %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vor -> vxor
 (define_insn "*fuse_vor_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vor %3,%1,%0\;vxor %3,%3,%2
    vor %3,%1,%0\;vxor %3,%3,%2
    vor %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,120
    vor %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vorc -> vxor
 (define_insn "*fuse_vorc_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v"))
-                          (match_operand:VM 1 "altivec_register_operand" 
"v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                          (match_operand:VM 1 "vector_fusion_operand" 
"v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vorc %3,%1,%0\;vxor %3,%3,%2
    vorc %3,%1,%0\;vxor %3,%3,%2
    vorc %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,180
    vorc %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; logical-logical fusion pattern generated by gen_logical_addsubf
 ;; vector vxor -> vxor
 (define_insn "*fuse_vxor_vxor"
-  [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v")
-        (xor:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" 
"v,v,v,v")
-                          (match_operand:VM 1 "altivec_register_operand" 
"%v,v,v,v"))
-                 (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))
-   (clobber (match_scratch:VM 4 "=X,X,X,&v"))]
+  [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v")
+        (xor:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" 
"v,v,v,wa,v")
+                          (match_operand:VM 1 "vector_fusion_operand" 
"%v,v,v,wa,v"))
+                 (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))
+   (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))]
   "(TARGET_P10_FUSION)"
   "@
    vxor %3,%1,%0\;vxor %3,%3,%2
    vxor %3,%1,%0\;vxor %3,%3,%2
    vxor %3,%1,%0\;vxor %3,%3,%2
+   xxeval %x3,%x2,%x1,%x0,105
    vxor %4,%1,%0\;vxor %3,%4,%2"
   [(set_attr "type" "fused_vector")
    (set_attr "cost" "6")
-   (set_attr "length" "8")])
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
 
 ;; add-add fusion pattern generated by gen_addadd
 (define_insn "*fuse_add_add"
diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl
index e5d3b1ee449d..1258a97f8a05 100755
--- a/gcc/config/rs6000/genfusion.pl
+++ b/gcc/config/rs6000/genfusion.pl
@@ -211,25 +211,76 @@ sub gen_logical_addsubf
        $inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4,
        $bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp,
        $ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name,
-       $fuse_type);
-  KIND: foreach $kind ('scalar','vector') {
+       $fuse_type, $xxeval, $c5, $vect_pred, $vect_inner_arg0, 
$vect_inner_arg1,
+       $vect_inner_exp, $vect_outer_arg2, $vect_outer_exp);
+
+    my %xxeval_fusions = (
+      "vand_vand"   =>   1,
+      "vandc_vand"  =>   2,
+      "vxor_vand"   =>   6,
+      "vor_vand"    =>   7,
+      "vnor_vand"   =>   8,
+      "veqv_vand"   =>   9,
+      "vorc_vand"   =>  11,
+      "vandc_vandc" =>  13,
+      "vnand_vand"  =>  14,
+      "vnand_vnor"  =>  16,
+      "vand_vxor"   =>  30,
+      "vand_vor"    =>  31,
+      "vandc_vxor"  =>  45,
+      "vandc_vor"   =>  47,
+      "vorc_vnor"   =>  64,
+      "vorc_veqv"   =>  75,
+      "vorc_vorc"   =>  79,
+      "veqv_vnor"   =>  96,
+      "vxor_vxor"   => 105,
+      "vxor_vor"    => 111,
+      "vnor_vnor"   => 112,
+      "vor_vxor"    => 120,
+      "vor_vor"     => 127,
+      "vor_vnor"    => 128,
+      "vnor_vxor"   => 135,
+      "vnor_vor"    => 143,
+      "vxor_vnor"   => 144,
+      "veqv_vxor"   => 150,
+      "veqv_vor"    => 159,
+      "vorc_vxor"   => 180,
+      "vorc_vor"    => 191,
+      "vandc_vnor"  => 208,
+      "vandc_veqv"  => 210,
+      "vand_vnor"   => 224,
+      "vnand_vxor"  => 225,
+      "vnand_vor"   => 239,
+      "vnand_vnand" => 241,
+      "vorc_vnand"  => 244,
+      "veqv_vnand"  => 246,
+      "vnor_vnand"  => 247,
+      "vor_vnand"   => 248,
+      "vxor_vnand"  => 249,
+      "vandc_vnand" => 253,
+      "vand_vnand"  => 254,
+    );
+
+    KIND: foreach $kind ('scalar','vector') {
       @outer_ops = @logicals;
       if ( $kind eq 'vector' ) {
          $vchr = "v";
          $mode = "VM";
          $pred = "altivec_register_operand";
+         $vect_pred = "vector_fusion_operand";
          $constraint = "v";
          $fuse_type = "fused_vector";
       } else {
          $vchr = "";
          $mode = "GPR";
-         $pred = "gpc_reg_operand";
+         $vect_pred = $pred = "gpc_reg_operand";
          $constraint = "r";
          $fuse_type = "fused_arith_logical";
          push (@outer_ops, @addsub);
          push (@outer_ops, ( "rsubf" ));
       }
       $c4 = "${constraint},${constraint},${constraint},${constraint}";
+      $c5 = "${constraint},${constraint},${constraint},wa,${constraint}";
     OUTER: foreach $outer ( @outer_ops ) {
        $outer_name = "${vchr}${outer}";
        $is_subf = ( $outer eq "subf" );
@@ -257,29 +308,40 @@ sub gen_logical_addsubf
          $inner_inv = $invert{$inner};
          $inner_rtl = $rtlop{$inner};
          $inner_op = "${vchr}${inner}";
+
          # If both ops commute then we can specify % on operand 1
          # so the pattern will let operands 1 and 2 interchange.
          $both_commute = ($inner eq $outer) && ($commute2{$inner} == 1);
          $bc = ""; if ( $both_commute ) { $bc = "%"; }
          $inner_arg0 = "(match_operand:${mode} 0 \"${pred}\" \"${c4}\")";
          $inner_arg1 = "(match_operand:${mode} 1 \"${pred}\" \"${bc}${c4}\")";
+         $vect_inner_arg0 = "(match_operand:${mode} 0 \"${vect_pred}\" 
\"${c5}\")";
+         $vect_inner_arg1 = "(match_operand:${mode} 1 \"${vect_pred}\" 
\"${bc}${c5}\")";
          if ( ($inner_comp & 1) == 1 ) {
              $inner_arg0 = "(not:${mode} $inner_arg0)";
+             $vect_inner_arg0 = "(not:${mode} $vect_inner_arg0)";
          }
          if ( ($inner_comp & 2) == 2 ) {
              $inner_arg1 = "(not:${mode} $inner_arg1)";
+             $vect_inner_arg1 = "(not:${mode} $vect_inner_arg1)";
          }
          $inner_exp = "(${inner_rtl}:${mode} ${inner_arg0}
                           ${inner_arg1})";
+         $vect_inner_exp = "(${inner_rtl}:${mode} ${vect_inner_arg0}
+                          ${vect_inner_arg1})";
          if ( $inner_inv == 1 ) {
              $inner_exp = "(not:${mode} $inner_exp)";
+             $vect_inner_exp = "(not:${mode} $vect_inner_exp)";
          }
          $outer_arg2 = "(match_operand:${mode} 2 \"${pred}\" \"${c4}\")";
+         $vect_outer_arg2 = "(match_operand:${mode} 2 \"${vect_pred}\" 
\"${c5}\")";
          if ( ($outer_comp & 1) == 1 ) {
              $outer_arg2 = "(not:${mode} $outer_arg2)";
+             $vect_outer_arg2 = "(not:${mode} $vect_outer_arg2)";
          }
          if ( ($outer_comp & 2) == 2 ) {
              $inner_exp = "(not:${mode} $inner_exp)";
+             $vect_inner_exp = "(not:${mode} $vect_inner_exp)";
          }
          if ( $is_subf ) {
              $outer_32 = "%2,%3";
@@ -291,15 +353,23 @@ sub gen_logical_addsubf
          if ( $is_rsubf == 1 ) {
              $outer_exp = "(${outer_rtl}:${mode} ${outer_arg2}
                  ${inner_exp})";
+             $vect_outer_exp = "(${outer_rtl}:${mode} ${vect_outer_arg2}
+                 ${vect_inner_exp})";
          } else {
              $outer_exp = "(${outer_rtl}:${mode} ${inner_exp}
                  ${outer_arg2})";
+             $vect_outer_exp = "(${outer_rtl}:${mode} ${vect_inner_exp}
+                 ${vect_outer_arg2})";
          }
          if ( $outer_inv == 1 ) {
              $outer_exp = "(not:${mode} $outer_exp)";
+             $vect_outer_exp = "(not:${mode} $vect_outer_exp)";
          }
 
-         $insn =  <<"EOF";
+         # See if we can use xxeval on vector fusion
+         $xxeval = $xxeval_fusions{"${inner_op}_${outer_name}"};
+         if (!$xxeval) {
+             $insn =  <<"EOF";
 
 ;; $ftype fusion pattern generated by gen_logical_addsubf
 ;; $kind $inner_op -> $outer_name
@@ -318,6 +388,30 @@ sub gen_logical_addsubf
    (set_attr "length" "8")])
 EOF
 
+         } else {
+             $insn =  <<"EOF";
+
+;; $ftype fusion pattern generated by gen_logical_addsubf
+;; $kind $inner_op -> $outer_name
+(define_insn "*fuse_${inner_op}_${outer_name}"
+  [(set (match_operand:${mode} 3 "${vect_pred}" 
"=&0,&1,&${constraint},wa,${constraint}")
+        ${vect_outer_exp})
+   (clobber (match_scratch:${mode} 4 "=X,X,X,X,&${constraint}"))]
+  "(TARGET_P10_FUSION)"
+  "@
+   ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
+   ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
+   ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32}
+   xxeval %x3,%x2,%x1,%x0,${xxeval}
+   ${inner_op} %4,%1,%0\\;${outer_op} %3,${outer_42}"
+  [(set_attr "type" "$fuse_type")
+   (set_attr "cost" "6")
+   (set_attr "length" "8")
+   (set_attr "prefixed" "*,*,*,yes,*")
+   (set_attr "isa" "*,*,*,xxeval,*")])
+EOF
+         }
+
          print $insn;
       }
     }
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 647e89afb6a7..6485ee3eeecc 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -82,7 +82,7 @@
   return ALTIVEC_REGNO_P (REGNO (op));
 })
 
-;; Return 1 if op is a VSX register.
+;; Return 1 if op is a VSX register
 (define_predicate "vsx_register_operand"
   (match_operand 0 "register_operand")
 {
@@ -119,6 +119,18 @@
   return VSX_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if op is a register that can be used for vector fusion.  If XXEVAL
+;; is supported, return true for all VSX registers, otherwise the fusion is
+;; limited to Altivec registers since the machine only fuses Altivec
+;; operations.
+(define_predicate "vector_fusion_operand"
+  (match_operand 0 "register_operand")
+{
+  return (TARGET_XXEVAL && TARGET_PREFIXED
+         ? vsx_register_operand (op, mode)
+         : altivec_register_operand (op, mode));
+})
+
 ;; Return 1 if op is a vector register that operates on floating point vectors
 ;; (either altivec or VSX).
 (define_predicate "vfloat_operand"
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index f9f9a0b931db..c30aa15ca50f 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -24663,6 +24663,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] =
   { "speculate-indirect-jumps",
     offsetof (struct gcc_options, x_rs6000_speculate_indirect_jumps),
     offsetof (struct cl_target_option, x_rs6000_speculate_indirect_jumps), },
+  { "xxeval",
+    offsetof (struct gcc_options, x_TARGET_XXEVAL),
+    offsetof (struct cl_target_option, x_TARGET_XXEVAL), },
 };
 
 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4c2bc81caf56..3b876462ec32 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -369,7 +369,7 @@
   (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
 
 ;; The ISA we implement.
-(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10"
+(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval"
   (const_string "any"))
 
 ;; Is this alternative enabled for the current CPU/ISA/etc.?
@@ -421,6 +421,11 @@
      (and (eq_attr "isa" "p10")
          (match_test "TARGET_POWER10"))
      (const_int 1)
+
+     (and (eq_attr "isa" "xxeval")
+         (match_test "TARGET_PREFIXED && TARGET_XXEVAL"))
+     (const_int 1)
+
     ] (const_int 0)))
 
 ;; If this instruction is microcoded on the CELL processor
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 360dd3a61e7f..dd74bce90993 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -631,6 +631,10 @@ mieee128-constant
 Target Var(TARGET_IEEE128_CONSTANT) Init(1) Save
 Generate (do not generate) code that uses the LXVKQ instruction.
 
+mxxeval
+Target Undocumented Var(TARGET_XXEVAL) Init(1) Save
+Generate (do not generate) code that uses the XXEVAL instruction.
+
 ; Documented parameters
 
 -param=rs6000-vect-unroll-limit=
diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c 
b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c
new file mode 100644
index 000000000000..28e0874b3454
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c
@@ -0,0 +1,409 @@
+/* { dg-do run } */
+/* { dg-require-effective-target power10_hw } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+/* Generate and check most of the vector logical instruction combinations that
+   may or may not generate xxeval to do a fused operation on power10.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <altivec.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+
+static int errors = 0;
+static int tests  = 0;
+#endif
+
+typedef vector unsigned int    vector_t;
+typedef unsigned int           scalar_t;
+
+/* Vector logical functions.  */
+static inline vector_t
+vector_and (vector_t x, vector_t y)
+{
+  return x & y;
+}
+
+static inline vector_t
+vector_or (vector_t x, vector_t y)
+{
+  return x | y;
+}
+
+static inline vector_t
+vector_xor (vector_t x, vector_t y)
+{
+  return x ^ y;
+}
+
+static inline vector_t
+vector_andc (vector_t x, vector_t y)
+{
+  return x & ~y;
+}
+
+static inline vector_t
+vector_orc (vector_t x, vector_t y)
+{
+  return x | ~y;
+}
+
+static inline vector_t
+vector_nand (vector_t x, vector_t y)
+{
+  return ~(x & y);
+}
+
+static inline vector_t
+vector_nor (vector_t x, vector_t y)
+{
+  return ~(x | y);
+}
+
+static inline vector_t
+vector_eqv (vector_t x, vector_t y)
+{
+  return ~(x ^ y);
+}
+
+/* Scalar logical functions.  */
+static inline scalar_t
+scalar_and (scalar_t x, scalar_t y)
+{
+  return x & y;
+}
+
+static inline scalar_t
+scalar_or (scalar_t x, scalar_t y)
+{
+  return x | y;
+}
+
+static inline scalar_t
+scalar_xor (scalar_t x, scalar_t y)
+{
+  return x ^ y;
+}
+
+static inline scalar_t
+scalar_andc (scalar_t x, scalar_t y)
+{
+  return x & ~y;
+}
+
+static inline scalar_t
+scalar_orc (scalar_t x, scalar_t y)
+{
+  return x | ~y;
+}
+
+static inline scalar_t
+scalar_nand (scalar_t x, scalar_t y)
+{
+  return ~(x & y);
+}
+
+static inline scalar_t
+scalar_nor (scalar_t x, scalar_t y)
+{
+  return ~(x | y);
+}
+
+static inline scalar_t
+scalar_eqv (scalar_t x, scalar_t y)
+{
+  return ~(x ^ y);
+}
+
+
+/*
+ * Generate one function for each combination that we are checking.  Do 4
+ * operations:
+ *
+ * Use FPR regs that should generate either XXEVAL or XXL* insns;
+ * Use Altivec registers than may generated fused V* insns;
+ * Use VSX registers, insure fusing it not done via asm; (and)
+ * Use GPR registers on scalar operations.
+ */
+
+#ifdef DEBUG
+#define TRACE(INNER, OUTER)                                            \
+  do {                                                                 \
+    tests++;                                                           \
+    printf ("%s_%s\n", INNER, OUTER);                                  \
+    fflush (stdout);                                                   \
+  } while (0)                                                          \
+
+#define FAILED(INNER, OUTER)                                           \
+  do {                                                                 \
+    errors++;                                                          \
+    printf ("%s_%s failed\n", INNER, OUTER);                           \
+    fflush (stdout);                                                   \
+  } while (0)                                                          \
+
+#else
+#define TRACE(INNER, OUTER)
+#define FAILED(INNER, OUTER)   abort ()
+#endif
+
+#define FUSED_FUNC(INNER, OUTER)                                       \
+static void                                                            \
+INNER ## _ ## OUTER (vector_t a, vector_t b, vector_t c)               \
+{                                                                      \
+  vector_t f_a, f_b, f_c, f_r, f_t;                                    \
+  vector_t v_a, v_b, v_c, v_r, v_t;                                    \
+  vector_t w_a, w_b, w_c, w_r, w_t;                                    \
+  scalar_t s_a, s_b, s_c, s_r, s_t;                                    \
+                                                                       \
+  TRACE (#INNER, #OUTER);                                              \
+                                                                       \
+  f_a = a;                                                             \
+  f_b = b;                                                             \
+  f_c = c;                                                             \
+                                                                       \
+  __asm__ (" # fpr regs: %x0,%x1,%x2 " #INNER "_" #OUTER               \
+          : "+d" (f_a),                                                \
+            "+d" (f_b),                                                \
+            "+d" (f_c));                                               \
+                                                                       \
+  f_t = vector_ ## INNER (f_b, f_c);                                   \
+  f_r = vector_ ## OUTER (f_a, f_t);                                   \
+                                                                       \
+  __asm__ (" # fpr regs result: %x0 " #INNER "_" #OUTER                        
\
+          : "+d" (f_r));                                               \
+                                                                       \
+  v_a = a;                                                             \
+  v_b = b;                                                             \
+  v_c = c;                                                             \
+                                                                       \
+  __asm__ (" # altivec regs: %x0,%x1,%x2 " #INNER "_" #OUTER           \
+          : "+v" (v_a),                                                \
+            "+v" (v_b),                                                \
+            "+v" (v_c));                                               \
+                                                                       \
+  v_t = vector_ ## INNER (v_b, v_c);                                   \
+  v_r = vector_ ## OUTER (v_a, v_t);                                   \
+                                                                       \
+  __asm__ (" # altivec regs result: %x0 " #INNER "_" #OUTER            \
+          : "+v" (v_r));                                               \
+                                                                       \
+  w_a = a;                                                             \
+  w_b = b;                                                             \
+  w_c = c;                                                             \
+                                                                       \
+  __asm__ (" # vsx regs: %x0,%x1,%x2 " #INNER "_" #OUTER               \
+          : "+wa" (w_a),                                               \
+            "+wa" (w_b),                                               \
+            "+wa" (w_c));                                              \
+                                                                       \
+  w_t = vector_ ## INNER (w_b, w_c);                                   \
+  __asm__ ("nop # break vsx fusion reg %x0" : "+wa" (w_t));            \
+  w_r = vector_ ## OUTER (w_a, w_t);                                   \
+                                                                       \
+  __asm__ (" # vsx regs result: %x0 " #INNER "_" #OUTER                        
\
+          : "+wa" (w_r));                                              \
+                                                                       \
+  s_a = a[0];                                                          \
+  s_b = b[0];                                                          \
+  s_c = c[0];                                                          \
+                                                                       \
+  __asm__ (" # gpr regs: %0,%1,%2 " #INNER "_" #OUTER                  \
+          : "+r" (s_a),                                                \
+            "+r" (s_b),                                                \
+            "+r" (s_c));                                               \
+                                                                       \
+  s_t = scalar_ ## INNER (s_b, s_c);                                   \
+  s_r = scalar_ ## OUTER (s_a, s_t);                                   \
+                                                                       \
+  __asm__ (" # gpr regs result: %0 " #INNER "_" #OUTER                 \
+          : "+r" (s_r));                                               \
+                                                                       \
+  if (!vec_all_eq (w_r, f_r)                                           \
+      || !vec_all_eq (w_r, v_r)                                                
\
+      || s_r != w_r[0])                                                        
\
+    FAILED (#INNER, #OUTER);                                           \
+                                                                       \
+  return;                                                              \
+}
+
+FUSED_FUNC (and,  and)
+FUSED_FUNC (andc, and)
+FUSED_FUNC (eqv,  and)
+FUSED_FUNC (nand, and)
+FUSED_FUNC (nor,  and)
+FUSED_FUNC (or,   and)
+FUSED_FUNC (orc,  and)
+FUSED_FUNC (xor,  and)
+
+FUSED_FUNC (and,  andc)
+FUSED_FUNC (andc, andc)
+FUSED_FUNC (eqv,  andc)
+FUSED_FUNC (nand, andc)
+FUSED_FUNC (nor,  andc)
+FUSED_FUNC (or,   andc)
+FUSED_FUNC (orc,  andc)
+FUSED_FUNC (xor,  andc)
+
+FUSED_FUNC (and,  eqv)
+FUSED_FUNC (andc, eqv)
+FUSED_FUNC (eqv,  eqv)
+FUSED_FUNC (nand, eqv)
+FUSED_FUNC (nor,  eqv)
+FUSED_FUNC (or,   eqv)
+FUSED_FUNC (orc,  eqv)
+FUSED_FUNC (xor,  eqv)
+
+FUSED_FUNC (and,  nand)
+FUSED_FUNC (andc, nand)
+FUSED_FUNC (eqv,  nand)
+FUSED_FUNC (nand, nand)
+FUSED_FUNC (nor,  nand)
+FUSED_FUNC (or,   nand)
+FUSED_FUNC (orc,  nand)
+FUSED_FUNC (xor,  nand)
+
+FUSED_FUNC (and,  nor)
+FUSED_FUNC (andc, nor)
+FUSED_FUNC (eqv,  nor)
+FUSED_FUNC (nand, nor)
+FUSED_FUNC (nor,  nor)
+FUSED_FUNC (or,   nor)
+FUSED_FUNC (orc,  nor)
+FUSED_FUNC (xor,  nor)
+
+FUSED_FUNC (and,  or)
+FUSED_FUNC (andc, or)
+FUSED_FUNC (eqv,  or)
+FUSED_FUNC (nand, or)
+FUSED_FUNC (nor,  or)
+FUSED_FUNC (or,   or)
+FUSED_FUNC (orc,  or)
+FUSED_FUNC (xor,  or)
+
+FUSED_FUNC (and,  orc)
+FUSED_FUNC (andc, orc)
+FUSED_FUNC (eqv,  orc)
+FUSED_FUNC (nand, orc)
+FUSED_FUNC (nor,  orc)
+FUSED_FUNC (or,   orc)
+FUSED_FUNC (orc,  orc)
+FUSED_FUNC (xor,  orc)
+
+FUSED_FUNC (and,  xor)
+FUSED_FUNC (andc, xor)
+FUSED_FUNC (eqv,  xor)
+FUSED_FUNC (nand, xor)
+FUSED_FUNC (nor,  xor)
+FUSED_FUNC (or,   xor)
+FUSED_FUNC (orc,  xor)
+FUSED_FUNC (xor,  xor)
+
+
+/* List of functions to check.  */
+typedef void func_t (vector_t,
+                    vector_t,
+                    vector_t);
+
+typedef func_t *ptr_func_t;
+
+static ptr_func_t functions[] = {
+  and_and,
+  andc_and,
+  eqv_and,
+  nand_and,
+  nor_and,
+  or_and,
+  orc_and,
+  xor_and,
+
+  and_andc,
+  andc_andc,
+  eqv_andc,
+  nand_andc,
+  nor_andc,
+  or_andc,
+  orc_andc,
+  xor_andc,
+
+  and_eqv,
+  andc_eqv,
+  eqv_eqv,
+  nand_eqv,
+  nor_eqv,
+  or_eqv,
+  orc_eqv,
+  xor_eqv,
+
+  and_nand,
+  andc_nand,
+  eqv_nand,
+  nand_nand,
+  nor_nand,
+  or_nand,
+  orc_nand,
+  xor_nand,
+
+  and_nor,
+  andc_nor,
+  eqv_nor,
+  nand_nor,
+  nor_nor,
+  or_nor,
+  orc_nor,
+  xor_nor,
+
+  and_or,
+  andc_or,
+  eqv_or,
+  nand_or,
+  nor_or,
+  or_or,
+  orc_or,
+  xor_or,
+
+  and_orc,
+  andc_orc,
+  eqv_orc,
+  nand_orc,
+  nor_orc,
+  or_orc,
+  orc_orc,
+  xor_orc,
+
+  and_xor,
+  andc_xor,
+  eqv_xor,
+  nand_xor,
+  nor_xor,
+  or_xor,
+  orc_xor,
+  xor_xor,
+};
+
+
+int
+main (void)
+{
+  scalar_t s_a = 0x0fu;
+  scalar_t s_b = 0xaau;
+  scalar_t s_c = 0xccu;
+
+  vector_t a = (vector_t) { s_a,  s_a, ~s_a, ~s_a };
+  vector_t b = (vector_t) { s_b, ~s_b,  s_b, ~s_b };
+  vector_t c = (vector_t) { s_c, ~s_c, ~s_c,  s_c };
+
+  size_t i;
+
+  for (i = 0; i < sizeof (functions) / sizeof (functions[0]); i++)
+    functions[i] (a, b, c);
+
+#ifdef DEBUG
+  printf ("Done, %d tests, %d failures\n", tests, errors);
+  return errors;
+
+#else
+  return 0;
+#endif
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c 
b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c
new file mode 100644
index 000000000000..f074622c9f67
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c
@@ -0,0 +1,936 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+/* Make sure all of the fusion cases that generate the xxeval instruction
+   actually generate it.  */
+typedef vector unsigned int vector_t;
+
+static inline vector_t
+vector_and (vector_t x, vector_t y)
+{
+  return x & y;
+}
+
+static inline vector_t
+vector_or (vector_t x, vector_t y)
+{
+  return x | y;
+}
+
+static inline vector_t
+vector_xor (vector_t x, vector_t y)
+{
+  return x ^ y;
+}
+
+static inline vector_t
+vector_andc (vector_t x, vector_t y)
+{
+  return x & ~y;
+}
+
+static inline vector_t
+vector_orc (vector_t x, vector_t y)
+{
+  return x | ~y;
+}
+
+static inline vector_t
+vector_nand (vector_t x, vector_t y)
+{
+  return ~(x & y);
+}
+
+static inline vector_t
+vector_nor (vector_t x, vector_t y)
+{
+  return ~(x | y);
+}
+
+static inline vector_t
+vector_eqv (vector_t x, vector_t y)
+{
+  return ~(x ^ y);
+}
+
+void
+and_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,1.  */
+  r = vector_and (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+and_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,14.  */
+  r = vector_andc (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+and_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,31.  */
+  r = vector_or (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+and_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,239.  */
+  r = vector_orc (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+and_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,30.  */
+  r = vector_xor (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,14.  */
+  r = vector_andc (a, vector_and (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,11.  */
+  r = vector_andc (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,210.  */
+  r = vector_eqv (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,239.  */
+  r = vector_nand (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,47.  */
+  r = vector_or (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,191.  */
+  r = vector_orc (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+andc_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,45.  */
+  r = vector_xor (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+eqv_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,9.  */
+  r = vector_and (a, vector_eqv (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+eqv_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,210.  */
+  r = vector_eqv (a, vector_andc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+eqv_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,105.  */
+  r = vector_eqv (a, vector_eqv (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+eqv_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,159.  */
+  r = vector_or (a, vector_eqv (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+eqv_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,111.  */
+  r = vector_orc (a, vector_eqv (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nand_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,14.  */
+  r = vector_and (a, vector_nand (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nand_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,1.  */
+  r = vector_andc (a, vector_nand (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nand_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,30.  */
+  r = vector_eqv (a, vector_nand (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nand_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,2.  */
+  r = vector_nor (a, vector_nand (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nand_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,31.  */
+  r = vector_orc (a, vector_nand (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,8.  */
+  r = vector_and (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,7.  */
+  r = vector_andc (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,120.  */
+  r = vector_eqv (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,191.  */
+  r = vector_nand (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,143.  */
+  r = vector_or (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+nor_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,127.  */
+  r = vector_orc (a, vector_nor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+or_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,7.  */
+  r = vector_and (a, vector_or (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+or_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,8.  */
+  r = vector_andc (a, vector_or (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+or_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,127.  */
+  r = vector_or (a, vector_or (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+or_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,143.  */
+  r = vector_orc (a, vector_or (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+or_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,120.  */
+  r = vector_xor (a, vector_or (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,11.  */
+  r = vector_and (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,2.  */
+  r = vector_andc (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,75.  */
+  r = vector_eqv (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_nor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,8.  */
+  r = vector_nor (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,191.  */
+  r = vector_or (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,47.  */
+  r = vector_orc (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+orc_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,180.  */
+  r = vector_xor (a, vector_orc (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,6.  */
+  r = vector_and (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,9.  */
+  r = vector_andc (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,249.  */
+  r = vector_nand (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,111.  */
+  r = vector_or (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,159.  */
+  r = vector_orc (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+void
+xor_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r)
+{
+  vector_t a = *p_a;
+  vector_t b = *p_b;
+  vector_t c = *p_c;
+  vector_t r;
+
+  __asm__ (" # force fpr registers, %x0,%x1,%x2"
+          : "+d" (a), "+d" (b), "+d" (c));
+
+  /* xxeval r,a,b,c,105.  */
+  r = vector_xor (a, vector_xor (b, c));
+
+  __asm__ (" # force fpr result, %x0" : "+d" (r));
+  *p_r = r;
+  return;
+}
+
+/* Make sure none of traditional logical instructions are generated.  Skip
+   checking for xxlor in case the register allocator decides to add some vector
+   moves.  */
+/* { dg-final { scan-assembler-not   {\mv(and|or|xor|andc|orc|nand|nor|eqv)\M} 
} } */
+/* { dg-final { scan-assembler-not   {\mxxl(and|xor|andc|orc|nand|nor|eqv)\M}  
} } */
+/* { dg-final { scan-assembler-times {\mxxeval\M} 46 } } */

Reply via email to