public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [power7-meissner] Add builtins for VSX instructions
@ 2009-04-26 12:27 Michael Meissner
  0 siblings, 0 replies; only message in thread
From: Michael Meissner @ 2009-04-26 12:27 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 398 bytes --]

This patch to my development branch adds support for most of the VSX
instructions as builtins, except for the comparisons that set the CR.  I need
to add those builtins, tweak the external vec builtins and document the builts,
and the patches should be ready to submit for GCC 4.5.

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com

[-- Attachment #2: gcc-power7.patch36 --]
[-- Type: text/plain, Size: 54352 bytes --]

[gcc]
2009-04-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/vector.md (vector_vsel<mode>): Generate the insns
	directly instead of calling VSX/Altivec expanders.

	* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Map VSX
	builtins that are identical to Altivec, to the Altivec vesion.
	(altivec_overloaded_builtins): Add V2DF/V2DI sel, perm support.
	(altivec_resolve_overloaded_builtin): Add V2DF/V2DI support.

	* config/rs6000/rs6000.c (rs6000_expand_vector_init): Rename VSX
	splat functions.
	(expand_vector_set): Merge V2DF/V2DI code.
	(expand_vector_extract): Ditto.
	(bdesc_3arg): Add more VSX builtins.
	(bdesc_2arg): Ditto.
	(bdesc_1arg): Ditto.
	(rs6000_expand_ternop_builtin): Require xxpermdi 3rd argument to
	be 2 bit-constant, and V2DF/V2DI set to be a 1 bit-constant.
	(altivec_expand_builtin): Add support for VSX overloaded builtins.
	(altivec_init_builtins): Ditto.
	(rs6000_common_init_builtins): Ditto.
	(rs6000_init_builtins): Add V2DI types and vector long support.
	(rs6000_handle_altivec_attribute): Ditto.
	(rs6000_mange_type): Ditto.

	* config/rs6000/vsx.md (UNSPEC_*): Add new UNSPEC constants.
	(vsx_vsel<mode>): Add support for all vector types, including
	Altivec types.
	(vsx_ftrunc<mode>2): Emit the correct instruction.
	(vsx_x<VSv>r<VSs>i): New builtin rounding mode insns.
	(vsx_x<VSv>r<VSs>ic): Ditto.
	(vsx_concat_<mode>): Key off of VSX memory instructions being
	generated instead of the vector arithmetic unit to enable V2DI
	mode.
	(vsx_extract_<mode>): Ditto.
	(vsx_set_<mode>): Rewrite as an unspec.
	(vsx_xxpermdi2_<mode>): Rename old vsx_xxpermdi_<mode> here.  Key
	off of VSX memory instructions instead of arithmetic unit.
	(vsx_xxpermdi_<mode>): New insn for __builtin_vsx_xxpermdi.
	(vsx_splat_<mode>): Rename from vsx_splat<mode>.
	(vsx_xxspltw_<mode>): Change from V4SF only to V4SF/V4SI modes.
	Fix up constraints.  Key of memory instructions instead of
	arithmetic instructions.
	(vsx_xxmrghw_<mode>): Ditto.
	(vsx_xxmrglw_<mode>): Ditto.

	* config/rs6000/rs6000.h (VSX_BUILTIN_*): Update for current
	builtins being generated.
	(RS6000_BTI_unsigned_V2DI): Add vector long support.
	(RS6000_BTI_bool_long): Ditto.
	(RS6000_BTI_bool_V2DI): Ditto.
	(unsigned_V2DI_type_node): Ditto.
	(bool_long_type_node): Ditto.
	(bool_V2DI_type_node): Ditto.

	* config/rs6000/altivec.md (altivec_vsel<mode>): Add '*' since we
	don't need the generator function now.  Use VSX instruction if
	-mvsx.
	(altivec_vmrghw): Use VSX instruction if -mvsx.
	(altivec_vmrghsf): Ditto.
	(altivec_vmrglw): Ditto.
	(altivec_vmrglsf): Ditto.

[gcc/testsuite]
2009-04-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/vsx-builtin-3.c: New test for VSX builtins.

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 146116)
+++ gcc/doc/extend.texi	(working copy)
@@ -7094,7 +7094,7 @@ instructions, but allow the compiler to 
 * MIPS Loongson Built-in Functions::
 * Other MIPS Built-in Functions::
 * picoChip Built-in Functions::
-* PowerPC AltiVec Built-in Functions::
+* PowerPC AltiVec/VSX Built-in Functions::
 * SPARC VIS Built-in Functions::
 * SPU Built-in Functions::
 @end menu
@@ -9571,7 +9571,7 @@ GCC defines the preprocessor macro @code
 when this function is available.
 @end table
 
-@node PowerPC AltiVec Built-in Functions
+@node PowerPC AltiVec/VSX Built-in Functions
 @subsection PowerPC AltiVec Built-in Functions
 
 GCC provides an interface for the PowerPC family of processors to access
@@ -9597,6 +9597,19 @@ vector bool int
 vector float
 @end smallexample
 
+If @option{-mvsx} is used the following additional vector types are
+implemented.
+
+@smallexample
+vector unsigned long
+vector signed long
+vector double
+@end smallexample
+
+The long types are only implemented for 64-bit code generation, and
+the long type is only used in the floating point/integer conversion
+instructions.
+
 GCC's implementation of the high-level language interface available from
 C and C++ code differs from Motorola's documentation in several ways.
 
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c	(revision 0)
@@ -0,0 +1,212 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mcpu=power7" } */
+/* { dg-final { scan-assembler "xxsel" } } */
+/* { dg-final { scan-assembler "vperm" } } */
+/* { dg-final { scan-assembler "xvrdpi" } } */
+/* { dg-final { scan-assembler "xvrdpic" } } */
+/* { dg-final { scan-assembler "xvrdpim" } } */
+/* { dg-final { scan-assembler "xvrdpip" } } */
+/* { dg-final { scan-assembler "xvrdpiz" } } */
+/* { dg-final { scan-assembler "xvrspi" } } */
+/* { dg-final { scan-assembler "xvrspic" } } */
+/* { dg-final { scan-assembler "xvrspim" } } */
+/* { dg-final { scan-assembler "xvrspip" } } */
+/* { dg-final { scan-assembler "xvrspiz" } } */
+/* { dg-final { scan-assembler "xsrdpi" } } */
+/* { dg-final { scan-assembler "xsrdpic" } } */
+/* { dg-final { scan-assembler "xsrdpim" } } */
+/* { dg-final { scan-assembler "xsrdpip" } } */
+/* { dg-final { scan-assembler "xsrdpiz" } } */
+/* { dg-final { scan-assembler "xsmaxdp" } } */
+/* { dg-final { scan-assembler "xsmindp" } } */
+/* { dg-final { scan-assembler "xxland" } } */
+/* { dg-final { scan-assembler "xxlandc" } } */
+/* { dg-final { scan-assembler "xxlnor" } } */
+/* { dg-final { scan-assembler "xxlor" } } */
+/* { dg-final { scan-assembler "xxlxor" } } */
+/* { dg-final { scan-assembler "xvcmpeqdp" } } */
+/* { dg-final { scan-assembler "xvcmpgtdp" } } */
+/* { dg-final { scan-assembler "xvcmpgedp" } } */
+/* { dg-final { scan-assembler "xvcmpeqsp" } } */
+/* { dg-final { scan-assembler "xvcmpgtsp" } } */
+/* { dg-final { scan-assembler "xvcmpgesp" } } */
+/* { dg-final { scan-assembler "xxsldwi" } } */
+/* { dg-final { scan-assembler-not "call" } } */
+
+extern __vector int si[][4];
+extern __vector short ss[][4];
+extern __vector signed char sc[][4];
+extern __vector float f[][4];
+extern __vector unsigned int ui[][4];
+extern __vector unsigned short us[][4];
+extern __vector unsigned char uc[][4];
+extern __vector __bool int bi[][4];
+extern __vector __bool short bs[][4];
+extern __vector __bool char bc[][4];
+extern __vector __pixel p[][4];
+#ifdef __VSX__
+extern __vector double d[][4];
+extern __vector long sl[][4];
+extern __vector unsigned long ul[][4];
+extern __vector __bool long bl[][4];
+#endif
+
+int do_sel(void)
+{
+  int i = 0;
+
+  si[i][0] = __builtin_vsx_xxsel_4si (si[i][1], si[i][2], si[i][3]); i++;
+  ss[i][0] = __builtin_vsx_xxsel_8hi (ss[i][1], ss[i][2], ss[i][3]); i++;
+  sc[i][0] = __builtin_vsx_xxsel_16qi (sc[i][1], sc[i][2], sc[i][3]); i++;
+  f[i][0] = __builtin_vsx_xxsel_4sf (f[i][1], f[i][2], f[i][3]); i++;
+  d[i][0] = __builtin_vsx_xxsel_2df (d[i][1], d[i][2], d[i][3]); i++;
+
+  si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], bi[i][3]); i++;
+  ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], bs[i][3]); i++;
+  sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], bc[i][3]); i++;
+  f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], bi[i][3]); i++;
+  d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], bl[i][3]); i++;
+
+  si[i][0] = __builtin_vsx_xxsel (si[i][1], si[i][2], ui[i][3]); i++;
+  ss[i][0] = __builtin_vsx_xxsel (ss[i][1], ss[i][2], us[i][3]); i++;
+  sc[i][0] = __builtin_vsx_xxsel (sc[i][1], sc[i][2], uc[i][3]); i++;
+  f[i][0] = __builtin_vsx_xxsel (f[i][1], f[i][2], ui[i][3]); i++;
+  d[i][0] = __builtin_vsx_xxsel (d[i][1], d[i][2], ul[i][3]); i++;
+
+  return i;
+}
+
+int do_perm(void)
+{
+  int i = 0;
+
+  si[i][0] = __builtin_vsx_vperm_4si (si[i][1], si[i][2], sc[i][3]); i++;
+  ss[i][0] = __builtin_vsx_vperm_8hi (ss[i][1], ss[i][2], sc[i][3]); i++;
+  sc[i][0] = __builtin_vsx_vperm_16qi (sc[i][1], sc[i][2], sc[i][3]); i++;
+  f[i][0] = __builtin_vsx_vperm_4sf (f[i][1], f[i][2], sc[i][3]); i++;
+  d[i][0] = __builtin_vsx_vperm_2df (d[i][1], d[i][2], sc[i][3]); i++;
+
+  si[i][0] = __builtin_vsx_vperm (si[i][1], si[i][2], uc[i][3]); i++;
+  ss[i][0] = __builtin_vsx_vperm (ss[i][1], ss[i][2], uc[i][3]); i++;
+  sc[i][0] = __builtin_vsx_vperm (sc[i][1], sc[i][2], uc[i][3]); i++;
+  f[i][0] = __builtin_vsx_vperm (f[i][1], f[i][2], uc[i][3]); i++;
+  d[i][0] = __builtin_vsx_vperm (d[i][1], d[i][2], uc[i][3]); i++;
+
+  return i;
+}
+
+int do_xxperm (void)
+{
+  int i = 0;
+
+  d[i][0] = __builtin_vsx_xxpermdi_2df (d[i][1], d[i][2], 0); i++;
+  d[i][0] = __builtin_vsx_xxpermdi (d[i][1], d[i][2], 1); i++;
+  return i;
+}
+
+double x, y;
+void do_concat (void)
+{
+  d[0][0] = __builtin_vsx_concat_2df (x, y);
+}
+
+void do_set (void)
+{
+  d[0][0] = __builtin_vsx_set_2df (d[0][1], x, 0);
+  d[1][0] = __builtin_vsx_set_2df (d[1][1], y, 1);
+}
+
+extern double z[][4];
+
+int do_math (void)
+{
+  int i = 0;
+
+  d[i][0] = __builtin_vsx_xvrdpi  (d[i][1]); i++;
+  d[i][0] = __builtin_vsx_xvrdpic (d[i][1]); i++;
+  d[i][0] = __builtin_vsx_xvrdpim (d[i][1]); i++;
+  d[i][0] = __builtin_vsx_xvrdpip (d[i][1]); i++;
+  d[i][0] = __builtin_vsx_xvrdpiz (d[i][1]); i++;
+
+  f[i][0] = __builtin_vsx_xvrspi  (f[i][1]); i++;
+  f[i][0] = __builtin_vsx_xvrspic (f[i][1]); i++;
+  f[i][0] = __builtin_vsx_xvrspim (f[i][1]); i++;
+  f[i][0] = __builtin_vsx_xvrspip (f[i][1]); i++;
+  f[i][0] = __builtin_vsx_xvrspiz (f[i][1]); i++;
+
+  z[i][0] = __builtin_vsx_xsrdpi  (z[i][1]); i++;
+  z[i][0] = __builtin_vsx_xsrdpic (z[i][1]); i++;
+  z[i][0] = __builtin_vsx_xsrdpim (z[i][1]); i++;
+  z[i][0] = __builtin_vsx_xsrdpip (z[i][1]); i++;
+  z[i][0] = __builtin_vsx_xsrdpiz (z[i][1]); i++;
+  z[i][0] = __builtin_vsx_xsmaxdp (z[i][1], z[i][0]); i++;
+  z[i][0] = __builtin_vsx_xsmindp (z[i][1], z[i][0]); i++;
+  return i;
+}
+
+int do_cmp (void)
+{
+  int i = 0;
+
+  d[i][0] = __builtin_vsx_xvcmpeqdp (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xvcmpgtdp (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xvcmpgedp (d[i][1], d[i][2]); i++;
+
+  f[i][0] = __builtin_vsx_xvcmpeqsp (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xvcmpgtsp (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xvcmpgesp (f[i][1], f[i][2]); i++;
+  return i;
+}
+
+int do_logical (void)
+{
+  int i = 0;
+
+  si[i][0] = __builtin_vsx_xxland (si[i][1], si[i][2]); i++;
+  si[i][0] = __builtin_vsx_xxlandc (si[i][1], si[i][2]); i++;
+  si[i][0] = __builtin_vsx_xxlnor (si[i][1], si[i][2]); i++;
+  si[i][0] = __builtin_vsx_xxlor (si[i][1], si[i][2]); i++;
+  si[i][0] = __builtin_vsx_xxlxor (si[i][1], si[i][2]); i++;
+
+  ss[i][0] = __builtin_vsx_xxland (ss[i][1], ss[i][2]); i++;
+  ss[i][0] = __builtin_vsx_xxlandc (ss[i][1], ss[i][2]); i++;
+  ss[i][0] = __builtin_vsx_xxlnor (ss[i][1], ss[i][2]); i++;
+  ss[i][0] = __builtin_vsx_xxlor (ss[i][1], ss[i][2]); i++;
+  ss[i][0] = __builtin_vsx_xxlxor (ss[i][1], ss[i][2]); i++;
+
+  sc[i][0] = __builtin_vsx_xxland (sc[i][1], sc[i][2]); i++;
+  sc[i][0] = __builtin_vsx_xxlandc (sc[i][1], sc[i][2]); i++;
+  sc[i][0] = __builtin_vsx_xxlnor (sc[i][1], sc[i][2]); i++;
+  sc[i][0] = __builtin_vsx_xxlor (sc[i][1], sc[i][2]); i++;
+  sc[i][0] = __builtin_vsx_xxlxor (sc[i][1], sc[i][2]); i++;
+
+  d[i][0] = __builtin_vsx_xxland (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xxlandc (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xxlnor (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xxlor (d[i][1], d[i][2]); i++;
+  d[i][0] = __builtin_vsx_xxlxor (d[i][1], d[i][2]); i++;
+
+  f[i][0] = __builtin_vsx_xxland (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xxlandc (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xxlnor (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xxlor (f[i][1], f[i][2]); i++;
+  f[i][0] = __builtin_vsx_xxlxor (f[i][1], f[i][2]); i++;
+  return i;
+}
+
+int do_xxsldwi (void)
+{
+  int i = 0;
+
+  si[i][0] = __builtin_vsx_xxsldwi (si[i][1], si[i][2], 0); i++;
+  ss[i][0] = __builtin_vsx_xxsldwi (ss[i][1], ss[i][2], 1); i++;
+  sc[i][0] = __builtin_vsx_xxsldwi (sc[i][1], sc[i][2], 2); i++;
+  ui[i][0] = __builtin_vsx_xxsldwi (ui[i][1], ui[i][2], 3); i++;
+  us[i][0] = __builtin_vsx_xxsldwi (us[i][1], us[i][2], 0); i++;
+  uc[i][0] = __builtin_vsx_xxsldwi (uc[i][1], uc[i][2], 1); i++;
+  f[i][0] = __builtin_vsx_xxsldwi (f[i][1], f[i][2], 2); i++;
+  d[i][0] = __builtin_vsx_xxsldwi (d[i][1], d[i][2], 3); i++;
+  return i;
+}
Index: gcc/config/rs6000/vector.md
===================================================================
--- gcc/config/rs6000/vector.md	(revision 146656)
+++ gcc/config/rs6000/vector.md	(working copy)
@@ -350,34 +350,13 @@
 ;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask
 ;; which is in the reverse order that we want
 (define_expand "vector_vsel<mode>"
-  [(match_operand:VEC_F 0 "vlogical_operand" "")
-   (match_operand:VEC_F 1 "vlogical_operand" "")
-   (match_operand:VEC_F 2 "vlogical_operand" "")
-   (match_operand:VEC_F 3 "vlogical_operand" "")]
+  [(set (match_operand:VEC_L 0 "vlogical_operand" "")
+	(if_then_else:VEC_L (ne (match_operand:VEC_L 3 "vlogical_operand" "")
+				(const_int 0))
+			    (match_operand:VEC_L 2 "vlogical_operand" "")
+			    (match_operand:VEC_L 1 "vlogical_operand" "")))]
   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
-  "
-{
-  if (VECTOR_UNIT_VSX_P (<MODE>mode))
-    emit_insn (gen_vsx_vsel<mode> (operands[0], operands[3],
-				   operands[2], operands[1]));
-  else
-    emit_insn (gen_altivec_vsel<mode> (operands[0], operands[3],
-				       operands[2], operands[1]));
-  DONE;
-}")
-
-(define_expand "vector_vsel<mode>"
-  [(match_operand:VEC_I 0 "vlogical_operand" "")
-   (match_operand:VEC_I 1 "vlogical_operand" "")
-   (match_operand:VEC_I 2 "vlogical_operand" "")
-   (match_operand:VEC_I 3 "vlogical_operand" "")]
-  "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
-  "
-{
-  emit_insn (gen_altivec_vsel<mode> (operands[0], operands[3],
-				     operands[2], operands[1]));
-  DONE;
-}")
+  "")
 
 \f
 ;; Vector logical instructions
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 146119)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -336,7 +336,20 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
   if (TARGET_NO_LWSYNC)
     builtin_define ("__NO_LWSYNC__");
   if (TARGET_VSX)
-    builtin_define ("__VSX__");
+    {
+      builtin_define ("__VSX__");
+
+      /* For the VSX builtin functions identical to Altivec functions, just map
+	 the altivec builtin into the vsx version (the altivec functions
+	 generate VSX code if -mvsx).  */
+      builtin_define ("__builtin_vsx_xxland=__builtin_vec_and");
+      builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc");
+      builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor");
+      builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or");
+      builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor");
+      builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel");
+      builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm");
+    }
 
   /* May be overridden by target configuration.  */
   RS6000_CPU_CPP_ENDIAN_BUILTINS();
@@ -400,7 +413,7 @@ struct altivec_builtin_types
 };
 
 const struct altivec_builtin_types altivec_overloaded_builtins[] = {
-  /* Unary AltiVec builtins.  */
+  /* Unary AltiVec/VSX builtins.  */
   { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI,
     RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
   { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI,
@@ -496,7 +509,7 @@ const struct altivec_builtin_types altiv
   { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB,
     RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
 
-  /* Binary AltiVec builtins.  */
+  /* Binary AltiVec/VSX builtins.  */
   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
     RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
@@ -2206,7 +2219,7 @@ const struct altivec_builtin_types altiv
   { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR,
     RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
 
-  /* Ternary AltiVec builtins.  */
+  /* Ternary AltiVec/VSX builtins.  */
   { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
     RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI },
   { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST,
@@ -2407,6 +2420,10 @@ const struct altivec_builtin_types altiv
     RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI },
   { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP,
     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
+  { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI },
+  { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI },
   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SF,
     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI },
   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI,
@@ -2433,11 +2450,29 @@ const struct altivec_builtin_types altiv
     RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI },
   { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI,
     RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI },
   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI },
   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF,
     RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI },
   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
+    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
+    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SI },
+  { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
     RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI },
   { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI,
     RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI },
@@ -2805,6 +2840,37 @@ const struct altivec_builtin_types altiv
     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI },
   { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL,
     RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+    RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
+    RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
+    RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI,
+    RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
+    RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI,
+    RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
+    RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI,
+    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+    RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF,
+    RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF,
+    RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE },
+  { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI,
+    RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
+    RS6000_BTI_NOT_OPAQUE },
 
   /* Predicates.  */
   { ALTIVEC_BUILTIN_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P,
@@ -3108,6 +3174,10 @@ altivec_resolve_overloaded_builtin (tree
 	goto bad;
       switch (TYPE_MODE (type))
 	{
+	  case DImode:
+	    type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
+	    size = 2;
+	    break;
 	  case SImode:
 	    type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
 	    size = 4;
@@ -3121,6 +3191,7 @@ altivec_resolve_overloaded_builtin (tree
 	    size = 16;
 	    break;
 	  case SFmode: type = V4SF_type_node; size = 4; break;
+	  case DFmode: type = V2DF_type_node; size = 2; break;
 	  default:
 	    goto bad;
 	}
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 146656)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -3853,12 +3853,12 @@ rs6000_expand_vector_init (rtx target, r
 
       if (mode == V2DFmode)
 	{
-	  splat = gen_vsx_splatv2df;
+	  splat = gen_vsx_splat_v2df;
 	  concat = gen_vsx_concat_v2df;
 	}
       else
 	{
-	  splat = gen_vsx_splatv2di;
+	  splat = gen_vsx_splat_v2di;
 	  concat = gen_vsx_concat_v2di;
 	}
 
@@ -3930,16 +3930,12 @@ rs6000_expand_vector_set (rtx target, rt
   int width = GET_MODE_SIZE (inner_mode);
   int i;
 
-  if (mode == V2DFmode)
+  if (mode == V2DFmode || mode == V2DImode)
     {
+      rtx (*set_func) (rtx, rtx, rtx, rtx)
+	= ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
       gcc_assert (TARGET_VSX);
-      emit_insn (gen_vsx_set_v2df (target, val, target, GEN_INT (elt)));
-      return;
-    }
-  else if (mode == V2DImode)
-    {
-      gcc_assert (TARGET_VSX);
-      emit_insn (gen_vsx_set_v2di (target, val, target, GEN_INT (elt)));
+      emit_insn (set_func (target, val, target, GEN_INT (elt)));
       return;
     }
 
@@ -3980,16 +3976,12 @@ rs6000_expand_vector_extract (rtx target
   enum machine_mode inner_mode = GET_MODE_INNER (mode);
   rtx mem, x;
 
-  if (mode == V2DFmode)
-    {
-      gcc_assert (TARGET_VSX);
-      emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt)));
-      return;
-    }
-  else if (mode == V2DImode)
+  if (mode == V2DFmode || mode == V2DImode)
     {
+      rtx (*extract_func) (rtx, rtx, rtx)
+	= ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
       gcc_assert (TARGET_VSX);
-      emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt)));
+      emit_insn (extract_func (target, vec, GEN_INT (elt)));
       return;
     }
 
@@ -8024,6 +8016,34 @@ static const struct builtin_description 
   { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
   { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
 
+  { MASK_VSX, CODE_FOR_vector_vselv2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
+  { MASK_VSX, CODE_FOR_vector_vselv2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
+  { MASK_VSX, CODE_FOR_vector_vselv4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
+  { MASK_VSX, CODE_FOR_vector_vselv4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
+  { MASK_VSX, CODE_FOR_vector_vselv8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
+  { MASK_VSX, CODE_FOR_vector_vselv16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
+
+  { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
+  { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
+  { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
+  { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
+  { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
+  { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
+
+  { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
+  { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
+  { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
+  { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
+  { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
+
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
+  { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
+  { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
+
   { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
   { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
   { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
@@ -8173,6 +8193,9 @@ static struct builtin_description bdesc_
   { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
   { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
   { MASK_VSX, CODE_FOR_vsx_tdivv2df3, "__builtin_vsx_xvtdivdp", VSX_BUILTIN_XVTDIVDP },
+  { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
+  { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
+  { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
 
   { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
   { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
@@ -8181,6 +8204,21 @@ static struct builtin_description bdesc_
   { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
   { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
   { MASK_VSX, CODE_FOR_vsx_tdivv4sf3, "__builtin_vsx_xvtdivsp", VSX_BUILTIN_XVTDIVSP },
+  { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
+  { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
+  { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
+
+  { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
+  { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
+
+  { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
+  { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
+  { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
+  { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
+  { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
+  { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
+  { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
+  { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
 
   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
   { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
@@ -8617,11 +8655,27 @@ static struct builtin_description bdesc_
   { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
   { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
   { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
+  { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
+  { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
+  { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
+  { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
+  { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
 
   { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
   { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
   { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
   { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
+  { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
+  { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
+  { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
+  { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
+  { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
+
+  { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
+  { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
+  { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
+  { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
+  { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
 
   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
   { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
@@ -9152,11 +9206,12 @@ rs6000_expand_ternop_builtin (enum insn_
       || arg2 == error_mark_node)
     return const0_rtx;
 
-  if (icode == CODE_FOR_altivec_vsldoi_v4sf
-      || icode == CODE_FOR_altivec_vsldoi_v4si
-      || icode == CODE_FOR_altivec_vsldoi_v8hi
-      || icode == CODE_FOR_altivec_vsldoi_v16qi)
+  switch (icode)
     {
+    case CODE_FOR_altivec_vsldoi_v4sf:
+    case CODE_FOR_altivec_vsldoi_v4si:
+    case CODE_FOR_altivec_vsldoi_v8hi:
+    case CODE_FOR_altivec_vsldoi_v16qi:
       /* Only allow 4-bit unsigned literals.  */
       STRIP_NOPS (arg2);
       if (TREE_CODE (arg2) != INTEGER_CST
@@ -9165,6 +9220,40 @@ rs6000_expand_ternop_builtin (enum insn_
 	  error ("argument 3 must be a 4-bit unsigned literal");
 	  return const0_rtx;
 	}
+      break;
+
+    case CODE_FOR_vsx_xxpermdi_v2df:
+    case CODE_FOR_vsx_xxpermdi_v2di:
+    case CODE_FOR_vsx_xxsldwi_v16qi:
+    case CODE_FOR_vsx_xxsldwi_v8hi:
+    case CODE_FOR_vsx_xxsldwi_v4si:
+    case CODE_FOR_vsx_xxsldwi_v4sf:
+    case CODE_FOR_vsx_xxsldwi_v2di:
+    case CODE_FOR_vsx_xxsldwi_v2df:
+      /* Only allow 2-bit unsigned literals.  */
+      STRIP_NOPS (arg2);
+      if (TREE_CODE (arg2) != INTEGER_CST
+	  || TREE_INT_CST_LOW (arg2) & ~0x3)
+	{
+	  error ("argument 3 must be a 2-bit unsigned literal");
+	  return const0_rtx;
+	}
+      break;
+
+    case CODE_FOR_vsx_set_v2df:
+    case CODE_FOR_vsx_set_v2di:
+      /* Only allow 1-bit unsigned literals.  */
+      STRIP_NOPS (arg2);
+      if (TREE_CODE (arg2) != INTEGER_CST
+	  || TREE_INT_CST_LOW (arg2) & ~0x1)
+	{
+	  error ("argument 3 must be a 1-bit unsigned literal");
+	  return const0_rtx;
+	}
+      break;
+
+    default:
+      break;
     }
 
   if (target == 0
@@ -9472,8 +9561,10 @@ altivec_expand_builtin (tree exp, rtx ta
   enum machine_mode tmode, mode0;
   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
 
-  if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
-      && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+  if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+       && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+      || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
+	  && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
     {
       *expandedp = true;
       error ("unresolved overload for Altivec builtin %qF", fndecl);
@@ -10262,6 +10353,7 @@ rs6000_init_builtins (void)
   unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
   unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
   unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
+  unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
 
   opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
   opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
@@ -10275,6 +10367,7 @@ rs6000_init_builtins (void)
   bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
   bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
   bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
+  bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
   pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
 
   long_integer_type_internal_node = long_integer_type_node;
@@ -10307,6 +10400,7 @@ rs6000_init_builtins (void)
   bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
   bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
   bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
+  bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
   pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
 
   (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
@@ -10347,9 +10441,17 @@ rs6000_init_builtins (void)
 					    pixel_V8HI_type_node));
 
   if (TARGET_VSX)
-    (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
-					      get_identifier ("__vector double"),
-					      V2DF_type_node));
+    {
+      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+						get_identifier ("__vector double"),
+						V2DF_type_node));
+      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+						get_identifier ("__vector long"),
+						V2DI_type_node));
+      (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
+						get_identifier ("__vector __bool long"),
+						bool_V2DI_type_node));
+    }
 
   if (TARGET_PAIRED_FLOAT)
     paired_init_builtins ();
@@ -10924,8 +11026,10 @@ altivec_init_builtins (void)
     {
       enum machine_mode mode1;
       tree type;
-      bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
-			   && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
+      bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+			     && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+			    || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
+				&& dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
 
       if (is_overloaded)
 	mode1 = VOIDmode;
@@ -11247,8 +11351,10 @@ rs6000_common_init_builtins (void)
 	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
 	continue;
 
-      if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
-	  && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
+	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
 	{
 	  if (! (type = opaque_ftype_opaque_opaque_opaque))
 	    type = opaque_ftype_opaque_opaque_opaque
@@ -11286,8 +11392,10 @@ rs6000_common_init_builtins (void)
 	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
 	continue;
 
-      if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
-	  && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
+	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
 	{
 	  if (! (type = opaque_ftype_opaque_opaque))
 	    type = opaque_ftype_opaque_opaque
@@ -11347,8 +11455,10 @@ rs6000_common_init_builtins (void)
 	  || (mask == 0 && !TARGET_PAIRED_FLOAT))
 	continue;
 
-      if (d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
-	  && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+      if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
+	   && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
+	  || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
+	      && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
 	{
 	  if (! (type = opaque_ftype_opaque))
 	    type = opaque_ftype_opaque
@@ -21929,6 +22039,7 @@ rs6000_handle_altivec_attribute (tree *n
     case 'b':
       switch (mode)
 	{
+	case DImode: case V2DImode: result = bool_V2DI_type_node; break;
 	case SImode: case V4SImode: result = bool_V4SI_type_node; break;
 	case HImode: case V8HImode: result = bool_V8HI_type_node; break;
 	case QImode: case V16QImode: result = bool_V16QI_type_node;
@@ -21973,6 +22084,7 @@ rs6000_mangle_type (const_tree type)
   if (type == bool_short_type_node) return "U6__bools";
   if (type == pixel_type_node) return "u7__pixel";
   if (type == bool_int_type_node) return "U6__booli";
+  if (type == bool_long_type_node) return "U6__booll";
 
   /* Mangle IBM extended float long double as `g' (__float128) on
      powerpc*-linux where long-double-64 previously was the default.  */
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 146656)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -25,6 +25,9 @@
 ;; Iterator for the 2 64-bit vector types
 (define_mode_iterator VSX_D [V2DF V2DI])
 
+;; Iterator for the 2 32-bit vector types
+(define_mode_iterator VSX_W [V4SF V4SI])
+
 ;; Iterator for vector floating point types supported by VSX
 (define_mode_iterator VSX_F [V4SF V2DF])
 
@@ -222,7 +225,12 @@
    (UNSPEC_VSX_NMSUB		513)
    (UNSPEC_VSX_RSQRTE		514)
    (UNSPEC_VSX_TDIV		515)
-   (UNSPEC_VSX_TSQRT		516)])
+   (UNSPEC_VSX_TSQRT		516)
+   (UNSPEC_VSX_XXPERMDI		517)
+   (UNSPEC_VSX_SET		518)
+   (UNSPEC_VSX_ROUND_I		519)
+   (UNSPEC_VSX_ROUND_IC		520)
+   (UNSPEC_VSX_SLDWI		521)])
 
 ;; VSX moves
 (define_insn "*vsx_mov<mode>"
@@ -760,13 +768,13 @@
   [(set_attr "type" "<VStype_simple>")
    (set_attr "fp_type" "<VSfptype_simple>")])
 
-(define_insn "vsx_vsel<mode>"
-  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
-	(if_then_else:VSX_F (ne (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
+(define_insn "*vsx_vsel<mode>"
+  [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa")
+	(if_then_else:VSX_L (ne (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa")
 				(const_int 0))
-			    (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")
-			    (match_operand:VSX_F 3 "vsx_register_operand" "<VSr>,wa")))]
-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+			    (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa")
+			    (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "xxsel %x0,%x3,%x2,%x1"
   [(set_attr "type" "vecperm")])
 
@@ -791,7 +799,7 @@
   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
   	(fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
   "VECTOR_UNIT_VSX_P (<MODE>mode)"
-  "x<VSv>r<VSs>piz %x0,%x1"
+  "x<VSv>r<VSs>iz %x0,%x1"
   [(set_attr "type" "<VStype_simple>")
    (set_attr "fp_type" "<VSfptype_simple>")])
 
@@ -828,6 +836,24 @@
    (set_attr "fp_type" "<VSfptype_simple>")])
 
 ;; Math rounding functions
+(define_insn "vsx_x<VSv>r<VSs>i"
+  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
+		      UNSPEC_VSX_ROUND_I))]
+  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "x<VSv>r<VSs>i %x0,%x1"
+  [(set_attr "type" "<VStype_simple>")
+   (set_attr "fp_type" "<VSfptype_simple>")])
+
+(define_insn "vsx_x<VSv>r<VSs>ic"
+  [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
+	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
+		      UNSPEC_VSX_ROUND_IC))]
+  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "x<VSv>r<VSs>ic %x0,%x1"
+  [(set_attr "type" "<VStype_simple>")
+   (set_attr "fp_type" "<VSfptype_simple>")])
+
 (define_insn "vsx_btrunc<mode>2"
   [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
 	(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
@@ -1004,18 +1030,18 @@
 	 [(match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,wa")
 	  (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")]
 	 UNSPEC_VSX_CONCAT))]
-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "xxpermdi %x0,%x1,%x2,0"
   [(set_attr "type" "vecperm")])
 
 ;; Set the element of a V2DI/VD2F mode
 (define_insn "vsx_set_<mode>"
   [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
-	(vec_merge:VSX_D
-	 (match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
-	 (vec_duplicate:VSX_D (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,f"))
-	 (match_operand:QI 3 "u5bit_cint_operand" "i,i")))]
-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+	(unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
+		       (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")
+		       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
+		      UNSPEC_VSX_SET))]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
   if (INTVAL (operands[3]) == 0)
     return \"xxpermdi %x0,%x1,%x2,1\";
@@ -1032,7 +1058,7 @@
 	(vec_select:<VS_scalar> (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa")
 		       (parallel
 			[(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))]
-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
   gcc_assert (UINTVAL (operands[2]) <= 1);
   operands[3] = GEN_INT (INTVAL (operands[2]) << 1);
@@ -1040,8 +1066,19 @@
 }
   [(set_attr "type" "vecperm")])
 
-;; General V2DF permute, extract_{high,low,even,odd}
+;; General V2DF/V2DI permute
 (define_insn "vsx_xxpermdi_<mode>"
+  [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa")
+	(unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa")
+		       (match_operand:VSX_D 2 "vsx_register_operand" "wd,wa")
+		       (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
+		      UNSPEC_VSX_XXPERMDI))]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
+  "xxpermdi %x0,%x1,%x2,%3"
+  [(set_attr "type" "vecperm")])
+
+;; Varient of xxpermdi that is emitted by the vec_interleave functions
+(define_insn "*vsx_xxpermdi2_<mode>"
   [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
 	(vec_concat:VSX_D
 	 (vec_select:<VS_scalar>
@@ -1052,7 +1089,7 @@
 	  (match_operand:VSX_D 3 "vsx_register_operand" "wd")
 	  (parallel
 	   [(match_operand:QI 4 "u5bit_cint_operand" "i")]))))]
-  "VECTOR_UNIT_VSX_P (<MODE>mode)"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
   gcc_assert ((UINTVAL (operands[2]) <= 1) && (UINTVAL (operands[4]) <= 1));
   operands[5] = GEN_INT (((INTVAL (operands[2]) & 1) << 1)
@@ -1062,7 +1099,7 @@
   [(set_attr "type" "vecperm")])
 
 ;; V2DF splat
-(define_insn "vsx_splat<mode>"
+(define_insn "vsx_splat_<mode>"
   [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa")
 	(vec_duplicate:VSX_D
 	 (match_operand:<VS_scalar> 1 "input_operand" "ws,f,Z,wa,wa,Z")))]
@@ -1076,52 +1113,66 @@
    lxvdsx %x0,%y1"
   [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
 
-;; V4SF splat
-(define_insn "*vsx_xxspltw"
-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa")
-	(vec_duplicate:V4SF
-	 (vec_select:SF (match_operand:V4SF 1 "vsx_register_operand" "wf,wa")
-			(parallel
-			 [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
-  "VECTOR_UNIT_VSX_P (V4SFmode)"
+;; V4SF/V4SI splat
+(define_insn "vsx_xxspltw_<mode>"
+  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
+	(vec_duplicate:VSX_W
+	 (vec_select:<VS_scalar>
+	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
+	  (parallel
+	   [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "xxspltw %x0,%x1,%2"
   [(set_attr "type" "vecperm")])
 
-;; V4SF interleave
-(define_insn "vsx_xxmrghw"
-  [(set (match_operand:V4SF 0 "register_operand" "=wf,?wa")
-        (vec_merge:V4SF
-	 (vec_select:V4SF (match_operand:V4SF 1 "vsx_register_operand" "wf,wa")
-			  (parallel [(const_int 0)
-				     (const_int 2)
-				     (const_int 1)
-				     (const_int 3)]))
-	 (vec_select:V4SF (match_operand:V4SF 2 "vsx_register_operand" "wf,wa")
-			  (parallel [(const_int 2)
-				     (const_int 0)
-				     (const_int 3)
-				     (const_int 1)]))
+;; V4SF/V4SI interleave
+(define_insn "vsx_xxmrghw_<mode>"
+  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
+        (vec_merge:VSX_W
+	 (vec_select:VSX_W
+	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
+	  (parallel [(const_int 0)
+		     (const_int 2)
+		     (const_int 1)
+		     (const_int 3)]))
+	 (vec_select:VSX_W
+	  (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")
+	  (parallel [(const_int 2)
+		     (const_int 0)
+		     (const_int 3)
+		     (const_int 1)]))
 	 (const_int 5)))]
-  "VECTOR_UNIT_VSX_P (V4SFmode)"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "xxmrghw %x0,%x1,%x2"
   [(set_attr "type" "vecperm")])
 
-(define_insn "vsx_xxmrglw"
-  [(set (match_operand:V4SF 0 "register_operand" "=wf,?wa")
-        (vec_merge:V4SF
-	 (vec_select:V4SF
-	  (match_operand:V4SF 1 "register_operand" "wf,wa")
+(define_insn "vsx_xxmrglw_<mode>"
+  [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa")
+        (vec_merge:VSX_W
+	 (vec_select:VSX_W
+	  (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa")
 	  (parallel [(const_int 2)
 		     (const_int 0)
 		     (const_int 3)
 		     (const_int 1)]))
-	 (vec_select:V4SF
-	  (match_operand:V4SF 2 "register_operand" "wf,?wa")
+	 (vec_select:VSX_W
+	  (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")
 	  (parallel [(const_int 0)
 		     (const_int 2)
 		     (const_int 1)
 		     (const_int 3)]))
 	 (const_int 5)))]
-  "VECTOR_UNIT_VSX_P (V4SFmode)"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "xxmrglw %x0,%x1,%x2"
   [(set_attr "type" "vecperm")])
+
+;; Shift left double by word immediate
+(define_insn "vsx_xxsldwi_<mode>"
+  [(set (match_operand:VSX_L 0 "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:QI 3 "u5bit_cint_operand" "i")]
+		      UNSPEC_VSX_SLDWI))]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
+  "xxsldwi %x0,%x1,%x2,%3"
+  [(set_attr "type" "vecperm")])
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 146656)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -3372,21 +3372,36 @@ enum rs6000_builtins
   VSX_BUILTIN_XVTDIVSP,
   VSX_BUILTIN_XVTSQRTDP,
   VSX_BUILTIN_XVTSQRTSP,
-  VSX_BUILTIN_XXLAND,
-  VSX_BUILTIN_XXLANDC,
-  VSX_BUILTIN_XXLNOR,
-  VSX_BUILTIN_XXLOR,
-  VSX_BUILTIN_XXLXOR,
-  VSX_BUILTIN_XXMRGHD,
-  VSX_BUILTIN_XXMRGHW,
-  VSX_BUILTIN_XXMRGLD,
-  VSX_BUILTIN_XXMRGLW,
-  VSX_BUILTIN_XXPERMDI,
-  VSX_BUILTIN_XXSEL,
-  VSX_BUILTIN_XXSLDWI,
-  VSX_BUILTIN_XXSPLTD,
-  VSX_BUILTIN_XXSPLTW,
-  VSX_BUILTIN_XXSWAPD,
+  VSX_BUILTIN_XXSEL_2DI,
+  VSX_BUILTIN_XXSEL_2DF,
+  VSX_BUILTIN_XXSEL_4SI,
+  VSX_BUILTIN_XXSEL_4SF,
+  VSX_BUILTIN_XXSEL_8HI,
+  VSX_BUILTIN_XXSEL_16QI,
+  VSX_BUILTIN_VPERM_2DI,
+  VSX_BUILTIN_VPERM_2DF,
+  VSX_BUILTIN_VPERM_4SI,
+  VSX_BUILTIN_VPERM_4SF,
+  VSX_BUILTIN_VPERM_8HI,
+  VSX_BUILTIN_VPERM_16QI,
+  VSX_BUILTIN_XXPERMDI_2DF,
+  VSX_BUILTIN_XXPERMDI_2DI,
+  VSX_BUILTIN_CONCAT_2DF,
+  VSX_BUILTIN_CONCAT_2DI,
+  VSX_BUILTIN_SET_2DF,
+  VSX_BUILTIN_SET_2DI,
+  VSX_BUILTIN_SPLAT_2DF,
+  VSX_BUILTIN_SPLAT_2DI,
+  VSX_BUILTIN_XXMRGHW_4SF,
+  VSX_BUILTIN_XXMRGHW_4SI,
+  VSX_BUILTIN_XXMRGLW_4SF,
+  VSX_BUILTIN_XXMRGLW_4SI,
+  VSX_BUILTIN_XXSLDWI_16QI,
+  VSX_BUILTIN_XXSLDWI_8HI,
+  VSX_BUILTIN_XXSLDWI_4SI,
+  VSX_BUILTIN_XXSLDWI_4SF,
+  VSX_BUILTIN_XXSLDWI_2DI,
+  VSX_BUILTIN_XXSLDWI_2DF,
 
   /* VSX overloaded builtins, add the overloaded functions not present in
      Altivec.  */
@@ -3396,7 +3411,13 @@ enum rs6000_builtins
   VSX_BUILTIN_VEC_NMADD,
   VSX_BUITLIN_VEC_NMSUB,
   VSX_BUILTIN_VEC_DIV,
-  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_DIV,
+  VSX_BUILTIN_VEC_XXMRGHW,
+  VSX_BUILTIN_VEC_XXMRGLW,
+  VSX_BUILTIN_VEC_XXPERMDI,
+  VSX_BUILTIN_VEC_XXSLDWI,
+  VSX_BUILTIN_VEC_XXSPLTD,
+  VSX_BUILTIN_VEC_XXSPLTW,
+  VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_XXSPLTW,
 
   /* Combined VSX/Altivec builtins.  */
   VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
@@ -3426,13 +3447,16 @@ enum rs6000_builtin_type_index
   RS6000_BTI_unsigned_V16QI,
   RS6000_BTI_unsigned_V8HI,
   RS6000_BTI_unsigned_V4SI,
+  RS6000_BTI_unsigned_V2DI,
   RS6000_BTI_bool_char,          /* __bool char */
   RS6000_BTI_bool_short,         /* __bool short */
   RS6000_BTI_bool_int,           /* __bool int */
+  RS6000_BTI_bool_long,		 /* __bool long */
   RS6000_BTI_pixel,              /* __pixel */
   RS6000_BTI_bool_V16QI,         /* __vector __bool char */
   RS6000_BTI_bool_V8HI,          /* __vector __bool short */
   RS6000_BTI_bool_V4SI,          /* __vector __bool int */
+  RS6000_BTI_bool_V2DI,          /* __vector __bool long */
   RS6000_BTI_pixel_V8HI,         /* __vector __pixel */
   RS6000_BTI_long,	         /* long_integer_type_node */
   RS6000_BTI_unsigned_long,      /* long_unsigned_type_node */
@@ -3467,13 +3491,16 @@ enum rs6000_builtin_type_index
 #define unsigned_V16QI_type_node      (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
 #define unsigned_V8HI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
 #define unsigned_V4SI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
+#define unsigned_V2DI_type_node       (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI])
 #define bool_char_type_node           (rs6000_builtin_types[RS6000_BTI_bool_char])
 #define bool_short_type_node          (rs6000_builtin_types[RS6000_BTI_bool_short])
 #define bool_int_type_node            (rs6000_builtin_types[RS6000_BTI_bool_int])
+#define bool_long_type_node           (rs6000_builtin_types[RS6000_BTI_bool_long])
 #define pixel_type_node               (rs6000_builtin_types[RS6000_BTI_pixel])
 #define bool_V16QI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
 #define bool_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
 #define bool_V4SI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
+#define bool_V2DI_type_node	      (rs6000_builtin_types[RS6000_BTI_bool_V2DI])
 #define pixel_V8HI_type_node	      (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
 
 #define long_integer_type_internal_node  (rs6000_builtin_types[RS6000_BTI_long])
Index: gcc/config/rs6000/altivec.md
===================================================================
--- gcc/config/rs6000/altivec.md	(revision 146656)
+++ gcc/config/rs6000/altivec.md	(working copy)
@@ -462,13 +462,13 @@
   "vcmpgefp %0,%1,%2"
   [(set_attr "type" "veccmp")])
 
-(define_insn "altivec_vsel<mode>"
+(define_insn "*altivec_vsel<mode>"
   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
 	(if_then_else:VM (ne (match_operand:VM 1 "altivec_register_operand" "v")
 			     (const_int 0))
 			 (match_operand:VM 2 "altivec_register_operand" "v")
 			 (match_operand:VM 3 "altivec_register_operand" "v")))]
-  "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
+  "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
   "vsel %0,%3,%2,%1"
   [(set_attr "type" "vecperm")])
 
@@ -808,7 +808,7 @@
 						    (const_int 3)
 						    (const_int 1)]))
 		      (const_int 5)))]
-  "TARGET_ALTIVEC"
+  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
   "vmrghw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -825,7 +825,7 @@
                                                     (const_int 3)
                                                     (const_int 1)]))
                       (const_int 5)))]
-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
+  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
   "vmrghw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -909,7 +909,7 @@
 				     (const_int 1)
 				     (const_int 3)]))
 	 (const_int 5)))]
-  "TARGET_ALTIVEC"
+  "VECTOR_MEM_ALTIVEC_P (V4SImode)"
   "vmrglw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 
@@ -927,7 +927,7 @@
 				     (const_int 1)
 				     (const_int 3)]))
 	 (const_int 5)))]
-  "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
+  "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
   "vmrglw %0,%1,%2"
   [(set_attr "type" "vecperm")])
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-04-26 12:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-26 12:27 [power7-meissner] Add builtins for VSX instructions Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).