OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [config/] [rs6000/] [vsx.md] - Diff between revs 282 and 338

Only display areas with differences | Details | Blame | View Log

Rev 282 Rev 338
;; VSX patterns.
;; VSX patterns.
;; Copyright (C) 2009
;; Copyright (C) 2009
;; Free Software Foundation, Inc.
;; Free Software Foundation, Inc.
;; Contributed by Michael Meissner 
;; Contributed by Michael Meissner 
;; This file is part of GCC.
;; This file is part of GCC.
;; GCC is free software; you can redistribute it and/or modify it
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;; option) any later version.
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
;; License for more details.
;; License for more details.
;; You should have received a copy of the GNU General Public License
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3.  If not see
;; along with GCC; see the file COPYING3.  If not see
;; .
;; .
;; Iterator for both scalar and vector floating point types supported by VSX
;; Iterator for both scalar and vector floating point types supported by VSX
(define_mode_iterator VSX_B [DF V4SF V2DF])
(define_mode_iterator VSX_B [DF V4SF V2DF])
;; Iterator for the 2 64-bit vector types
;; Iterator for the 2 64-bit vector types
(define_mode_iterator VSX_D [V2DF V2DI])
(define_mode_iterator VSX_D [V2DF V2DI])
;; Iterator for the 2 32-bit vector types
;; Iterator for the 2 32-bit vector types
(define_mode_iterator VSX_W [V4SF V4SI])
(define_mode_iterator VSX_W [V4SF V4SI])
;; Iterator for vector floating point types supported by VSX
;; Iterator for vector floating point types supported by VSX
(define_mode_iterator VSX_F [V4SF V2DF])
(define_mode_iterator VSX_F [V4SF V2DF])
;; Iterator for logical types supported by VSX
;; Iterator for logical types supported by VSX
(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI])
;; Iterator for memory move.  Handle TImode specially to allow
;; Iterator for memory move.  Handle TImode specially to allow
;; it to use gprs as well as vsx registers.
;; it to use gprs as well as vsx registers.
(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
;; Map into the appropriate load/store name based on the type
;; Map into the appropriate load/store name based on the type
(define_mode_attr VSm  [(V16QI "vw4")
(define_mode_attr VSm  [(V16QI "vw4")
                        (V8HI  "vw4")
                        (V8HI  "vw4")
                        (V4SI  "vw4")
                        (V4SI  "vw4")
                        (V4SF  "vw4")
                        (V4SF  "vw4")
                        (V2DF  "vd2")
                        (V2DF  "vd2")
                        (V2DI  "vd2")
                        (V2DI  "vd2")
                        (DF    "d")
                        (DF    "d")
                        (TI    "vw4")])
                        (TI    "vw4")])
;; Map into the appropriate suffix based on the type
;; Map into the appropriate suffix based on the type
(define_mode_attr VSs   [(V16QI "sp")
(define_mode_attr VSs   [(V16QI "sp")
                         (V8HI  "sp")
                         (V8HI  "sp")
                         (V4SI  "sp")
                         (V4SI  "sp")
                         (V4SF  "sp")
                         (V4SF  "sp")
                         (V2DF  "dp")
                         (V2DF  "dp")
                         (V2DI  "dp")
                         (V2DI  "dp")
                         (DF    "dp")
                         (DF    "dp")
                         (SF    "sp")
                         (SF    "sp")
                         (TI    "sp")])
                         (TI    "sp")])
;; Map the register class used
;; Map the register class used
(define_mode_attr VSr   [(V16QI "v")
(define_mode_attr VSr   [(V16QI "v")
                         (V8HI  "v")
                         (V8HI  "v")
                         (V4SI  "v")
                         (V4SI  "v")
                         (V4SF  "wf")
                         (V4SF  "wf")
                         (V2DI  "wd")
                         (V2DI  "wd")
                         (V2DF  "wd")
                         (V2DF  "wd")
                         (DF    "ws")
                         (DF    "ws")
                         (SF    "d")
                         (SF    "d")
                         (TI    "wd")])
                         (TI    "wd")])
;; Map the register class used for float<->int conversions
;; Map the register class used for float<->int conversions
(define_mode_attr VSr2  [(V2DF  "wd")
(define_mode_attr VSr2  [(V2DF  "wd")
                         (V4SF  "wf")
                         (V4SF  "wf")
                         (DF    "!f#r")])
                         (DF    "!f#r")])
(define_mode_attr VSr3  [(V2DF  "wa")
(define_mode_attr VSr3  [(V2DF  "wa")
                         (V4SF  "wa")
                         (V4SF  "wa")
                         (DF    "!f#r")])
                         (DF    "!f#r")])
;; Map the register class for sp<->dp float conversions, destination
;; Map the register class for sp<->dp float conversions, destination
(define_mode_attr VSr4  [(SF    "ws")
(define_mode_attr VSr4  [(SF    "ws")
                         (DF    "f")
                         (DF    "f")
                         (V2DF  "wd")
                         (V2DF  "wd")
                         (V4SF  "v")])
                         (V4SF  "v")])
;; Map the register class for sp<->dp float conversions, destination
;; Map the register class for sp<->dp float conversions, destination
(define_mode_attr VSr5  [(SF    "ws")
(define_mode_attr VSr5  [(SF    "ws")
                         (DF    "f")
                         (DF    "f")
                         (V2DF  "v")
                         (V2DF  "v")
                         (V4SF  "wd")])
                         (V4SF  "wd")])
;; Same size integer type for floating point data
;; Same size integer type for floating point data
(define_mode_attr VSi [(V4SF  "v4si")
(define_mode_attr VSi [(V4SF  "v4si")
                       (V2DF  "v2di")
                       (V2DF  "v2di")
                       (DF    "di")])
                       (DF    "di")])
(define_mode_attr VSI [(V4SF  "V4SI")
(define_mode_attr VSI [(V4SF  "V4SI")
                       (V2DF  "V2DI")
                       (V2DF  "V2DI")
                       (DF    "DI")])
                       (DF    "DI")])
;; Word size for same size conversion
;; Word size for same size conversion
(define_mode_attr VSc [(V4SF "w")
(define_mode_attr VSc [(V4SF "w")
                       (V2DF "d")
                       (V2DF "d")
                       (DF   "d")])
                       (DF   "d")])
;; Map into either s or v, depending on whether this is a scalar or vector
;; Map into either s or v, depending on whether this is a scalar or vector
;; operation
;; operation
(define_mode_attr VSv   [(V16QI "v")
(define_mode_attr VSv   [(V16QI "v")
                         (V8HI  "v")
                         (V8HI  "v")
                         (V4SI  "v")
                         (V4SI  "v")
                         (V4SF  "v")
                         (V4SF  "v")
                         (V2DI  "v")
                         (V2DI  "v")
                         (V2DF  "v")
                         (V2DF  "v")
                         (TI    "v")
                         (TI    "v")
                         (DF    "s")])
                         (DF    "s")])
;; Appropriate type for add ops (and other simple FP ops)
;; Appropriate type for add ops (and other simple FP ops)
(define_mode_attr VStype_simple [(V2DF "vecfloat")
(define_mode_attr VStype_simple [(V2DF "vecfloat")
                                 (V4SF "vecfloat")
                                 (V4SF "vecfloat")
                                 (DF   "fp")])
                                 (DF   "fp")])
(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d")
(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d")
                                   (V4SF "fp_addsub_s")
                                   (V4SF "fp_addsub_s")
                                   (DF   "fp_addsub_d")])
                                   (DF   "fp_addsub_d")])
;; Appropriate type for multiply ops
;; Appropriate type for multiply ops
(define_mode_attr VStype_mul    [(V2DF "vecfloat")
(define_mode_attr VStype_mul    [(V2DF "vecfloat")
                                 (V4SF "vecfloat")
                                 (V4SF "vecfloat")
                                 (DF   "dmul")])
                                 (DF   "dmul")])
(define_mode_attr VSfptype_mul  [(V2DF "fp_mul_d")
(define_mode_attr VSfptype_mul  [(V2DF "fp_mul_d")
                                 (V4SF "fp_mul_s")
                                 (V4SF "fp_mul_s")
                                 (DF   "fp_mul_d")])
                                 (DF   "fp_mul_d")])
;; Appropriate type for divide ops.  For now, just lump the vector divide with
;; Appropriate type for divide ops.  For now, just lump the vector divide with
;; the scalar divides
;; the scalar divides
(define_mode_attr VStype_div    [(V2DF "ddiv")
(define_mode_attr VStype_div    [(V2DF "ddiv")
                                 (V4SF "sdiv")
                                 (V4SF "sdiv")
                                 (DF   "ddiv")])
                                 (DF   "ddiv")])
(define_mode_attr VSfptype_div  [(V2DF "fp_div_d")
(define_mode_attr VSfptype_div  [(V2DF "fp_div_d")
                                 (V4SF "fp_div_s")
                                 (V4SF "fp_div_s")
                                 (DF   "fp_div_d")])
                                 (DF   "fp_div_d")])
;; Appropriate type for sqrt ops.  For now, just lump the vector sqrt with
;; Appropriate type for sqrt ops.  For now, just lump the vector sqrt with
;; the scalar sqrt
;; the scalar sqrt
(define_mode_attr VStype_sqrt   [(V2DF "dsqrt")
(define_mode_attr VStype_sqrt   [(V2DF "dsqrt")
                                 (V4SF "sdiv")
                                 (V4SF "sdiv")
                                 (DF   "ddiv")])
                                 (DF   "ddiv")])
(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d")
(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d")
                                 (V4SF "fp_sqrt_s")
                                 (V4SF "fp_sqrt_s")
                                 (DF   "fp_sqrt_d")])
                                 (DF   "fp_sqrt_d")])
;; Iterator and modes for sp<->dp conversions
;; Iterator and modes for sp<->dp conversions
;; Because scalar SF values are represented internally as double, use the
;; Because scalar SF values are represented internally as double, use the
;; V4SF type to represent this than SF.
;; V4SF type to represent this than SF.
(define_mode_iterator VSX_SPDP [DF V4SF V2DF])
(define_mode_iterator VSX_SPDP [DF V4SF V2DF])
(define_mode_attr VS_spdp_res [(DF      "V4SF")
(define_mode_attr VS_spdp_res [(DF      "V4SF")
                               (V4SF    "V2DF")
                               (V4SF    "V2DF")
                               (V2DF    "V4SF")])
                               (V2DF    "V4SF")])
(define_mode_attr VS_spdp_insn [(DF     "xscvdpsp")
(define_mode_attr VS_spdp_insn [(DF     "xscvdpsp")
                                (V4SF   "xvcvspdp")
                                (V4SF   "xvcvspdp")
                                (V2DF   "xvcvdpsp")])
                                (V2DF   "xvcvdpsp")])
(define_mode_attr VS_spdp_type [(DF     "fp")
(define_mode_attr VS_spdp_type [(DF     "fp")
                                (V4SF   "vecfloat")
                                (V4SF   "vecfloat")
                                (V2DF   "vecfloat")])
                                (V2DF   "vecfloat")])
;; Map the scalar mode for a vector type
;; Map the scalar mode for a vector type
(define_mode_attr VS_scalar [(V2DF      "DF")
(define_mode_attr VS_scalar [(V2DF      "DF")
                             (V2DI      "DI")
                             (V2DI      "DI")
                             (V4SF      "SF")
                             (V4SF      "SF")
                             (V4SI      "SI")
                             (V4SI      "SI")
                             (V8HI      "HI")
                             (V8HI      "HI")
                             (V16QI     "QI")])
                             (V16QI     "QI")])
;; Constants for creating unspecs
;; Constants for creating unspecs
(define_constants
(define_constants
  [(UNSPEC_VSX_CONCAT           500)
  [(UNSPEC_VSX_CONCAT           500)
   (UNSPEC_VSX_CVDPSXWS         501)
   (UNSPEC_VSX_CVDPSXWS         501)
   (UNSPEC_VSX_CVDPUXWS         502)
   (UNSPEC_VSX_CVDPUXWS         502)
   (UNSPEC_VSX_CVSPDP           503)
   (UNSPEC_VSX_CVSPDP           503)
   (UNSPEC_VSX_CVSXWDP          504)
   (UNSPEC_VSX_CVSXWDP          504)
   (UNSPEC_VSX_CVUXWDP          505)
   (UNSPEC_VSX_CVUXWDP          505)
   (UNSPEC_VSX_CVSXDSP          506)
   (UNSPEC_VSX_CVSXDSP          506)
   (UNSPEC_VSX_CVUXDSP          507)
   (UNSPEC_VSX_CVUXDSP          507)
   (UNSPEC_VSX_CVSPSXDS         508)
   (UNSPEC_VSX_CVSPSXDS         508)
   (UNSPEC_VSX_CVSPUXDS         509)
   (UNSPEC_VSX_CVSPUXDS         509)
   (UNSPEC_VSX_MADD             510)
   (UNSPEC_VSX_MADD             510)
   (UNSPEC_VSX_MSUB             511)
   (UNSPEC_VSX_MSUB             511)
   (UNSPEC_VSX_NMADD            512)
   (UNSPEC_VSX_NMADD            512)
   (UNSPEC_VSX_NMSUB            513)
   (UNSPEC_VSX_NMSUB            513)
   (UNSPEC_VSX_RSQRTE           514)
   (UNSPEC_VSX_RSQRTE           514)
   (UNSPEC_VSX_TDIV             515)
   (UNSPEC_VSX_TDIV             515)
   (UNSPEC_VSX_TSQRT            516)
   (UNSPEC_VSX_TSQRT            516)
   (UNSPEC_VSX_XXPERMDI         517)
   (UNSPEC_VSX_XXPERMDI         517)
   (UNSPEC_VSX_SET              518)
   (UNSPEC_VSX_SET              518)
   (UNSPEC_VSX_ROUND_I          519)
   (UNSPEC_VSX_ROUND_I          519)
   (UNSPEC_VSX_ROUND_IC         520)
   (UNSPEC_VSX_ROUND_IC         520)
   (UNSPEC_VSX_SLDWI            521)])
   (UNSPEC_VSX_SLDWI            521)])
;; VSX moves
;; VSX moves
(define_insn "*vsx_mov"
(define_insn "*vsx_mov"
  [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,,,?Z,?wa,?wa,*o,*r,*r,,?wa,v,wZ,v")
  [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,,,?Z,?wa,?wa,*o,*r,*r,,?wa,v,wZ,v")
        (match_operand:VSX_M 1 "input_operand" ",Z,,wa,Z,wa,r,o,r,j,j,W,v,wZ"))]
        (match_operand:VSX_M 1 "input_operand" ",Z,,wa,Z,wa,r,o,r,j,j,W,v,wZ"))]
  "VECTOR_MEM_VSX_P (mode)
  "VECTOR_MEM_VSX_P (mode)
   && (register_operand (operands[0], mode)
   && (register_operand (operands[0], mode)
       || register_operand (operands[1], mode))"
       || register_operand (operands[1], mode))"
{
{
  switch (which_alternative)
  switch (which_alternative)
    {
    {
    case 0:
    case 0:
    case 3:
    case 3:
      gcc_assert (MEM_P (operands[0])
      gcc_assert (MEM_P (operands[0])
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
      return "stxx %x1,%y0";
      return "stxx %x1,%y0";
    case 1:
    case 1:
    case 4:
    case 4:
      gcc_assert (MEM_P (operands[1])
      gcc_assert (MEM_P (operands[1])
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY);
                  && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY);
      return "lxx %x0,%y1";
      return "lxx %x0,%y1";
    case 2:
    case 2:
    case 5:
    case 5:
      return "xxlor %x0,%x1,%x1";
      return "xxlor %x0,%x1,%x1";
    case 6:
    case 6:
    case 7:
    case 7:
    case 8:
    case 8:
      return "#";
      return "#";
    case 9:
    case 9:
    case 10:
    case 10:
      return "xxlxor %x0,%x0,%x0";
      return "xxlxor %x0,%x0,%x0";
    case 11:
    case 11:
      return output_vec_const_move (operands);
      return output_vec_const_move (operands);
    case 12:
    case 12:
      gcc_assert (MEM_P (operands[0])
      gcc_assert (MEM_P (operands[0])
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
      return "stvx %1,%y0";
      return "stvx %1,%y0";
    case 13:
    case 13:
      gcc_assert (MEM_P (operands[0])
      gcc_assert (MEM_P (operands[0])
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_INC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
                  && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY);
      return "lvx %0,%y1";
      return "lvx %0,%y1";
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}
}
  [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")])
  [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,vecstore,vecload")])
;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for
;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for
;; unions.  However for plain data movement, slightly favor the vector loads
;; unions.  However for plain data movement, slightly favor the vector loads
(define_insn "*vsx_movti"
(define_insn "*vsx_movti"
  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?o,?r,?r,wa,v,v,wZ")
  [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?o,?r,?r,wa,v,v,wZ")
        (match_operand:TI 1 "input_operand" "wa,Z,wa,r,o,r,j,W,wZ,v"))]
        (match_operand:TI 1 "input_operand" "wa,Z,wa,r,o,r,j,W,wZ,v"))]
  "VECTOR_MEM_VSX_P (TImode)
  "VECTOR_MEM_VSX_P (TImode)
   && (register_operand (operands[0], TImode)
   && (register_operand (operands[0], TImode)
       || register_operand (operands[1], TImode))"
       || register_operand (operands[1], TImode))"
{
{
  switch (which_alternative)
  switch (which_alternative)
    {
    {
    case 0:
    case 0:
      return "stxvd2x %x1,%y0";
      return "stxvd2x %x1,%y0";
    case 1:
    case 1:
      return "lxvd2x %x0,%y1";
      return "lxvd2x %x0,%y1";
    case 2:
    case 2:
      return "xxlor %x0,%x1,%x1";
      return "xxlor %x0,%x1,%x1";
    case 3:
    case 3:
    case 4:
    case 4:
    case 5:
    case 5:
      return "#";
      return "#";
    case 6:
    case 6:
      return "xxlxor %x0,%x0,%x0";
      return "xxlxor %x0,%x0,%x0";
    case 7:
    case 7:
      return output_vec_const_move (operands);
      return output_vec_const_move (operands);
    case 8:
    case 8:
      return "stvx %1,%y0";
      return "stvx %1,%y0";
    case 9:
    case 9:
      return "lvx %0,%y1";
      return "lvx %0,%y1";
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}
}
  [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")])
  [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")])


;; VSX scalar and vector floating point arithmetic instructions
;; VSX scalar and vector floating point arithmetic instructions
(define_insn "*vsx_add3"
(define_insn "*vsx_add3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xadd %x0,%x1,%x2"
  "xadd %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_sub3"
(define_insn "*vsx_sub3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                     (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                     (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xsub %x0,%x1,%x2"
  "xsub %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_mul3"
(define_insn "*vsx_mul3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xmul %x0,%x1,%x2"
  "xmul %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_div3"
(define_insn "*vsx_div3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                   (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                   (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xdiv %x0,%x1,%x2"
  "xdiv %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; *tdiv* instruction returning the FG flag
;; *tdiv* instruction returning the FG flag
(define_expand "vsx_tdiv3_fg"
(define_expand "vsx_tdiv3_fg"
  [(set (match_dup 3)
  [(set (match_dup 3)
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
                     UNSPEC_VSX_TDIV))
                     UNSPEC_VSX_TDIV))
   (set (match_operand:SI 0 "gpc_reg_operand" "")
   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (gt:SI (match_dup 3)
        (gt:SI (match_dup 3)
               (const_int 0)))]
               (const_int 0)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  operands[3] = gen_reg_rtx (CCFPmode);
  operands[3] = gen_reg_rtx (CCFPmode);
})
})
;; *tdiv* instruction returning the FE flag
;; *tdiv* instruction returning the FE flag
(define_expand "vsx_tdiv3_fe"
(define_expand "vsx_tdiv3_fe"
  [(set (match_dup 3)
  [(set (match_dup 3)
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
                      (match_operand:VSX_B 2 "vsx_register_operand" "")]
                     UNSPEC_VSX_TDIV))
                     UNSPEC_VSX_TDIV))
   (set (match_operand:SI 0 "gpc_reg_operand" "")
   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (eq:SI (match_dup 3)
        (eq:SI (match_dup 3)
               (const_int 0)))]
               (const_int 0)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  operands[3] = gen_reg_rtx (CCFPmode);
  operands[3] = gen_reg_rtx (CCFPmode);
})
})
(define_insn "*vsx_tdiv3_internal"
(define_insn "*vsx_tdiv3_internal"
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                      (match_operand:VSX_B 2 "vsx_register_operand" ",wa")]
                      (match_operand:VSX_B 2 "vsx_register_operand" ",wa")]
                   UNSPEC_VSX_TDIV))]
                   UNSPEC_VSX_TDIV))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xtdiv %0,%x1,%x2"
  "xtdiv %0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fre2"
(define_insn "vsx_fre2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_FRES))]
                      UNSPEC_FRES))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xre %x0,%x1"
  "xre %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_neg2"
(define_insn "*vsx_neg2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xneg %x0,%x1"
  "xneg %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_abs2"
(define_insn "*vsx_abs2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xabs %x0,%x1"
  "xabs %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_nabs2"
(define_insn "vsx_nabs2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (neg:VSX_B
        (neg:VSX_B
         (abs:VSX_B
         (abs:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))))]
          (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xnabs %x0,%x1"
  "xnabs %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_smax3"
(define_insn "vsx_smax3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xmax %x0,%x1,%x2"
  "xmax %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_smin3"
(define_insn "*vsx_smin3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
        (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
                    (match_operand:VSX_B 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xmin %x0,%x1,%x2"
  "xmin %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_sqrt2"
(define_insn "*vsx_sqrt2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xsqrt %x0,%x1"
  "xsqrt %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_rsqrte2"
(define_insn "vsx_rsqrte2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_VSX_RSQRTE))]
                      UNSPEC_VSX_RSQRTE))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xrsqrte %x0,%x1"
  "xrsqrte %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; *tsqrt* returning the fg flag
;; *tsqrt* returning the fg flag
(define_expand "vsx_tsqrt2_fg"
(define_expand "vsx_tsqrt2_fg"
  [(set (match_dup 3)
  [(set (match_dup 3)
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
                     UNSPEC_VSX_TSQRT))
                     UNSPEC_VSX_TSQRT))
   (set (match_operand:SI 0 "gpc_reg_operand" "")
   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (gt:SI (match_dup 3)
        (gt:SI (match_dup 3)
               (const_int 0)))]
               (const_int 0)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  operands[3] = gen_reg_rtx (CCFPmode);
  operands[3] = gen_reg_rtx (CCFPmode);
})
})
;; *tsqrt* returning the fe flag
;; *tsqrt* returning the fe flag
(define_expand "vsx_tsqrt2_fe"
(define_expand "vsx_tsqrt2_fe"
  [(set (match_dup 3)
  [(set (match_dup 3)
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
                     UNSPEC_VSX_TSQRT))
                     UNSPEC_VSX_TSQRT))
   (set (match_operand:SI 0 "gpc_reg_operand" "")
   (set (match_operand:SI 0 "gpc_reg_operand" "")
        (eq:SI (match_dup 3)
        (eq:SI (match_dup 3)
               (const_int 0)))]
               (const_int 0)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  operands[3] = gen_reg_rtx (CCFPmode);
  operands[3] = gen_reg_rtx (CCFPmode);
})
})
(define_insn "*vsx_tsqrt2_internal"
(define_insn "*vsx_tsqrt2_internal"
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                     UNSPEC_VSX_TSQRT))]
                     UNSPEC_VSX_TSQRT))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xtsqrt %0,%x1"
  "xtsqrt %0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; Fused vector multiply/add instructions
;; Fused vector multiply/add instructions
;; Note we have a pattern for the multiply/add operations that uses unspec and
;; Note we have a pattern for the multiply/add operations that uses unspec and
;; does not check -mfused-madd to allow users to use these ops when they know
;; does not check -mfused-madd to allow users to use these ops when they know
;; they want the fused multiply/add.
;; they want the fused multiply/add.
(define_expand "vsx_fmadd4"
(define_expand "vsx_fmadd4"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
        (plus:VSX_B
        (plus:VSX_B
         (mult:VSX_B
         (mult:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" "")
          (match_operand:VSX_B 1 "vsx_register_operand" "")
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  if (!TARGET_FUSED_MADD)
  if (!TARGET_FUSED_MADD)
    {
    {
      emit_insn (gen_vsx_fmadd4_2 (operands[0], operands[1], operands[2],
      emit_insn (gen_vsx_fmadd4_2 (operands[0], operands[1], operands[2],
                                         operands[3]));
                                         operands[3]));
      DONE;
      DONE;
    }
    }
})
})
(define_insn "*vsx_fmadd4_1"
(define_insn "*vsx_fmadd4_1"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (plus:VSX_B
        (plus:VSX_B
         (mult:VSX_B
         (mult:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
  "@
  "@
   xmadda %x0,%x1,%x2
   xmadda %x0,%x1,%x2
   xmaddm %x0,%x1,%x3
   xmaddm %x0,%x1,%x3
   xmadda %x0,%x1,%x2
   xmadda %x0,%x1,%x2
   xmaddm %x0,%x1,%x3"
   xmaddm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fmadd4_2"
(define_insn "vsx_fmadd4_2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                      UNSPEC_VSX_MADD))]
                      UNSPEC_VSX_MADD))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "@
  "@
   xmadda %x0,%x1,%x2
   xmadda %x0,%x1,%x2
   xmaddm %x0,%x1,%x3
   xmaddm %x0,%x1,%x3
   xmadda %x0,%x1,%x2
   xmadda %x0,%x1,%x2
   xmaddm %x0,%x1,%x3"
   xmaddm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_expand "vsx_fmsub4"
(define_expand "vsx_fmsub4"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "")
        (minus:VSX_B
        (minus:VSX_B
         (mult:VSX_B
         (mult:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" "")
          (match_operand:VSX_B 1 "vsx_register_operand" "")
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
          (match_operand:VSX_B 2 "vsx_register_operand" ""))
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
         (match_operand:VSX_B 3 "vsx_register_operand" "")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  if (!TARGET_FUSED_MADD)
  if (!TARGET_FUSED_MADD)
    {
    {
      emit_insn (gen_vsx_fmsub4_2 (operands[0], operands[1], operands[2],
      emit_insn (gen_vsx_fmsub4_2 (operands[0], operands[1], operands[2],
                                         operands[3]));
                                         operands[3]));
      DONE;
      DONE;
    }
    }
})
})
(define_insn "*vsx_fmsub4_1"
(define_insn "*vsx_fmsub4_1"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (minus:VSX_B
        (minus:VSX_B
         (mult:VSX_B
         (mult:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD"
  "@
  "@
   xmsuba %x0,%x1,%x2
   xmsuba %x0,%x1,%x2
   xmsubm %x0,%x1,%x3
   xmsubm %x0,%x1,%x3
   xmsuba %x0,%x1,%x2
   xmsuba %x0,%x1,%x2
   xmsubm %x0,%x1,%x3"
   xmsubm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fmsub4_2"
(define_insn "vsx_fmsub4_2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                      UNSPEC_VSX_MSUB))]
                      UNSPEC_VSX_MSUB))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "@
  "@
   xmsuba %x0,%x1,%x2
   xmsuba %x0,%x1,%x2
   xmsubm %x0,%x1,%x3
   xmsubm %x0,%x1,%x3
   xmsuba %x0,%x1,%x2
   xmsuba %x0,%x1,%x2
   xmsubm %x0,%x1,%x3"
   xmsubm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_expand "vsx_fnmadd4"
(define_expand "vsx_fnmadd4"
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
   (match_operand:VSX_B 1 "vsx_register_operand" "")
   (match_operand:VSX_B 1 "vsx_register_operand" "")
   (match_operand:VSX_B 2 "vsx_register_operand" "")
   (match_operand:VSX_B 2 "vsx_register_operand" "")
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
    {
    {
       emit_insn (gen_vsx_fnmadd4_1 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmadd4_1 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
    {
    {
       emit_insn (gen_vsx_fnmadd4_2 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmadd4_2 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
  else
  else
    {
    {
       emit_insn (gen_vsx_fnmadd4_3 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmadd4_3 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
})
})
(define_insn "vsx_fnmadd4_1"
(define_insn "vsx_fnmadd4_1"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (neg:VSX_B
        (neg:VSX_B
         (plus:VSX_B
         (plus:VSX_B
          (mult:VSX_B
          (mult:VSX_B
           (match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
           (match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
   && HONOR_SIGNED_ZEROS (DFmode)"
   && HONOR_SIGNED_ZEROS (DFmode)"
  "@
  "@
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3
   xnmaddm %x0,%x1,%x3
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3"
   xnmaddm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fnmadd4_2"
(define_insn "vsx_fnmadd4_2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (minus:VSX_B
        (minus:VSX_B
         (mult:VSX_B
         (mult:VSX_B
          (neg:VSX_B
          (neg:VSX_B
           (match_operand:VSX_B 1 "gpc_reg_operand" ",,wa,wa"))
           (match_operand:VSX_B 1 "gpc_reg_operand" ",,wa,wa"))
          (match_operand:VSX_B 2 "gpc_reg_operand" ",0,wa,0"))
          (match_operand:VSX_B 2 "gpc_reg_operand" ",0,wa,0"))
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
   && !HONOR_SIGNED_ZEROS (DFmode)"
   && !HONOR_SIGNED_ZEROS (DFmode)"
  "@
  "@
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3
   xnmaddm %x0,%x1,%x3
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3"
   xnmaddm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fnmadd4_3"
(define_insn "vsx_fnmadd4_3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",,wa,wa")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                      UNSPEC_VSX_NMADD))]
                      UNSPEC_VSX_NMADD))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "@
  "@
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3
   xnmaddm %x0,%x1,%x3
   xnmadda %x0,%x1,%x2
   xnmadda %x0,%x1,%x2
   xnmaddm %x0,%x1,%x3"
   xnmaddm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_expand "vsx_fnmsub4"
(define_expand "vsx_fnmsub4"
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
  [(match_operand:VSX_B 0 "vsx_register_operand" "")
   (match_operand:VSX_B 1 "vsx_register_operand" "")
   (match_operand:VSX_B 1 "vsx_register_operand" "")
   (match_operand:VSX_B 2 "vsx_register_operand" "")
   (match_operand:VSX_B 2 "vsx_register_operand" "")
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
   (match_operand:VSX_B 3 "vsx_register_operand" "")]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
{
{
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
  if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
    {
    {
       emit_insn (gen_vsx_fnmsub4_1 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmsub4_1 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
  else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
    {
    {
       emit_insn (gen_vsx_fnmsub4_2 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmsub4_2 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
  else
  else
    {
    {
       emit_insn (gen_vsx_fnmsub4_3 (operands[0], operands[1],
       emit_insn (gen_vsx_fnmsub4_3 (operands[0], operands[1],
                                           operands[2], operands[3]));
                                           operands[2], operands[3]));
       DONE;
       DONE;
    }
    }
})
})
(define_insn "vsx_fnmsub4_1"
(define_insn "vsx_fnmsub4_1"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (neg:VSX_B
        (neg:VSX_B
         (minus:VSX_B
         (minus:VSX_B
          (mult:VSX_B
          (mult:VSX_B
           (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
           (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
           (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
          (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa"))))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
   && HONOR_SIGNED_ZEROS (DFmode)"
   && HONOR_SIGNED_ZEROS (DFmode)"
  "@
  "@
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3
   xnmsubm %x0,%x1,%x3
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3"
   xnmsubm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fnmsub4_2"
(define_insn "vsx_fnmsub4_2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (minus:VSX_B
        (minus:VSX_B
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")
         (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")
         (mult:VSX_B
         (mult:VSX_B
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))))]
          (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0"))))]
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
  "VECTOR_UNIT_VSX_P (mode) && TARGET_FUSED_MADD
   && !HONOR_SIGNED_ZEROS (DFmode)"
   && !HONOR_SIGNED_ZEROS (DFmode)"
  "@
  "@
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3
   xnmsubm %x0,%x1,%x3
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3"
   xnmsubm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fnmsub4_3"
(define_insn "vsx_fnmsub4_3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,,?wa,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%,,wa,wa")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 2 "vsx_register_operand" ",0,wa,0")
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                       (match_operand:VSX_B 3 "vsx_register_operand" "0,,0,wa")]
                      UNSPEC_VSX_NMSUB))]
                      UNSPEC_VSX_NMSUB))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "@
  "@
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3
   xnmsubm %x0,%x1,%x3
   xnmsuba %x0,%x1,%x2
   xnmsuba %x0,%x1,%x2
   xnmsubm %x0,%x1,%x3"
   xnmsubm %x0,%x1,%x3"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; Vector conditional expressions (no scalar version for these instructions)
;; Vector conditional expressions (no scalar version for these instructions)
(define_insn "vsx_eq"
(define_insn "vsx_eq"
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
        (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpeq %x0,%x1,%x2"
  "xvcmpeq %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_gt"
(define_insn "vsx_gt"
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
        (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpgt %x0,%x1,%x2"
  "xvcmpgt %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_ge"
(define_insn "*vsx_ge"
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
        (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" ",wa")
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
                  (match_operand:VSX_F 2 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpge %x0,%x1,%x2"
  "xvcmpge %x0,%x1,%x2"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; Floating point scalar compare
;; Floating point scalar compare
(define_insn "*vsx_cmpdf_internal1"
(define_insn "*vsx_cmpdf_internal1"
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y")
  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y")
        (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa")
        (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa")
                      (match_operand:DF 2 "gpc_reg_operand" "ws,wa")))]
                      (match_operand:DF 2 "gpc_reg_operand" "ws,wa")))]
  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
   && VECTOR_UNIT_VSX_P (DFmode)"
   && VECTOR_UNIT_VSX_P (DFmode)"
  "xscmpudp %0,%x1,%x2"
  "xscmpudp %0,%x1,%x2"
  [(set_attr "type" "fpcompare")])
  [(set_attr "type" "fpcompare")])
;; Compare vectors producing a vector result and a predicate, setting CR6 to
;; Compare vectors producing a vector result and a predicate, setting CR6 to
;; indicate a combined status
;; indicate a combined status
(define_insn "*vsx_eq__p"
(define_insn "*vsx_eq__p"
  [(set (reg:CC 74)
  [(set (reg:CC 74)
        (unspec:CC
        (unspec:CC
         [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
         [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
         UNSPEC_PREDICATE))
         UNSPEC_PREDICATE))
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (eq:VSX_F (match_dup 1)
        (eq:VSX_F (match_dup 1)
                  (match_dup 2)))]
                  (match_dup 2)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpeq. %x0,%x1,%x2"
  "xvcmpeq. %x0,%x1,%x2"
  [(set_attr "type" "veccmp")])
  [(set_attr "type" "veccmp")])
(define_insn "*vsx_gt__p"
(define_insn "*vsx_gt__p"
  [(set (reg:CC 74)
  [(set (reg:CC 74)
        (unspec:CC
        (unspec:CC
         [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
         [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
         UNSPEC_PREDICATE))
         UNSPEC_PREDICATE))
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (gt:VSX_F (match_dup 1)
        (gt:VSX_F (match_dup 1)
                  (match_dup 2)))]
                  (match_dup 2)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpgt. %x0,%x1,%x2"
  "xvcmpgt. %x0,%x1,%x2"
  [(set_attr "type" "veccmp")])
  [(set_attr "type" "veccmp")])
(define_insn "*vsx_ge__p"
(define_insn "*vsx_ge__p"
  [(set (reg:CC 74)
  [(set (reg:CC 74)
        (unspec:CC
        (unspec:CC
         [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
         [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" ",?wa")
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
                 (match_operand:VSX_F 2 "vsx_register_operand" ",?wa"))]
         UNSPEC_PREDICATE))
         UNSPEC_PREDICATE))
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
   (set (match_operand:VSX_F 0 "vsx_register_operand" "=,?wa")
        (ge:VSX_F (match_dup 1)
        (ge:VSX_F (match_dup 1)
                  (match_dup 2)))]
                  (match_dup 2)))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xvcmpge. %x0,%x1,%x2"
  "xvcmpge. %x0,%x1,%x2"
  [(set_attr "type" "veccmp")])
  [(set_attr "type" "veccmp")])
;; Vector select
;; Vector select
(define_insn "*vsx_xxsel"
(define_insn "*vsx_xxsel"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (if_then_else:VSX_L
        (if_then_else:VSX_L
         (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
         (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
                (const_int 0))
                (const_int 0))
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxsel %x0,%x3,%x2,%x1"
  "xxsel %x0,%x3,%x2,%x1"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
(define_insn "*vsx_xxsel_uns"
(define_insn "*vsx_xxsel_uns"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (if_then_else:VSX_L
        (if_then_else:VSX_L
         (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
         (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" ",wa")
                   (const_int 0))
                   (const_int 0))
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
         (match_operand:VSX_L 2 "vsx_register_operand" ",wa")
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
         (match_operand:VSX_L 3 "vsx_register_operand" ",wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxsel %x0,%x3,%x2,%x1"
  "xxsel %x0,%x3,%x2,%x1"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Copy sign
;; Copy sign
(define_insn "vsx_copysign3"
(define_insn "vsx_copysign3"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (if_then_else:VSX_B
        (if_then_else:VSX_B
         (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" ",wa")
         (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" ",wa")
                   (match_operand:VSX_B 3 "zero_constant" "j,j"))
                   (match_operand:VSX_B 3 "zero_constant" "j,j"))
         (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))
         (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa"))
         (neg:VSX_B (abs:VSX_B (match_dup 1)))))]
         (neg:VSX_B (abs:VSX_B (match_dup 1)))))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xcpsgn %x0,%x2,%x1"
  "xcpsgn %x0,%x2,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; For the conversions, limit the register class for the integer value to be
;; For the conversions, limit the register class for the integer value to be
;; the fprs because we don't want to add the altivec registers to movdi/movsi.
;; the fprs because we don't want to add the altivec registers to movdi/movsi.
;; For the unsigned tests, there isn't a generic double -> unsigned conversion
;; For the unsigned tests, there isn't a generic double -> unsigned conversion
;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
(define_insn "vsx_float2"
(define_insn "vsx_float2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
        (float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xcvsx %x0,%x1"
  "xcvsx %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_floatuns2"
(define_insn "vsx_floatuns2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unsigned_float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
        (unsigned_float:VSX_B (match_operand: 1 "vsx_register_operand" ",")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xcvux %x0,%x1"
  "xcvux %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fix_trunc2"
(define_insn "vsx_fix_trunc2"
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
        (fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xcvsxs %x0,%x1"
  "xcvsxs %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_fixuns_trunc2"
(define_insn "vsx_fixuns_trunc2"
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
  [(set (match_operand: 0 "vsx_register_operand" "=,?")
        (unsigned_fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (unsigned_fix: (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xcvuxs %x0,%x1"
  "xcvuxs %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
;; Math rounding functions
;; Math rounding functions
(define_insn "vsx_xri"
(define_insn "vsx_xri"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_VSX_ROUND_I))]
                      UNSPEC_VSX_ROUND_I))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xri %x0,%x1"
  "xri %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_xric"
(define_insn "vsx_xric"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_VSX_ROUND_IC))]
                      UNSPEC_VSX_ROUND_IC))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xric %x0,%x1"
  "xric %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_btrunc2"
(define_insn "vsx_btrunc2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
        (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" ",wa")))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xriz %x0,%x1"
  "xriz %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "*vsx_b2trunc2"
(define_insn "*vsx_b2trunc2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_FRIZ))]
                      UNSPEC_FRIZ))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xriz %x0,%x1"
  "xriz %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_floor2"
(define_insn "vsx_floor2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_FRIM))]
                      UNSPEC_FRIM))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xrim %x0,%x1"
  "xrim %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])
(define_insn "vsx_ceil2"
(define_insn "vsx_ceil2"
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=,?wa")
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
        (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" ",wa")]
                      UNSPEC_FRIP))]
                      UNSPEC_FRIP))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  "xrip %x0,%x1"
  "xrip %x0,%x1"
  [(set_attr "type" "")
  [(set_attr "type" "")
   (set_attr "fp_type" "")])
   (set_attr "fp_type" "")])


;; VSX convert to/from double vector
;; VSX convert to/from double vector
;; Convert between single and double precision
;; Convert between single and double precision
;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal
;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal
;; scalar single precision instructions internally use the double format.
;; scalar single precision instructions internally use the double format.
;; Prefer the altivec registers, since we likely will need to do a vperm
;; Prefer the altivec registers, since we likely will need to do a vperm
(define_insn "vsx_"
(define_insn "vsx_"
  [(set (match_operand: 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand: 0 "vsx_register_operand" "=,?wa")
        (unspec: [(match_operand:VSX_SPDP 1 "vsx_register_operand" ",wa")]
        (unspec: [(match_operand:VSX_SPDP 1 "vsx_register_operand" ",wa")]
                              UNSPEC_VSX_CVSPDP))]
                              UNSPEC_VSX_CVSPDP))]
  "VECTOR_UNIT_VSX_P (mode)"
  "VECTOR_UNIT_VSX_P (mode)"
  " %x0,%x1"
  " %x0,%x1"
  [(set_attr "type" "")])
  [(set_attr "type" "")])
;; xscvspdp, represent the scalar SF type as V4SF
;; xscvspdp, represent the scalar SF type as V4SF
(define_insn "vsx_xscvspdp"
(define_insn "vsx_xscvspdp"
  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa")
  [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa")
        (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
        (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
                   UNSPEC_VSX_CVSPDP))]
                   UNSPEC_VSX_CVSPDP))]
  "VECTOR_UNIT_VSX_P (DFmode)"
  "VECTOR_UNIT_VSX_P (DFmode)"
  "xscvspdp %x0,%x1"
  "xscvspdp %x0,%x1"
  [(set_attr "type" "fp")])
  [(set_attr "type" "fp")])
;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF
;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF
;; format of scalars is actually DF.
;; format of scalars is actually DF.
(define_insn "vsx_xscvdpsp_scalar"
(define_insn "vsx_xscvdpsp_scalar"
  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
        (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")]
        (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")]
                     UNSPEC_VSX_CVSPDP))]
                     UNSPEC_VSX_CVSPDP))]
  "VECTOR_UNIT_VSX_P (DFmode)"
  "VECTOR_UNIT_VSX_P (DFmode)"
  "xscvdpsp %x0,%x1"
  "xscvdpsp %x0,%x1"
  [(set_attr "type" "fp")])
  [(set_attr "type" "fp")])
;; Convert from 64-bit to 32-bit types
;; Convert from 64-bit to 32-bit types
;; Note, favor the Altivec registers since the usual use of these instructions
;; Note, favor the Altivec registers since the usual use of these instructions
;; is in vector converts and we need to use the Altivec vperm instruction.
;; is in vector converts and we need to use the Altivec vperm instruction.
(define_insn "vsx_xvcvdpsxws"
(define_insn "vsx_xvcvdpsxws"
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
                     UNSPEC_VSX_CVDPSXWS))]
                     UNSPEC_VSX_CVDPSXWS))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvdpsxws %x0,%x1"
  "xvcvdpsxws %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvdpuxws"
(define_insn "vsx_xvcvdpuxws"
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
                     UNSPEC_VSX_CVDPUXWS))]
                     UNSPEC_VSX_CVDPUXWS))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvdpuxws %x0,%x1"
  "xvcvdpuxws %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvsxdsp"
(define_insn "vsx_xvcvsxdsp"
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
                     UNSPEC_VSX_CVSXDSP))]
                     UNSPEC_VSX_CVSXDSP))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvsxdsp %x0,%x1"
  "xvcvsxdsp %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvuxdsp"
(define_insn "vsx_xvcvuxdsp"
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
        (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
                     UNSPEC_VSX_CVUXDSP))]
                     UNSPEC_VSX_CVUXDSP))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvuxwdp %x0,%x1"
  "xvcvuxwdp %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
;; Convert from 32-bit to 64-bit types
;; Convert from 32-bit to 64-bit types
(define_insn "vsx_xvcvsxwdp"
(define_insn "vsx_xvcvsxwdp"
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
                     UNSPEC_VSX_CVSXWDP))]
                     UNSPEC_VSX_CVSXWDP))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvsxwdp %x0,%x1"
  "xvcvsxwdp %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvuxwdp"
(define_insn "vsx_xvcvuxwdp"
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
        (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
                     UNSPEC_VSX_CVUXWDP))]
                     UNSPEC_VSX_CVUXWDP))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvuxwdp %x0,%x1"
  "xvcvuxwdp %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvspsxds"
(define_insn "vsx_xvcvspsxds"
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
                     UNSPEC_VSX_CVSPSXDS))]
                     UNSPEC_VSX_CVSPSXDS))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvspsxds %x0,%x1"
  "xvcvspsxds %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])
(define_insn "vsx_xvcvspuxds"
(define_insn "vsx_xvcvspuxds"
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
        (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
                     UNSPEC_VSX_CVSPUXDS))]
                     UNSPEC_VSX_CVSPUXDS))]
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "VECTOR_UNIT_VSX_P (V2DFmode)"
  "xvcvspuxds %x0,%x1"
  "xvcvspuxds %x0,%x1"
  [(set_attr "type" "vecfloat")])
  [(set_attr "type" "vecfloat")])


;; Logical and permute operations
;; Logical and permute operations
(define_insn "*vsx_and3"
(define_insn "*vsx_and3"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (and:VSX_L
        (and:VSX_L
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxland %x0,%x1,%x2"
  "xxland %x0,%x1,%x2"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])
(define_insn "*vsx_ior3"
(define_insn "*vsx_ior3"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (ior:VSX_L (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
        (ior:VSX_L (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
                   (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
                   (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxlor %x0,%x1,%x2"
  "xxlor %x0,%x1,%x2"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])
(define_insn "*vsx_xor3"
(define_insn "*vsx_xor3"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (xor:VSX_L
        (xor:VSX_L
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
         (match_operand:VSX_L 2 "vsx_register_operand" ",?wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxlxor %x0,%x1,%x2"
  "xxlxor %x0,%x1,%x2"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])
(define_insn "*vsx_one_cmpl2"
(define_insn "*vsx_one_cmpl2"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (not:VSX_L
        (not:VSX_L
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxlnor %x0,%x1,%x1"
  "xxlnor %x0,%x1,%x1"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])
(define_insn "*vsx_nor3"
(define_insn "*vsx_nor3"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (not:VSX_L
        (not:VSX_L
         (ior:VSX_L
         (ior:VSX_L
          (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
          (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))))]
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxlnor %x0,%x1,%x2"
  "xxlnor %x0,%x1,%x2"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])
(define_insn "*vsx_andc3"
(define_insn "*vsx_andc3"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=,?wa")
        (and:VSX_L
        (and:VSX_L
         (not:VSX_L
         (not:VSX_L
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))
          (match_operand:VSX_L 2 "vsx_register_operand" ",?wa"))
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
         (match_operand:VSX_L 1 "vsx_register_operand" ",?wa")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxlandc %x0,%x1,%x2"
  "xxlandc %x0,%x1,%x2"
  [(set_attr "type" "vecsimple")])
  [(set_attr "type" "vecsimple")])


;; Permute operations
;; Permute operations
;; Build a V2DF/V2DI vector from two scalars
;; Build a V2DF/V2DI vector from two scalars
(define_insn "vsx_concat_"
(define_insn "vsx_concat_"
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
        (unspec:VSX_D
        (unspec:VSX_D
         [(match_operand: 1 "vsx_register_operand" "ws,wa")
         [(match_operand: 1 "vsx_register_operand" "ws,wa")
          (match_operand: 2 "vsx_register_operand" "ws,wa")]
          (match_operand: 2 "vsx_register_operand" "ws,wa")]
         UNSPEC_VSX_CONCAT))]
         UNSPEC_VSX_CONCAT))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxpermdi %x0,%x1,%x2,0"
  "xxpermdi %x0,%x1,%x2,0"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Special purpose concat using xxpermdi to glue two single precision values
;; Special purpose concat using xxpermdi to glue two single precision values
;; together, relying on the fact that internally scalar floats are represented
;; together, relying on the fact that internally scalar floats are represented
;; as doubles.  This is used to initialize a V4SF vector with 4 floats
;; as doubles.  This is used to initialize a V4SF vector with 4 floats
(define_insn "vsx_concat_v2sf"
(define_insn "vsx_concat_v2sf"
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
        (unspec:V2DF
        (unspec:V2DF
         [(match_operand:SF 1 "vsx_register_operand" "f,f")
         [(match_operand:SF 1 "vsx_register_operand" "f,f")
          (match_operand:SF 2 "vsx_register_operand" "f,f")]
          (match_operand:SF 2 "vsx_register_operand" "f,f")]
         UNSPEC_VSX_CONCAT))]
         UNSPEC_VSX_CONCAT))]
  "VECTOR_MEM_VSX_P (V2DFmode)"
  "VECTOR_MEM_VSX_P (V2DFmode)"
  "xxpermdi %x0,%x1,%x2,0"
  "xxpermdi %x0,%x1,%x2,0"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Set the element of a V2DI/VD2F mode
;; Set the element of a V2DI/VD2F mode
(define_insn "vsx_set_"
(define_insn "vsx_set_"
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
        (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
        (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
                       (match_operand: 2 "vsx_register_operand" "ws,wa")
                       (match_operand: 2 "vsx_register_operand" "ws,wa")
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
                      UNSPEC_VSX_SET))]
                      UNSPEC_VSX_SET))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
{
{
  if (INTVAL (operands[3]) == 0)
  if (INTVAL (operands[3]) == 0)
    return \"xxpermdi %x0,%x1,%x2,1\";
    return \"xxpermdi %x0,%x1,%x2,1\";
  else if (INTVAL (operands[3]) == 1)
  else if (INTVAL (operands[3]) == 1)
    return \"xxpermdi %x0,%x2,%x1,0\";
    return \"xxpermdi %x0,%x2,%x1,0\";
  else
  else
    gcc_unreachable ();
    gcc_unreachable ();
}
}
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Extract a DF/DI element from V2DF/V2DI
;; Extract a DF/DI element from V2DF/V2DI
(define_insn "vsx_extract_"
(define_insn "vsx_extract_"
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
        (vec_select: (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa")
        (vec_select: (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa")
                       (parallel
                       (parallel
                        [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
                        [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
{
{
  gcc_assert (UINTVAL (operands[2]) <= 1);
  gcc_assert (UINTVAL (operands[2]) <= 1);
  operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
  operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
  return \"xxpermdi %x0,%x1,%x1,%3\";
  return \"xxpermdi %x0,%x1,%x1,%3\";
}
}
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Optimize extracting element 0 from memory
;; Optimize extracting element 0 from memory
(define_insn "*vsx_extract__zero"
(define_insn "*vsx_extract__zero"
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
  [(set (match_operand: 0 "vsx_register_operand" "=ws,d,?wa")
        (vec_select:
        (vec_select:
         (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z")
         (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z")
         (parallel [(const_int 0)])))]
         (parallel [(const_int 0)])))]
  "VECTOR_MEM_VSX_P (mode) && WORDS_BIG_ENDIAN"
  "VECTOR_MEM_VSX_P (mode) && WORDS_BIG_ENDIAN"
  "lxsd%U1x %x0,%y1"
  "lxsd%U1x %x0,%y1"
  [(set_attr "type" "fpload")
  [(set_attr "type" "fpload")
   (set_attr "length" "4")])
   (set_attr "length" "4")])
;; General double word oriented permute, allow the other vector types for
;; General double word oriented permute, allow the other vector types for
;; optimizing the permute instruction.
;; optimizing the permute instruction.
(define_insn "vsx_xxpermdi_"
(define_insn "vsx_xxpermdi_"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wd,?wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wd,?wa")
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wd,wa")
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wd,wa")
                       (match_operand:VSX_L 2 "vsx_register_operand" "wd,wa")
                       (match_operand:VSX_L 2 "vsx_register_operand" "wd,wa")
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
                       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
                      UNSPEC_VSX_XXPERMDI))]
                      UNSPEC_VSX_XXPERMDI))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxpermdi %x0,%x1,%x2,%3"
  "xxpermdi %x0,%x1,%x2,%3"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Varient of xxpermdi that is emitted by the vec_interleave functions
;; Varient of xxpermdi that is emitted by the vec_interleave functions
(define_insn "*vsx_xxpermdi2_"
(define_insn "*vsx_xxpermdi2_"
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
        (vec_concat:VSX_D
        (vec_concat:VSX_D
         (vec_select:
         (vec_select:
          (match_operand:VSX_D 1 "vsx_register_operand" "wd")
          (match_operand:VSX_D 1 "vsx_register_operand" "wd")
          (parallel
          (parallel
           [(match_operand:QI 2 "u5bit_cint_operand" "i")]))
           [(match_operand:QI 2 "u5bit_cint_operand" "i")]))
         (vec_select:
         (vec_select:
          (match_operand:VSX_D 3 "vsx_register_operand" "wd")
          (match_operand:VSX_D 3 "vsx_register_operand" "wd")
          (parallel
          (parallel
           [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
           [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
{
{
  gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
  gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
  operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
  operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
                         | (INTVAL (operands[4]) & 1));
                         | (INTVAL (operands[4]) & 1));
  return \"xxpermdi %x0,%x1,%x3,%5\";
  return \"xxpermdi %x0,%x1,%x3,%5\";
}
}
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; V2DF/V2DI splat
;; V2DF/V2DI splat
(define_insn "vsx_splat_"
(define_insn "vsx_splat_"
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
        (vec_duplicate:VSX_D
        (vec_duplicate:VSX_D
         (match_operand: 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
         (match_operand: 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "@
  "@
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   lxvdsx %x0,%y1
   lxvdsx %x0,%y1
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   xxpermdi %x0,%x1,%x1,0
   lxvdsx %x0,%y1"
   lxvdsx %x0,%y1"
  [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
  [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
;; V4SF/V4SI splat
;; V4SF/V4SI splat
(define_insn "vsx_xxspltw_"
(define_insn "vsx_xxspltw_"
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
        (vec_duplicate:VSX_W
        (vec_duplicate:VSX_W
         (vec_select:
         (vec_select:
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (parallel
          (parallel
           [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
           [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxspltw %x0,%x1,%2"
  "xxspltw %x0,%x1,%2"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; V4SF/V4SI interleave
;; V4SF/V4SI interleave
(define_insn "vsx_xxmrghw_"
(define_insn "vsx_xxmrghw_"
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
        (vec_merge:VSX_W
        (vec_merge:VSX_W
         (vec_select:VSX_W
         (vec_select:VSX_W
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (parallel [(const_int 0)
          (parallel [(const_int 0)
                     (const_int 2)
                     (const_int 2)
                     (const_int 1)
                     (const_int 1)
                     (const_int 3)]))
                     (const_int 3)]))
         (vec_select:VSX_W
         (vec_select:VSX_W
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")
          (parallel [(const_int 2)
          (parallel [(const_int 2)
                     (const_int 0)
                     (const_int 0)
                     (const_int 3)
                     (const_int 3)
                     (const_int 1)]))
                     (const_int 1)]))
         (const_int 5)))]
         (const_int 5)))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxmrghw %x0,%x1,%x2"
  "xxmrghw %x0,%x1,%x2"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
(define_insn "vsx_xxmrglw_"
(define_insn "vsx_xxmrglw_"
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
        (vec_merge:VSX_W
        (vec_merge:VSX_W
         (vec_select:VSX_W
         (vec_select:VSX_W
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
          (parallel [(const_int 2)
          (parallel [(const_int 2)
                     (const_int 0)
                     (const_int 0)
                     (const_int 3)
                     (const_int 3)
                     (const_int 1)]))
                     (const_int 1)]))
         (vec_select:VSX_W
         (vec_select:VSX_W
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")
          (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")
          (parallel [(const_int 0)
          (parallel [(const_int 0)
                     (const_int 2)
                     (const_int 2)
                     (const_int 1)
                     (const_int 1)
                     (const_int 3)]))
                     (const_int 3)]))
         (const_int 5)))]
         (const_int 5)))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxmrglw %x0,%x1,%x2"
  "xxmrglw %x0,%x1,%x2"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
;; Shift left double by word immediate
;; Shift left double by word immediate
(define_insn "vsx_xxsldwi_"
(define_insn "vsx_xxsldwi_"
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa")
  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa")
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa")
        (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa")
                       (match_operand:VSX_L 2 "vsx_register_operand" "wa")
                       (match_operand:VSX_L 2 "vsx_register_operand" "wa")
                       (match_operand:QI 3 "u5bit_cint_operand" "i")]
                       (match_operand:QI 3 "u5bit_cint_operand" "i")]
                      UNSPEC_VSX_SLDWI))]
                      UNSPEC_VSX_SLDWI))]
  "VECTOR_MEM_VSX_P (mode)"
  "VECTOR_MEM_VSX_P (mode)"
  "xxsldwi %x0,%x1,%x2,%3"
  "xxsldwi %x0,%x1,%x2,%3"
  [(set_attr "type" "vecperm")])
  [(set_attr "type" "vecperm")])
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.