On Wed, Aug 19, 2015 at 07:41:24AM -0500, Segher Boessenkool wrote:
> On Fri, Aug 14, 2015 at 11:46:03AM -0400, Michael Meissner wrote:
> > +;; Like int_reg_operand, but don't return true for pseudo registers
> > +(define_predicate "int_reg_operand_not_pseudo"
> > +  (match_operand 0 "register_operand")
> > +{
> > +  if ((TARGET_E500_DOUBLE || TARGET_SPE) && invalid_e500_subreg (op, mode))
> > +    return 0;
> > +
> > +  if (GET_CODE (op) == SUBREG)
> > +    op = SUBREG_REG (op);
> > +
> > +  if (!REG_P (op))
> > +    return 0;
> > +
> > +  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
> > +    return 0;
> > +
> > +  return INT_REGNO_P (REGNO (op));
> > +})
> 
> Since you use this only once, maybe it is easier (to read, etc.) if you
> just test it there?  Hard regs do not get subregs.

I was worried about hard regs appearing before reload, and possibly being
subregs, so I'll remove the SUBREG test.

> > +(define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
> > +  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
> > +   (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
> > +   (clobber (match_scratch:V16QI 2 "=v"))]
> > +  "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
> > +  "#"
> > +  "&& 1"
> > +  [(parallel [(set (match_dup 0)
> > +              (neg:TFIFKF (match_dup 1)))
> > +         (use (match_dup 2))])]
> > +{
> > +  if (GET_CODE (operands[2]) == SCRATCH)
> > +    operands[2] = gen_reg_rtx (V16QImode);
> > +
> > +  operands[3] = gen_reg_rtx (V16QImode);
> > +  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
> > +}
> > +  [(set_attr "length" "8")
> > +   (set_attr "type" "vecsimple")])
> 
> Where is operands[3] used?  I guess that whole line should be deleted?

Good catch. It was from the earlier patch before the fix for PR 67071, which
added better support for vector constants that can be constructed with several
vector operations, including a vector octet shift.

> > +(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
> > +  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
> > +   (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
> > +   (use (match_operand:V16QI 2 "register_operand" "=v"))]
> > +  "TARGET_FLOAT128"
> > +  "xxlxor %x0,%x1,%x2"
> > +  [(set_attr "length" "4")
> > +   (set_attr "type" "vecsimple")])
> 
> Length 4 is default, you can just leave it out (like we do for most
> machine insns already).

Ok, though I tend to always put them in.

Here is the revised patch. Is it ok to install?

2015-08-25  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        * config/rs6000/predicates.md (int_reg_operand_not_pseudo): New
        predicate for only GPR hard registers.

        * config/rs6000/rs6000.md (FP): Add IEEE 128-bit floating point
        modes to iterators. Add new iterators for moving 128-bit values in
        scalar FPR registers and VSX registers.
        (FMOVE128): Likewise.
        (FMOVE128_FPR): Likewise.
        (FMOVE128_GPR): Likewise.
        (FMOVE128_VSX): Likewise.
        (FLOAT128_SFDFTF): New iterators for IEEE 128-bit floating point
        in VSX registers.
        (IFKF): Likewise.
        (IBM128): Likewise.
        (TFIFKF): Likewise.
        (RELOAD): Add IEEE 128-bit floating point modes.
        (signbittf2): Convert TF insns to add support for new IEEE 128-bit
        floating point in VSX registers modes.
        (signbit<mode>2, IBM128 iterator): Likewise.
        (mov<mode>_64bit_dm, FMOVE128_FPR iterator): Likewise.
        (mov<mode>_32bit, FMOVE128_FPR iterator): Likewise.
        (negtf2): Likewise.
        (neg<mode>2, TFIFKF iterator): Likewise.
        (negtf2_internal): Likewise.
        (abstf2): Likewise.
        (abs<mode>2, TFIFKF iterator): Likewise.
        (ieee_128bit_negative_zero): New IEEE 128-bit floating point in
        VSX insn support for negate, absolute value, and negative absolute
        value.
        (ieee_128bit_vsx_neg<mode>2): Likewise.
        (ieee_128bit_vsx_neg<mode>2_internal): Likewise.
        (ieee_128bit_vsx_abs<mode>2): Likewise.
        (ieee_128bit_vsx_abs<mode>2_internal): Likewise.
        (ieee_128bit_vsx_nabs<mode>2): Likewise.
        (ieee_128bit_vsx_nabs<mode>2_internal): Likewise.
        (FP128_64): Update pack/unpack 128-bit insns for IEEE 128-bit
        floating point in VSX registers.
        (unpack<mode>_dm): Likewise.
        (unpack<mode>_nodm): Likewise.
        (pack<mode>): Likewise.
        (unpackv1ti): Likewise.
        (unpack<mode>, FMOVE128_VSX iterator): Likewise.
        (packv1ti): Likewise.
        (pack<mode>, FMOVE128_VSX iterator): Likewise.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md     (revision 227180)
+++ gcc/config/rs6000/predicates.md     (working copy)
@@ -239,6 +239,25 @@ (define_predicate "int_reg_operand"
   return INT_REGNO_P (REGNO (op));
 })
 
+;; Like int_reg_operand, but don't return true for pseudo registers
+(define_predicate "int_reg_operand_not_pseudo"
+  (match_operand 0 "register_operand")
+{
+  if ((TARGET_E500_DOUBLE || TARGET_SPE) && invalid_e500_subreg (op, mode))
+    return 0;
+
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  if (REGNO (op) >= FIRST_PSEUDO_REGISTER)
+    return 0;
+
+  return INT_REGNO_P (REGNO (op));
+})
+
 ;; Like int_reg_operand, but only return true for base registers
 (define_predicate "base_reg_operand"
   (match_operand 0 "int_reg_operand")
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 227180)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -348,6 +348,8 @@ (define_mode_iterator FP [
    && TARGET_HARD_FLOAT
    && (TARGET_FPRS || TARGET_E500_DOUBLE)
    && TARGET_LONG_DOUBLE_128")
+  (IF "TARGET_FLOAT128")
+  (KF "TARGET_FLOAT128")
   (DD "TARGET_DFP")
   (TD "TARGET_DFP")])
 
@@ -365,9 +367,14 @@ (define_mode_iterator FMA_F [
 (define_mode_iterator FMOVE32 [SF SD])
 (define_mode_iterator FMOVE64 [DF DD])
 (define_mode_iterator FMOVE64X [DI DF DD])
-(define_mode_iterator FMOVE128 [(TF "!TARGET_IEEEQUAD && 
TARGET_LONG_DOUBLE_128")
+(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
+                               (IF "TARGET_LONG_DOUBLE_128")
                                (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
 
+(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
+                                   (IF "FLOAT128_2REG_P (IFmode)")
+                                   (TD "TARGET_HARD_FLOAT && TARGET_FPRS")])
+
 ; Iterators for 128 bit types for direct move
 (define_mode_iterator FMOVE128_GPR [(TI    "TARGET_VSX_TIMODE")
                                    (V16QI "")
@@ -376,7 +383,13 @@ (define_mode_iterator FMOVE128_GPR [(TI 
                                    (V4SF  "")
                                    (V2DI  "")
                                    (V2DF  "")
-                                   (V1TI  "")])
+                                   (V1TI  "")
+                                   (KF    "")
+                                   (TF    "")
+                                   (IF    "")])
+
+; Iterator for 128-bit VSX types for pack/unpack
+(define_mode_iterator FMOVE128_VSX [V1TI KF])
 
 ; Whether a floating point move is ok, don't allow SD without hardware FP
 (define_mode_attr fmove_ok [(SF "")
@@ -432,6 +445,25 @@ (define_mode_iterator RECIPF [SF DF V4SF
 ; Iterator for just SF/DF
 (define_mode_iterator SFDF [SF DF])
 
+; Iterator for float128 floating conversions
+(define_mode_iterator FLOAT128_SFDFTF [
+    (SF "TARGET_FLOAT128")
+    (DF "TARGET_FLOAT128")
+    (TF "FLOAT128_IBM_P (TFmode)")
+    (IF "TARGET_FLOAT128")])
+
+; Iterator for special 128-bit floating point.  This is for non-default
+; conversions, so TFmode is not used here.
+(define_mode_iterator IFKF [IF KF])
+
+; Iterator for 128-bit floating point that uses the IBM double-double format
+(define_mode_iterator IBM128 [IF TF])
+
+; Iterator for 128-bit floating point
+(define_mode_iterator TFIFKF [(KF "TARGET_FLOAT128")
+                             (IF "TARGET_FLOAT128")
+                             (TF "TARGET_LONG_DOUBLE_128")])
+
 ; SF/DF suffix for traditional floating instructions
 (define_mode_attr Ftrad                [(SF "s") (DF "")])
 
@@ -596,7 +628,7 @@ (define_mode_attr BOOL_REGS_UNARY   [(TI    "
 ;; Reload iterator for creating the function to allocate a base register to
 ;; supplement addressing modes.
 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
-                             SF SD SI DF DD DI TI PTI])
+                             SF SD SI DF DD DI TI PTI KF IF TF])
 
 
 ;; Start with fixed-point load and store insns.  Here we put only the more
@@ -4216,19 +4248,18 @@ (define_insn "*truncdfsf2_fpr"
 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
 ;; builtins.c and optabs.c that are not correct for IBM long double
 ;; when little-endian.
-(define_expand "signbittf2"
+(define_expand "signbit<mode>2"
   [(set (match_dup 2)
-       (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))
+       (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "")))
    (set (match_dup 3)
        (subreg:DI (match_dup 2) 0))
    (set (match_dup 4)
        (match_dup 5))
    (set (match_operand:SI 0 "gpc_reg_operand" "")
        (match_dup 6))]
-  "!TARGET_IEEEQUAD
+  "FLOAT128_IBM_P (<MODE>mode)
    && TARGET_HARD_FLOAT
-   && (TARGET_FPRS || TARGET_E500_DOUBLE)
-   && TARGET_LONG_DOUBLE_128"
+   && (TARGET_FPRS || TARGET_E500_DOUBLE)"
 {
   operands[2] = gen_reg_rtx (DFmode);
   operands[3] = gen_reg_rtx (DImode);
@@ -6402,9 +6433,10 @@ (define_expand "mov<mode>"
 ;; problematical.  Don't allow direct move for this case.
 
 (define_insn_and_split "*mov<mode>_64bit_dm"
-  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" 
"=m,d,d,ws,Y,r,r,r,wm")
-       (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
+  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" 
"=m,d,d,ws,Y,r,r,r,wm")
+       (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r,wm,r"))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
+   && FLOAT128_2REG_P (<MODE>mode)
    && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -6427,9 +6459,12 @@ (define_insn_and_split "*movtd_64bit_nod
   [(set_attr "length" "8,8,8,8,12,12,8")])
 
 (define_insn_and_split "*mov<mode>_32bit"
-  [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
-       (match_operand:FMOVE128 1 "input_operand" "d,m,d,j,r,jY,r"))]
+  [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,ws,Y,r,r")
+       (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,j,r,jY,r"))]
   "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64
+   && (FLOAT128_2REG_P (<MODE>mode)
+       || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
+       || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
   "#"
@@ -6663,20 +6698,37 @@ (define_insn_and_split "*fix_trunctfsi2_
   DONE;
 })
 
-(define_expand "negtf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-       (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT
-   && (TARGET_FPRS || TARGET_E500_DOUBLE)
-   && TARGET_LONG_DOUBLE_128"
-  "")
+(define_expand "neg<mode>2"
+  [(set (match_operand:TFIFKF 0 "gpc_reg_operand" "")
+       (neg:TFIFKF (match_operand:TFIFKF 1 "gpc_reg_operand" "")))]
+  "FLOAT128_IEEE_P (<MODE>mode)
+   || (FLOAT128_IBM_P (<MODE>mode)
+       && TARGET_HARD_FLOAT
+       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
+  "
+{
+  if (FLOAT128_IEEE_P (<MODE>mode))
+    {
+      if (TARGET_FLOAT128)
+       emit_insn (gen_ieee_128bit_vsx_neg<mode>2 (operands[0], operands[1]));
+      else
+       {
+         rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
+         rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
+                                               <MODE>mode, 1,
+                                               operands[1], <MODE>mode);
+
+         if (target && !rtx_equal_p (target, operands[0]))
+           emit_move_insn (operands[0], target);
+       }
+      DONE;
+    }
+}")
 
 (define_insn "negtf2_internal"
   [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
        (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)"
   "*
 {
   if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
@@ -6687,16 +6739,29 @@ (define_insn "negtf2_internal"
   [(set_attr "type" "fp")
    (set_attr "length" "8")])
 
-(define_expand "abstf2"
-  [(set (match_operand:TF 0 "gpc_reg_operand" "")
-       (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
-  "!TARGET_IEEEQUAD
-   && TARGET_HARD_FLOAT
-   && (TARGET_FPRS || TARGET_E500_DOUBLE)
-   && TARGET_LONG_DOUBLE_128"
+(define_expand "abs<mode>2"
+  [(set (match_operand:TFIFKF 0 "gpc_reg_operand" "")
+       (abs:TFIFKF (match_operand:TFIFKF 1 "gpc_reg_operand" "")))]
+  "FLOAT128_IEEE_P (<MODE>mode)
+   || (FLOAT128_IBM_P (<MODE>mode)
+       && TARGET_HARD_FLOAT
+       && (TARGET_FPRS || TARGET_E500_DOUBLE))"
   "
 {
-  rtx label = gen_label_rtx ();
+  rtx label;
+
+  if (FLOAT128_IEEE_P (<MODE>mode))
+    {
+      if (TARGET_FLOAT128)
+       {
+         emit_insn (gen_ieee_128bit_vsx_abs<mode>2 (operands[0], operands[1]));
+         DONE;
+       }
+      else
+       FAIL;
+    }
+
+  label = gen_label_rtx ();
   if (TARGET_E500_DOUBLE)
     {
       if (flag_finite_math_only && !flag_trapping_math)
@@ -6732,6 +6797,126 @@ (define_expand "abstf2_internal"
   operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
   operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
 }")
+
+
+;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
+;; register
+
+(define_expand "ieee_128bit_negative_zero"
+  [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
+  "TARGET_FLOAT128"
+{
+  rtvec v = rtvec_alloc (16);
+  int i, high;
+
+  for (i = 0; i < 16; i++)
+    RTVEC_ELT (v, i) = const0_rtx;
+
+  high = (BYTES_BIG_ENDIAN) ? 0 : 15;
+  RTVEC_ELT (v, high) = GEN_INT (0x80);
+
+  rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
+  DONE;
+})
+
+;; IEEE 128-bit negate
+
+;; We have 2 insns here for negate and absolute value.  The first uses
+;; match_scratch so that phases like combine can recognize neg/abs as generic
+;; insns, and second insn after the first split pass loads up the bit to
+;; twiddle the sign bit.  Later GCSE passes can then combine multiple uses of
+;; neg/abs to create the constant just once.
+
+(define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+   (clobber (match_scratch:V16QI 2 "=v"))]
+  "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+                  (neg:TFIFKF (match_dup 1)))
+             (use (match_dup 2))])]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (V16QImode);
+
+  operands[3] = gen_reg_rtx (V16QImode);
+  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
+}
+  [(set_attr "length" "8")
+   (set_attr "type" "vecsimple")])
+
+(define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (neg:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+   (use (match_operand:V16QI 2 "register_operand" "=v"))]
+  "TARGET_FLOAT128"
+  "xxlxor %x0,%x1,%x2"
+  [(set_attr "type" "vecsimple")])
+
+;; IEEE 128-bit absolute value
+(define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (abs:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+   (clobber (match_scratch:V16QI 2 "=v"))]
+  "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+                  (abs:TFIFKF (match_dup 1)))
+             (use (match_dup 2))])]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (V16QImode);
+
+  operands[3] = gen_reg_rtx (V16QImode);
+  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
+}
+  [(set_attr "length" "8")
+   (set_attr "type" "vecsimple")])
+
+(define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (abs:TFIFKF (match_operand:TFIFKF 1 "register_operand" "wa")))
+   (use (match_operand:V16QI 2 "register_operand" "=v"))]
+  "TARGET_FLOAT128"
+  "xxlandc %x0,%x1,%x2"
+  [(set_attr "type" "vecsimple")])
+
+;; IEEE 128-bit negative absolute value
+(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (neg:TFIFKF
+        (abs:TFIFKF
+         (match_operand:TFIFKF 1 "register_operand" "wa"))))
+   (clobber (match_scratch:V16QI 2 "=v"))]
+  "TARGET_FLOAT128 && FLOAT128_IEEE_P (<MODE>mode)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+                  (abs:TFIFKF (match_dup 1)))
+             (use (match_dup 2))])]
+{
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (V16QImode);
+
+  operands[3] = gen_reg_rtx (V16QImode);
+  emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
+}
+  [(set_attr "length" "8")
+   (set_attr "type" "vecsimple")])
+
+(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
+  [(set (match_operand:TFIFKF 0 "register_operand" "=wa")
+       (neg:TFIFKF
+        (abs:TFIFKF
+         (match_operand:TFIFKF 1 "register_operand" "wa"))))
+   (use (match_operand:V16QI 2 "register_operand" "=v"))]
+  "TARGET_FLOAT128"
+  "xxlor %x0,%x1,%x2"
+  [(set_attr "type" "vecsimple")])
+
 
 ;; Reload helper functions used by rs6000_secondary_reload.  The patterns all
 ;; must have 3 arguments, and scratch register constraint must be a single
@@ -12134,7 +12319,10 @@ (define_insn "div<div_extend>_<mode>"
 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
 
 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
-(define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
+(define_mode_attr FP128_64 [(TF "DF")
+                           (IF "DF")
+                           (TD "DI")
+                           (KF "DI")])
 
 (define_expand "unpack<mode>"
   [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
@@ -12142,7 +12330,7 @@ (define_expand "unpack<mode>"
         [(match_operand:FMOVE128 1 "register_operand" "")
          (match_operand:QI 2 "const_0_to_1_operand" "")]
         UNSPEC_UNPACK_128BIT))]
-  ""
+  "FLOAT128_2REG_P (<MODE>mode)"
   "")
 
 (define_insn_and_split "unpack<mode>_dm"
@@ -12151,7 +12339,7 @@ (define_insn_and_split "unpack<mode>_dm"
         [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
          (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
         UNSPEC_UNPACK_128BIT))]
-  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (match_dup 3))]
@@ -12175,7 +12363,7 @@ (define_insn_and_split "unpack<mode>_nod
         [(match_operand:FMOVE128 1 "register_operand" "d,d")
          (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
         UNSPEC_UNPACK_128BIT))]
-  "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
+  "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (match_dup 3))]
@@ -12199,7 +12387,7 @@ (define_insn_and_split "pack<mode>"
         [(match_operand:<FP128_64> 1 "register_operand" "0,d")
          (match_operand:<FP128_64> 2 "register_operand" "d,d")]
         UNSPEC_PACK_128BIT))]
-  ""
+  "FLOAT128_2REG_P (<MODE>mode)"
   "@
    fmr %L0,%2
    #"
@@ -12219,12 +12407,12 @@ (define_insn_and_split "pack<mode>"
   [(set_attr "type" "fp,fp")
    (set_attr "length" "4,8")])
 
-(define_insn "unpackv1ti"
+(define_insn "unpack<mode>"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
-       (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
+       (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
                    (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
         UNSPEC_UNPACK_128BIT))]
-  "TARGET_VSX"
+  "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
 {
   if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
     return ASM_COMMENT_START " xxpermdi to same register";
@@ -12232,19 +12420,17 @@ (define_insn "unpackv1ti"
   operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
   return "xxpermdi %x0,%x1,%x1,%3";
 }
-  [(set_attr "type" "vecperm")
-   (set_attr "length" "4")])
+  [(set_attr "type" "vecperm")])
 
-(define_insn "packv1ti"
-  [(set (match_operand:V1TI 0 "register_operand" "=wa")
-       (unspec:V1TI
+(define_insn "pack<mode>"
+  [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
+       (unspec:FMOVE128_VSX
         [(match_operand:DI 1 "register_operand" "d")
          (match_operand:DI 2 "register_operand" "d")]
         UNSPEC_PACK_128BIT))]
   "TARGET_VSX"
   "xxpermdi %x0,%x1,%x2,0"
-  [(set_attr "type" "vecperm")
-   (set_attr "length" "4")])
+  [(set_attr "type" "vecperm")])
 
 
 

Reply via email to