diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index 677062c..449e176 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -74,6 +74,10 @@ VECTOR_MODES (FLOAT, 16);     /*       V8HF  V4SF V2DF */
 VECTOR_MODES (INT, 32);       /* V32QI V16HI V8SI V4DI */
 VECTOR_MODES (FLOAT, 32);     /*       V16HF V8SF V4DF */
 
+/* Half VMX/VSX vector (for select)  */
+VECTOR_MODE (FLOAT, SF, 2);   /*                 V2SF  */
+VECTOR_MODE (INT, SI, 2);     /*                 V2SI  */
+
 /* Replacement for TImode that only is allowed in GPRs.  We also use PTImode
    for quad memory atomic operations to force getting an even/odd register
    combination.  */
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 83e4071..44025f6 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -265,7 +265,6 @@
 ;; Constants for creating unspecs
 (define_c_enum "unspec"
   [UNSPEC_VSX_CONCAT
-   UNSPEC_VSX_CVDPSXWS
    UNSPEC_VSX_CVDPUXWS
    UNSPEC_VSX_CVSPDP
    UNSPEC_VSX_CVHPSP
@@ -273,10 +272,6 @@
    UNSPEC_VSX_CVDPSPN
    UNSPEC_VSX_CVSXWDP
    UNSPEC_VSX_CVUXWDP
-   UNSPEC_VSX_CVSXDSP
-   UNSPEC_VSX_CVUXDSP
-   UNSPEC_VSX_CVSPSXDS
-   UNSPEC_VSX_CVSPUXDS
    UNSPEC_VSX_FLOAT2
    UNSPEC_VSX_UNS_FLOAT2
    UNSPEC_VSX_FLOATE
@@ -2106,22 +2101,69 @@
   "xscvdpsp %x0,%x1"
   [(set_attr "type" "fp")])
 
-(define_insn "vsx_xvcvspdp"
+(define_insn "vsx_xvcvspdp_be"
   [(set (match_operand:V2DF 0 "vsx_register_operand" "=v,?wa")
-	(unspec:V2DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
-			      UNSPEC_VSX_CVSPDP))]
-  "VECTOR_UNIT_VSX_P (V4SFmode)"
+     (float_extend:V2DF
+       (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa")
+	 (parallel [(const_int 0) (const_int 2)]))))]
+  "VECTOR_UNIT_VSX_P (V4SFmode) && BYTES_BIG_ENDIAN"
+  "xvcvspdp %x0,%x1"
+  [(set_attr "type" "vecdouble")])
+
+(define_insn "vsx_xvcvspdp_le"
+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=v,?wa")
+     (float_extend:V2DF
+       (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa")
+	 (parallel [(const_int 1) (const_int 3)]))))]
+  "VECTOR_UNIT_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN"
   "xvcvspdp %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-(define_insn "vsx_xvcvdpsp"
+(define_expand "vsx_xvcvspdp"
+  [(match_operand:V2DF 0 "vsx_register_operand")
+   (match_operand:V4SF 1 "vsx_register_operand")]
+  "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcvspdp_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcvspdp_le (operands[0], operands[1]));
+  DONE;
+})
+
+(define_insn "vsx_xvcvdpsp_be"
   [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,?wa")
-	(unspec:V4SF [(match_operand:V2DF 1 "vsx_register_operand" "v,wa")]
-			      UNSPEC_VSX_CVSPDP))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
+     (float_truncate:V4SF
+       (vec_concat:V4DF (match_operand:V2DF 1 "vsx_register_operand" "v,wa")
+	 (vec_select:V2DF (match_dup 1)
+	   (parallel [(const_int 1) (const_int 0)])))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN"
   "xvcvdpsp %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
+(define_insn "vsx_xvcvdpsp_le"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,?wa")
+     (float_truncate:V4SF
+       (vec_concat:V4DF
+	 (vec_select:V2DF (match_operand:V2DF 1 "vsx_register_operand" "v,wa")
+	   (parallel [(const_int 1) (const_int 0)]))
+	 (match_dup 1))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
+  "xvcvdpsp %x0,%x1"
+  [(set_attr "type" "vecdouble")])
+
+(define_expand "vsx_xvcvdpsp"
+  [(match_operand:V4SF 0 "vsx_register_operand")
+   (match_operand:V2DF 1 "vsx_register_operand")]
+  "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcvdpsp_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcvdpsp_le (operands[0], operands[1]));
+  DONE;
+})
+
 ;; xscvspdp, represent the scalar SF type as V4SF
 (define_insn "vsx_xscvspdp"
   [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
@@ -2301,48 +2343,144 @@
 ;; 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.
 
-(define_insn "vsx_xvcvdpsxws"
+;; Convert vector of 64-bit floating point numbers to vector of
+;; 32-bit signed/unsigned integers.
+(define_insn "vsx_xvcvdp<su>xws_be"
   [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
-	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wa,wa")]
-		     UNSPEC_VSX_CVDPSXWS))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvdpsxws %x0,%x1"
+     (any_fix:V4SI
+       (vec_concat:V4DF (match_operand:V2DF 1 "vsx_register_operand" "wa,wa")
+	 (vec_select:V2DF (match_dup 1)
+	   (parallel [(const_int 1) (const_int 0)])))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN"
+  "xvcvdp<su>xws %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-(define_insn "vsx_xvcvdpuxws"
+(define_insn "vsx_xvcvdp<su>xws_le"
   [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
-	(unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wa,wa")]
-		     UNSPEC_VSX_CVDPUXWS))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvdpuxws %x0,%x1"
+     (any_fix:V4SI
+       (vec_concat:V4DF
+	 (vec_select:V2DF (match_operand:V2DF 1 "vsx_register_operand" "wa,wa")
+	   (parallel [(const_int 1) (const_int 0)]))
+	 (match_dup 1))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
+  "xvcvdp<su>xws %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-(define_insn "vsx_xvcvsxdsp"
-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
-	(unspec:V4SF [(match_operand:V2DI 1 "vsx_register_operand" "wa")]
-		     UNSPEC_VSX_CVSXDSP))]
+(define_expand "vsx_xvcvdp<su>xws"
+  [(match_operand:V4SI 0 "vsx_register_operand")
+   (match_operand:V2DF 1 "vsx_register_operand")
+   (any_fix (pc))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvsxdsp %x0,%x1"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcvdp<su>xws_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcvdp<su>xws_le (operands[0], operands[1]));
+  DONE;
+})
+
+;; Convert vector of 64-bit signed/unsigned integers to vector of
+;; 32-bit floating point numbers.
+(define_insn "vsx_xvcv<su>xdsp_be"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
+     (any_float:V4SF
+       (vec_concat:V4DI (match_operand:V2DI 1 "vsx_register_operand" "wa")
+	 (vec_select:V2DI (match_dup 1)
+	   (parallel [(const_int 1) (const_int 0)])))))]
+  "VECTOR_UNIT_VSX_P (V4SFmode) && BYTES_BIG_ENDIAN"
+  "xvcv<su>xdsp %x0,%x1"
   [(set_attr "type" "vecfloat")])
 
-(define_insn "vsx_xvcvuxdsp"
+(define_insn "vsx_xvcv<su>xdsp_le"
   [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
-	(unspec:V4SF [(match_operand:V2DI 1 "vsx_register_operand" "wa")]
-		     UNSPEC_VSX_CVUXDSP))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvuxdsp %x0,%x1"
+     (any_float:V4SF
+       (vec_concat:V4DI
+	 (vec_select:V2DI (match_operand:V2DI 1 "vsx_register_operand" "wa")
+	   (parallel [(const_int 1) (const_int 0)]))
+	 (match_dup 1))))]
+  "VECTOR_UNIT_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN"
+  "xvcv<su>xdsp %x0,%x1"
+  [(set_attr "type" "vecfloat")])
+
+(define_expand "vsx_xvcv<su>xdsp"
+  [(match_operand:V4SF 0 "vsx_register_operand")
+   (match_operand:V2DI 1 "vsx_register_operand")
+   (any_float (pc))]
+  "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcv<su>xdsp_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcv<su>xdsp_le (operands[0], operands[1]));
+  DONE;
+})
+
+;; Convert vector of 32-bit signed/unsigned integers to vector of
+;; 64-bit floating point numbers.
+(define_insn "vsx_xvcv<su>xwdp_be"
+  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
+     (any_float:V2DF
+       (vec_select:V2SI (match_operand:V4SI 1 "vsx_register_operand" "wa")
+	 (parallel [(const_int 0) (const_int 2)]))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN"
+  "xvcv<su>xwdp %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-;; Convert from 32-bit to 64-bit types
-;; Provide both vector and scalar targets
-(define_insn "vsx_xvcvsxwdp"
+(define_insn "vsx_xvcv<su>xwdp_le"
   [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
-	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")]
-		     UNSPEC_VSX_CVSXWDP))]
+     (any_float:V2DF
+       (vec_select:V2SI (match_operand:V4SI 1 "vsx_register_operand" "wa")
+	 (parallel [(const_int 1) (const_int 3)]))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
+  "xvcv<su>xwdp %x0,%x1"
+  [(set_attr "type" "vecdouble")])
+
+(define_expand "vsx_xvcv<su>xwdp"
+  [(match_operand:V2DF 0 "vsx_register_operand")
+   (match_operand:V4SI 1 "vsx_register_operand")
+   (any_float (pc))]
   "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvsxwdp %x0,%x1"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcv<su>xwdp_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcv<su>xwdp_le (operands[0], operands[1]));
+  DONE;
+})
+
+;; Convert vector of 32-bit floating point numbers to vector of
+;; 64-bit signed/unsigned integers.
+(define_insn "vsx_xvcvsp<su>xds_be"
+  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
+     (any_fix:V2DI
+       (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa")
+	 (parallel [(const_int 0) (const_int 2)]))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN"
+  "xvcvsp<su>xds %x0,%x1"
+  [(set_attr "type" "vecdouble")])
+
+(define_insn "vsx_xvcvsp<su>xds_le"
+  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
+     (any_fix:V2DI
+       (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa")
+	 (parallel [(const_int 1) (const_int 3)]))))]
+  "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
+  "xvcvsp<su>xds %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
+(define_expand "vsx_xvcvsp<su>xds"
+  [(match_operand:V2DI 0 "vsx_register_operand")
+   (match_operand:V4SF 1 "vsx_register_operand")
+   (any_fix (pc))]
+  "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_vsx_xvcvsp<su>xds_be (operands[0], operands[1]));
+  else
+    emit_insn (gen_vsx_xvcvsp<su>xds_le (operands[0], operands[1]));
+  DONE;
+})
+
 (define_insn "vsx_xvcvsxwdp_df"
   [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
 	(unspec:DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")]
@@ -2351,14 +2489,6 @@
   "xvcvsxwdp %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-(define_insn "vsx_xvcvuxwdp"
-  [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
-	(unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")]
-		     UNSPEC_VSX_CVUXWDP))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvuxwdp %x0,%x1"
-  [(set_attr "type" "vecdouble")])
-
 (define_insn "vsx_xvcvuxwdp_df"
   [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
 	(unspec:DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")]
@@ -2367,22 +2497,6 @@
   "xvcvuxwdp %x0,%x1"
   [(set_attr "type" "vecdouble")])
 
-(define_insn "vsx_xvcvspsxds"
-  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
-	(unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
-		     UNSPEC_VSX_CVSPSXDS))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvspsxds %x0,%x1"
-  [(set_attr "type" "vecdouble")])
-
-(define_insn "vsx_xvcvspuxds"
-  [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
-	(unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")]
-		     UNSPEC_VSX_CVSPUXDS))]
-  "VECTOR_UNIT_VSX_P (V2DFmode)"
-  "xvcvspuxds %x0,%x1"
-  [(set_attr "type" "vecdouble")])
-
 ;; Generate float2 double
 ;; convert two double to float
 (define_expand "float2_v2df"
