diff mbox

[v2,rs6000] Add built-in function support for Power9 binary floating point operations

Message ID 7d7e497b-c7a0-a82c-0d85-bdc6a8939dc8@linux.vnet.ibm.com
State New
Headers show

Commit Message

Kelvin Nilsen Aug. 4, 2016, 3:27 p.m. UTC
This patch adds built-in support for the following fourteen new binary
floating point instructions introduced with the Power9 architecture: 

VSX Scalar Extract Exponent Double-Precision
VSX Scalar Extract Significand Double-Precision
VSX Scalar Insert Exponent Double-Precision
VSX Scalar Compare Exponents Double-Precision
VSX Scalar Test Data Class Double-Precision
VSX Scalar Test Data Class Single-Precision
VSX Vector Extract Exponent Double-Precision
VSX Vector Extract Exponent Single-Precision
VSX Vector Extract Significand Double-Precision
VSX Vector Extract Significand Single-Precision
VSX Vector Insert Exponent Double-Precision
VSX Vector Insert Exponent Single-Precision
VSX Vector Test Data Class Double-Precision
VSX Vector Test Data Class Single-Precision

This patch differs from the first version of this patch in the
following ways:

1. Added semicolons where they were missing in extend.texi 
   descriptions of new built-in functions.
2. Reformatted the word wrap and indentation on some code
   displays within extend.texi.
3. Removed various trailing spaces in extend.texi and in 
   source files.
4. Removed a dg-skip-if dejagnu directive from 50 test
   files and placed this functionality into the corresponding
   bfp.exp file instead.
5. Improved comments describing multiple dejagnu test programs.
6. In vsx.md, removed newly introduced VSX_SF mode iterator and
   replaced all uses with existing SFDF mode iterator.
7. In vsx.md, removed newly introduced vsx_sf_suffix mode
   attributes and replaced with existing Fvsx mode attributes.
8. In vsx.md, removed VSX_F_INTEGER mode attributes and replaced
   with VSI.
9. In vsx.md, removed vsx_f_suffix mode attributes and replaced with 
   VSs.
10. Fixed indentation and line wrap and use of spaces and tabs for 
    several define_insn and define_expand directives.
11. Fixed the attributes associated with new define_insn directives.
12. Added an operand predicate on the new xscmpexpdp insn.
13. In rs6000-c.c, moved the declaration of the unsupported_builtin
    variable closer to its usage.
14. In rs6000-builtin.def, replaced spaces with tabs in the argument
    lists for multiple BU_P9V_VSX_2 macro expansions.
15. In predicates.md, rewrote the new u7bit_cint_operand predicate
    to use IN_RANGE and INTVAL.

Thank you to Segher Boessenkool and Pat Haugen for helpful review
feedback.

The patch has been bootstrapped and tested on powerpc64le-unknown-linux
and on powerpc64-unknown-linux (big-endian) with no regressions.  Is
this ok for the trunk?

gcc/ChangeLog:

2016-08-04  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
	overloaded binary floating point functions.
	(altivec_resolve_overloaded_builtin): Improve error messages to
	distinguish between functions not supported in the current
	compiler configuration and functions that were invoked with an
	invalid parameter combination, and include the built-in function
	name in both error messages.
	* config/rs6000/rs6000-builtin.def (BU_P9V_64BIT_VSX_1): New macro
	for power9 built-ins.
	(BU_P9V_VSX_2): Likewise.
	(BU_P9V_64BIT_VSX_2): Likewise.
	(VSEEDP): Add scalar extract exponent support.
	(VSEESP): Add scalar extract signature support.
	(VSTDCNDP): Add scalar test negative support.
	(VSTDCNSP): Likewise.
	(VSIEDP): Add scalar insert exponent support.
	(VSCEDPGT): Add scalar compare exponent greater than support.
	(VSCEDPLT): Add scalar compare exponent less than support.
	(VSCEDPEQ): Add scalar compare exponent test-for-equality support.
	(VSCEDPUO): Add scalar compare exponent test-for-unordered support.
	(VSTDCDP): Add scalar test data class support.
	(VSTDCSP): Likewise.
	(VSEEDP): Add overload support for scalar extract exponent
	operation.
	(VSESDP): Add overload support for scalar extract signature
	operation.
	(VSTDCN): Add overload support for scalar test negative
	operation.
	(VSTDCNDP): Add overload support for scalar test negative
	operation.
	(VSTDCNSP): Add overload support for scalar test negative
	operation.
	(VSIEDP): Add overload support for scalar insert exponent
	operation.
	(VSTDC): Add overload support for scalar test data class
	operation.
	(VSTDCDP): Add overload support for scalar test data class
	operation.
	(VSTDCSP): Add overload support for scalar test data class
	opreation.
	(VSCEDPGT): Add overload support for scalar compare exponent
	greater than operation.
	(VSCEDPLT): Add overload support for scalar compare exponent
	less than operation.
	(VSCEDPEQ): Add overload support for scalar compare exponent
	test-for-equality operation.
	(VSCEDPUO): Add overload support for scalar compare exponent
	test-for-unordered operation.
	(VEEDP): Add vector extract exponent support.
	(VEESP): Likewise.
	(VESDP): Add vector extract significand support.
	(VESSP): Likewise.
	(VIEDP): Add vector insert exponent support.
	(VIESP): Likewise.
	(VTDCDP): Add vector test data class support.
	(VTDCSP): Likewise.
	(VES): Add overload support for vector extract significand operation.
	(VESDP): Likewise.
	(VESSP): Likewise
	(VEE): Add overload support for vector extract exponent operation.
	(VEEDP): Likewise.
	(VEESP): Likewise.
	(VTDC): Add overload support for vector test data class operation.
	(VTDCDP): Likewise.
	(VTDCSP): Likewise.
	(VIE): Add overload support for vector insert exponent operation.
	(VIEDP): Likewise.
	(VIESP): Likewise.
	* config/rs6000/rs6000.c (rs6000_overloaded_builtin_name): New
	function.
	(rs6000_expand_binop_builtin): Add check to enforce that argument
	2 of the test data class operations is a 7-bit unsigned literal.
	(rs6000_invalid_builtin): Add code to issue an error message if a
	built-in function that requires the power9_vector and -m32
	command-line options is compiled without these options.
	* config/rs6000/vsx.md (UNSPEC_VSX_SXEXPDP): New value.
	(UNSPEC_VSX_SXSIGDP): New value.
	(UNSPEC_VSX_SXSIGPDP): New value.
	(UNSPEC_VSX_SIEXPDP): New value.
	(UNSPEC_VSX_SCMPEXPDP): New value.
	(UNSPEC_VSX_STSTDC): New value.
	(UNSPEC_VSX_VXEXP): New value.
	(UNSPEC_VSX_VXSIG): New value.
	(UNSPEC_VSX_VIEXP): New value.
	(UNSPEC_VSX_VTSTDC): New value.
	(xsxexpdp): New insn for scalar extract exponent.
	(xsxsigdp): New insn for scalar extract significand.
	(xsiexpdp): New insn for scalar insert exponent.
	(xscmpexpdp_<code>): New expansion for scalar compare exponents.
	(*xscmpexpdp): New insn for scalar compare exponents.
	(xststdc<Fvsx): New expansion for both single- and
	double-precision scalar test data class operations.
	(xststdcneg<Fvsx>): New expansion for both single- and
	double-precision scalar test for negative value operations.
	(*xststdc<Fvsx>): New insn for scalar test data class
	operation.
	(xvxexp<VSs>): New insn for single- and double-precision
	vector extract exponent operation.
	(xvxsig<VSs>): New insn for single- and double-precision
	vector extract significand operation.
	(xviexp<VSs>): New insn for single- and double-precision
	vector insert exponent operation.
	(xvtstdc<VSs>): New insn for single- and double-precision
	vector test data class operation.
	* config/rs6000/predicates.md (u7bit_cint_operand): New predicate
	to enforce constraint that operand is a 7-bit unsigned literal.
	* config/rs6000/rs6000-protos.h (rs6000_overloaded_builtin_name):
	New prototype.
	* config/rs6000/altivec.h (vec_extract_exp): New macro.
	(vec_extract_sig): New macro.
	(vec_insert_exp): New macro.
	(vec_test_data_class): New macro.
	(scalar_extract_exp): New macro.
	(scalar_extract_sig): New macro.
	(scalar_insert_exp): New macro.
	(scalar_test_data_class): New macro.
	(scalar_test_neg): New macro.
	(scalar_cmp_exp_gt): New macro.
	(scalar_cmp_exp_lt): New macro.
	(scalar_cmp_exp_eq): New macro.
	(scalar_cmp_exp_unordered): New macro.
	* doc/extend.texi (PowerPC AltiVec Built-in Functions): Document
	built-in functions to represent the Power9 binary floating-point
	support instructions.

gcc/testsuite/ChangeLog:

2016-08-04  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target/powerpc/bfp/bfp.exp: New file.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-eq-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-eq-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-gt-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-gt-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-lt-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-lt-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-5.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-6.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-7.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-0.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-1.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-2.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-3.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-0.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-1.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-2.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-3.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-0.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-1.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-2.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-3.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-0.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-1.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-2.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-3.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-0.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-1.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-2.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-3.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-4.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-5.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-6.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-7.c: New test.

Comments

Segher Boessenkool Aug. 4, 2016, 10:39 p.m. UTC | #1
On Thu, Aug 04, 2016 at 09:27:55AM -0600, Kelvin Nilsen wrote:
> The patch has been bootstrapped and tested on powerpc64le-unknown-linux
> and on powerpc64-unknown-linux (big-endian) with no regressions.  Is
> this ok for the trunk?

Just a couple more nits..  Okay for trunk with those fixed / looked at.

> --- gcc/config/rs6000/rs6000-c.c	(revision 238014)
> +++ gcc/config/rs6000/rs6000-c.c	(working copy)
> @@ -4302,6 +4302,84 @@ const struct altivec_builtin_types altivec_overloa
>      RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
>      RS6000_BTI_unsigned_V4SI, 0 },
>  
> +  { P9V_BUILTIN_VEC_VES, P9V_BUILTIN_VESSP,
> +    RS6000_BTI_V4SI, RS6000_BTI_V4SF, 0, 0 },   

There are still trailing spaces here.

> +(define_expand "xscmpexpdp_<code>"
> +  [(set (match_dup 3)
> +	(compare:CCFP
> +	 (unspec:DF
> +	  [(match_operand:DF 1 "vsx_register_operand" "wa")
> +	   (match_operand:DF 2 "vsx_register_operand" "wa")]
> +	  UNSPEC_VSX_SCMPEXPDP)
> +	 (match_dup 4)))
> +   (set (match_operand:SI 0 "register_operand" "=r")
> +	(CMP_TEST:SI (match_dup 3)
> +		     (const_int 0)))]
> +  "TARGET_P9_VECTOR"
> +{
> +  operands[3] = gen_reg_rtx (CCFPmode);
> +  operands[4] = CONST0_RTX (SImode);
> +})

"CONST0_RTX (SImode)" is just "const0_rtx".  You can write it in the
pattern I think?  As "(const_int 0)"?

> +# Exit immediately if this isn't a PowerPC target.
> +if { ![istarget powerpc*-*-*] && ![istarget rs6000-*-*] } then {
> +  return
> +}

I would put the AIX test here, too.

Thanks,


Segher
Pat Haugen Aug. 5, 2016, 9:52 p.m. UTC | #2
On 08/04/2016 10:27 AM, Kelvin Nilsen wrote:
> +  "xsxexpdp %0,%x1"
> +  [(set_attr "type" "vecsimple")])

> +  "xsxsigdp %0,%x1"
> +  [(set_attr "type" "vecsimple")])

'integer' for both, reasoning in response on initial thread for this patch.

> +  "xvxexp<VSs> %x0,%x1"
> +  [(set_attr "type" "fpsimple")])

> +  "xvxsig<VSs> %x0,%x1"
> +  [(set_attr "type" "fpsimple")])

'vecsimple' for both.

-Pat
diff mbox

Patch

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 238014)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -4302,6 +4302,84 @@  const struct altivec_builtin_types altivec_overloa
     RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
     RS6000_BTI_unsigned_V4SI, 0 },
 
+  { P9V_BUILTIN_VEC_VES, P9V_BUILTIN_VESSP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, 0, 0 },   
+  { P9V_BUILTIN_VEC_VES, P9V_BUILTIN_VESDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, 0, 0 },   
+
+  { P9V_BUILTIN_VEC_VESSP, P9V_BUILTIN_VESSP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, 0, 0 },   
+  { P9V_BUILTIN_VEC_VESDP, P9V_BUILTIN_VESDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, 0, 0 },   
+
+  { P9V_BUILTIN_VEC_VEE, P9V_BUILTIN_VEESP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, 0, 0 },   
+  { P9V_BUILTIN_VEC_VEE, P9V_BUILTIN_VEEDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, 0, 0 },   
+
+  { P9V_BUILTIN_VEC_VEESP, P9V_BUILTIN_VEESP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, 0, 0 },   
+  { P9V_BUILTIN_VEC_VEEDP, P9V_BUILTIN_VEEDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, 0, 0 },   
+
+  { P9V_BUILTIN_VEC_VTDC, P9V_BUILTIN_VTDCSP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_UINTSI, 0 },   
+  { P9V_BUILTIN_VEC_VTDC, P9V_BUILTIN_VTDCDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, RS6000_BTI_UINTSI, 0 },   
+
+  { P9V_BUILTIN_VEC_VTDCSP, P9V_BUILTIN_VTDCSP,
+    RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_UINTSI, 0 },   
+  { P9V_BUILTIN_VEC_VTDCDP, P9V_BUILTIN_VTDCDP,
+    RS6000_BTI_V2DI, RS6000_BTI_V2DF, RS6000_BTI_UINTSI, 0 },   
+
+  { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIESP,
+    RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIEDP,
+    RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+
+  { P9V_BUILTIN_VEC_VIESP, P9V_BUILTIN_VIESP,
+    RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VIEDP, P9V_BUILTIN_VIEDP,
+    RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
+
+  { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCSP,
+    RS6000_BTI_UINTSI, RS6000_BTI_float, RS6000_BTI_UINTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCDP,
+    RS6000_BTI_UINTSI, RS6000_BTI_double, RS6000_BTI_UINTSI, 0 },
+
+  { P9V_BUILTIN_VEC_VSTDCSP, P9V_BUILTIN_VSTDCSP,
+    RS6000_BTI_UINTSI, RS6000_BTI_float, RS6000_BTI_UINTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDCDP, P9V_BUILTIN_VSTDCDP,
+    RS6000_BTI_UINTSI, RS6000_BTI_double, RS6000_BTI_UINTSI, 0 },
+
+  { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNSP,
+    RS6000_BTI_INTSI, RS6000_BTI_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNDP,
+    RS6000_BTI_INTSI, RS6000_BTI_double, 0, 0 },
+
+  { P9V_BUILTIN_VEC_VSTDCNSP, P9V_BUILTIN_VSTDCNSP,
+    RS6000_BTI_INTSI, RS6000_BTI_float, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCNDP, P9V_BUILTIN_VSTDCNDP,
+    RS6000_BTI_INTSI, RS6000_BTI_double, 0, 0 },
+
+  { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEDP,
+    RS6000_BTI_UINTSI, RS6000_BTI_double, 0, 0 },
+
+  { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESDP,
+    RS6000_BTI_UINTDI, RS6000_BTI_double, 0, 0 },
+
+  { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDP,
+    RS6000_BTI_double, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 },
+
+  { P9V_BUILTIN_VEC_VSCEDPGT, P9V_BUILTIN_VSCEDPGT,
+    RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
+  { P9V_BUILTIN_VEC_VSCEDPLT, P9V_BUILTIN_VSCEDPLT,
+    RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
+  { P9V_BUILTIN_VEC_VSCEDPEQ, P9V_BUILTIN_VSCEDPEQ,
+    RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
+  { P9V_BUILTIN_VEC_VSCEDPUO, P9V_BUILTIN_VSCEDPUO,
+    RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 },
+
   { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
     RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 },
   { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD,
@@ -5480,23 +5558,42 @@  assignment for unaligned loads and stores");
       return build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (types[0]));
     }
 
-  for (desc = altivec_overloaded_builtins;
-       desc->code && desc->code != fcode; desc++)
-    continue;
-
-  /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
-     the opX fields.  */
-  for (; desc->code == fcode; desc++)
-    if ((desc->op1 == RS6000_BTI_NOT_OPAQUE
-	 || rs6000_builtin_type_compatible (types[0], desc->op1))
-	&& (desc->op2 == RS6000_BTI_NOT_OPAQUE
-	    || rs6000_builtin_type_compatible (types[1], desc->op2))
-	&& (desc->op3 == RS6000_BTI_NOT_OPAQUE
-	    || rs6000_builtin_type_compatible (types[2], desc->op3))
-	&& rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
-      return altivec_build_resolved_builtin (args, n, desc);
-
+  {
+    bool unsupported_builtin = false;
+    for (desc = altivec_overloaded_builtins;
+	 desc->code && desc->code != fcode; desc++)
+      continue;
+    
+    /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
+       the opX fields.  */
+    for (; desc->code == fcode; desc++)
+      {
+	if ((desc->op1 == RS6000_BTI_NOT_OPAQUE
+	     || rs6000_builtin_type_compatible (types[0], desc->op1))
+	    && (desc->op2 == RS6000_BTI_NOT_OPAQUE
+		|| rs6000_builtin_type_compatible (types[1], desc->op2))
+	    && (desc->op3 == RS6000_BTI_NOT_OPAQUE
+		|| rs6000_builtin_type_compatible (types[2], desc->op3)))
+	  {
+	    if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
+	      return altivec_build_resolved_builtin (args, n, desc);
+	    else
+	      unsupported_builtin = true;
+	  }
+      }
+    
+    if (unsupported_builtin)
+      {
+	const char *name = rs6000_overloaded_builtin_name (fcode);
+	error ("Builtin function %s not supported in this compiler configuration", 
+	       name);
+	return error_mark_node;
+      }
+  }
  bad:
-  error ("invalid parameter combination for AltiVec intrinsic");
-  return error_mark_node;
+    {
+      const char *name = rs6000_overloaded_builtin_name (fcode);
+      error ("invalid parameter combination for AltiVec intrinsic %s", name);
+      return error_mark_node;
+    }
 }
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 238014)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -799,6 +799,32 @@ 
 		     | RS6000_BTC_UNARY),				\
 		    CODE_FOR_ ## ICODE)			/* ICODE */
 
+#define BU_P9V_64BIT_VSX_1(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_1 (P9V_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_vsx_" NAME,		/* NAME */	\
+		    (RS6000_BTM_64BIT					\
+		     | RS6000_BTM_P9_VECTOR),		/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_UNARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+#define BU_P9V_VSX_2(ENUM, NAME, ATTR, ICODE)				\
+  RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_vsx_" NAME,		/* NAME */	\
+		    RS6000_BTM_P9_VECTOR,		/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_BINARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+#define BU_P9V_64BIT_VSX_2(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_vsx_" NAME,		/* NAME */	\
+		    (RS6000_BTM_64BIT					\
+		     | RS6000_BTM_P9_VECTOR),		/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_BINARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
 #define BU_P9V_OVERLOAD_1(ENUM, NAME)					\
   RS6000_BUILTIN_1 (P9V_BUILTIN_VEC_ ## ENUM,		/* ENUM */	\
 		    "__builtin_vec_" NAME,		/* NAME */	\
@@ -1799,6 +1825,74 @@  BU_P9V_OVERLOAD_2 (VADUB,	"vadub")
 BU_P9V_OVERLOAD_2 (VADUH,	"vaduh")
 BU_P9V_OVERLOAD_2 (VADUW,	"vaduw")
 
+/* 1 argument vsx scalar functions added in ISA 3.0 (power9).  */
+BU_P9V_64BIT_VSX_1 (VSEEDP,	"scalar_extract_exp",	CONST,	xsxexpdp)
+BU_P9V_64BIT_VSX_1 (VSESDP,	"scalar_extract_sig",	CONST,	xsxsigdp)
+
+BU_P9V_VSX_1 (VSTDCNDP,	"scalar_test_neg_dp",	CONST,	xststdcnegdp)
+BU_P9V_VSX_1 (VSTDCNSP,	"scalar_test_neg_sp",	CONST,	xststdcnegsp)
+
+/* 2 argument vsx scalar functions added in ISA 3.0 (power9).  */
+BU_P9V_64BIT_VSX_2 (VSIEDP,	"scalar_insert_exp",	CONST,	xsiexpdp)
+
+BU_P9V_VSX_2 (VSCEDPGT,	"scalar_cmp_exp_dp_gt",	CONST,	xscmpexpdp_gt)
+BU_P9V_VSX_2 (VSCEDPLT,	"scalar_cmp_exp_dp_lt",	CONST,	xscmpexpdp_lt)
+BU_P9V_VSX_2 (VSCEDPEQ,	"scalar_cmp_exp_dp_eq",	CONST,	xscmpexpdp_eq)
+BU_P9V_VSX_2 (VSCEDPUO,	"scalar_cmp_exp_dp_unordered",	CONST,	xscmpexpdp_unordered)
+
+BU_P9V_VSX_2 (VSTDCDP,	"scalar_test_data_class_dp",	CONST,	xststdcdp)
+BU_P9V_VSX_2 (VSTDCSP,	"scalar_test_data_class_sp",	CONST,	xststdcsp)
+
+/* ISA 3.0 vector scalar overloaded 1 argument functions.  */
+BU_P9V_OVERLOAD_1 (VSEEDP,	"scalar_extract_exp")
+BU_P9V_OVERLOAD_1 (VSESDP,	"scalar_extract_sig")
+
+BU_P9V_OVERLOAD_1 (VSTDCN,	"scalar_test_neg")
+BU_P9V_OVERLOAD_1 (VSTDCNDP,	"scalar_test_neg_dp")
+BU_P9V_OVERLOAD_1 (VSTDCNSP,	"scalar_test_neg_sp")
+
+/* ISA 3.0 vector scalar overloaded 2 argument functions.  */
+BU_P9V_OVERLOAD_2 (VSIEDP,	"scalar_insert_exp")
+
+BU_P9V_OVERLOAD_2 (VSTDC,	"scalar_test_data_class")
+BU_P9V_OVERLOAD_2 (VSTDCDP,	"scalar_test_data_class_dp")
+BU_P9V_OVERLOAD_2 (VSTDCSP,	"scalar_test_data_class_sp")
+
+BU_P9V_OVERLOAD_2 (VSCEDPGT,	"scalar_cmp_exp_gt")
+BU_P9V_OVERLOAD_2 (VSCEDPLT,	"scalar_cmp_exp_lt")
+BU_P9V_OVERLOAD_2 (VSCEDPEQ,	"scalar_cmp_exp_eq")
+BU_P9V_OVERLOAD_2 (VSCEDPUO,	"scalar_cmp_exp_unordered")
+
+/* 1 argument vsx vector functions added in ISA 3.0 (power9).  */
+BU_P9V_VSX_1 (VEEDP, "extract_exp_dp", CONST, xvxexpdp)
+BU_P9V_VSX_1 (VEESP, "extract_exp_sp", CONST, xvxexpsp)
+BU_P9V_VSX_1 (VESDP, "extract_sig_dp", CONST, xvxsigdp)
+BU_P9V_VSX_1 (VESSP, "extract_sig_sp", CONST, xvxsigsp)
+
+/* 2 argument vsx vector functions added in ISA 3.0 (power9).  */
+BU_P9V_VSX_2 (VIEDP, "insert_exp_dp", CONST, xviexpdp)
+BU_P9V_VSX_2 (VIESP, "insert_exp_sp", CONST, xviexpsp)
+BU_P9V_VSX_2 (VTDCDP, "test_data_class_dp", CONST, xvtstdcdp)
+BU_P9V_VSX_2 (VTDCSP, "test_data_class_sp", CONST, xvtstdcsp)
+
+/* ISA 3.0 vector overloaded 1 argument functions.  */
+BU_P9V_OVERLOAD_1 (VES,		"extract_sig")
+BU_P9V_OVERLOAD_1 (VESDP,	"extract_sig_dp")
+BU_P9V_OVERLOAD_1 (VESSP,	"extract_sig_sp")
+
+BU_P9V_OVERLOAD_1 (VEE,		"extract_exp")
+BU_P9V_OVERLOAD_1 (VEEDP,	"extract_exp_dp")
+BU_P9V_OVERLOAD_1 (VEESP,	"extract_exp_sp")
+
+/* ISA 3.0 vector overloaded 2 argument functions.  */
+BU_P9V_OVERLOAD_2 (VTDC,	"test_data_class")
+BU_P9V_OVERLOAD_2 (VTDCDP,	"test_data_class_dp")
+BU_P9V_OVERLOAD_2 (VTDCSP,	"test_data_class_sp")
+
+BU_P9V_OVERLOAD_2 (VIE,		"insert_exp")
+BU_P9V_OVERLOAD_2 (VIEDP,	"insert_exp_dp")
+BU_P9V_OVERLOAD_2 (VIESP,	"insert_exp_sp")
+
 
 /* 2 argument extended divide functions added in ISA 2.06.  */
 BU_P7_MISC_2 (DIVWE,		"divwe",	CONST,	dive_si)
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 238014)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -13180,6 +13180,12 @@  rs6000_overloaded_builtin_p (enum rs6000_builtins
   return (rs6000_builtin_info[(int)fncode].attr & RS6000_BTC_OVERLOADED) != 0;
 }
 
+const char *
+rs6000_overloaded_builtin_name (enum rs6000_builtins fncode)
+{
+  return rs6000_builtin_info[(int)fncode].name;
+}
+
 /* Expand an expression EXP that calls a builtin without arguments.  */
 static rtx
 rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
@@ -13399,6 +13405,20 @@  rs6000_expand_binop_builtin (enum insn_code icode,
 	  return CONST0_RTX (tmode);
 	}
     }
+  else if (icode == CODE_FOR_xststdcdp
+	   || icode == CODE_FOR_xststdcsp
+	   || icode == CODE_FOR_xvtstdcdp
+	   || icode == CODE_FOR_xvtstdcsp)
+    {
+      /* Only allow 7-bit unsigned literals. */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+	  || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 127))
+	{
+	  error ("argument 2 must be a 7-bit unsigned literal");
+	  return CONST0_RTX (tmode);
+	}
+    }
 
   if (target == 0
       || GET_MODE (target) != tmode
@@ -15503,6 +15523,10 @@  rs6000_invalid_builtin (enum rs6000_builtins fncod
     error ("Builtin function %s requires the -mhard-dfp option", name);
   else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
     error ("Builtin function %s requires the -mpower8-vector option", name);
+  else if ((fnmask & (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
+	   == (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
+    error ("Builtin function %s requires the -mcpu=power9 and"
+	   " -m64 options", name);
   else if ((fnmask & RS6000_BTM_P9_VECTOR) != 0)
     error ("Builtin function %s requires the -mpower9-vector option", name);
   else if ((fnmask & (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 238014)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -18,6 +18,9 @@ 
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+;; Iterator for comparison types
+(define_code_iterator CMP_TEST [eq lt gt unordered])
+
 ;; Iterator for both scalar and vector floating point types supported by VSX
 (define_mode_iterator VSX_B [DF V4SF V2DF])
 
@@ -309,6 +312,15 @@ 
    UNSPEC_VSX_XVCVDPUXDS
    UNSPEC_VSX_SIGN_EXTEND
    UNSPEC_P9_MEMORY
+   UNSPEC_VSX_SXEXPDP
+   UNSPEC_VSX_SXSIGDP
+   UNSPEC_VSX_SIEXPDP
+   UNSPEC_VSX_SCMPEXPDP
+   UNSPEC_VSX_STSTDC
+   UNSPEC_VSX_VXEXP
+   UNSPEC_VSX_VXSIG
+   UNSPEC_VSX_VIEXP
+   UNSPEC_VSX_VTSTDC
   ])
 
 ;; VSX moves
@@ -2829,3 +2841,157 @@ 
    mfvsrd %0,%x1
    stxsi<wd>x %x1,%y0"
   [(set_attr "type" "mffgpr,fpstore")])
+
+;; ISA 3.0 Binary Floating-Point Support
+
+;; VSX Scalar Extract Exponent Double-Precision
+(define_insn "xsxexpdp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(match_operand:DF 1 "vsx_register_operand" "wa")]
+	 UNSPEC_VSX_SXEXPDP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsxexpdp %0,%x1"
+  [(set_attr "type" "vecsimple")])
+
+;; VSX Scalar Extract Significand Double-Precision
+(define_insn "xsxsigdp"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI [(match_operand:DF 1 "vsx_register_operand" "wa")]
+	 UNSPEC_VSX_SXSIGDP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsxsigdp %0,%x1"
+  [(set_attr "type" "vecsimple")])
+
+;; VSX Scalar Insert Exponent Double-Precision
+(define_insn "xsiexpdp"
+  [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
+	(unspec:DF [(match_operand:DI 1 "register_operand" "r")
+		    (match_operand:DI 2 "register_operand" "r")]
+	 UNSPEC_VSX_SIEXPDP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsiexpdp %x0,%1,%2"
+  [(set_attr "type" "fpsimple")])
+
+;; VSX Scalar Compare Exponents Double-Precision
+(define_expand "xscmpexpdp_<code>"
+  [(set (match_dup 3)
+	(compare:CCFP
+	 (unspec:DF
+	  [(match_operand:DF 1 "vsx_register_operand" "wa")
+	   (match_operand:DF 2 "vsx_register_operand" "wa")]
+	  UNSPEC_VSX_SCMPEXPDP)
+	 (match_dup 4)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(CMP_TEST:SI (match_dup 3)
+		     (const_int 0)))]
+  "TARGET_P9_VECTOR"
+{
+  operands[3] = gen_reg_rtx (CCFPmode);
+  operands[4] = CONST0_RTX (SImode);
+})
+
+(define_insn "*xscmpexpdp"
+  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+	(compare:CCFP
+	 (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "wa")
+		     (match_operand:DF 2 "vsx_register_operand" "wa")]
+	  UNSPEC_VSX_SCMPEXPDP)
+	 (match_operand:SI 3 "zero_constant" "j")))]
+  "TARGET_P9_VECTOR"
+  "xscmpexpdp %0,%x1,%x2"
+  [(set_attr "type" "fpcompare")])
+
+;; VSX Scalar Test Data Class Double- and Single-Precision
+;;  (The lt bit is set if operand 1 is negative.  The eq bit is set
+;;   if any of the conditions tested by operand 2 are satisfied.
+;;   The gt and unordered bits are cleared to zero.)
+(define_expand "xststdc<Fvsx>"
+  [(set (match_dup 3)
+	(compare:CCFP
+	 (unspec:SFDF
+	  [(match_operand:SFDF 1 "vsx_register_operand" "wa")
+	   (match_operand:SI 2 "u7bit_cint_operand" "n")]
+	  UNSPEC_VSX_STSTDC)
+	 (match_dup 4)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(eq:SI (match_dup 3)
+	       (const_int 0)))]
+  "TARGET_P9_VECTOR"
+{
+  operands[3] = gen_reg_rtx (CCFPmode);
+  operands[4] = CONST0_RTX (SImode);
+})
+
+;; The VSX Scalar Test Data Class Double- and Single-Precision
+;; instruction may also be used to test for negative value.
+(define_expand "xststdcneg<Fvsx>"
+  [(set (match_dup 2)
+	(compare:CCFP
+	 (unspec:SFDF
+	  [(match_operand:SFDF 1 "vsx_register_operand" "wa")
+	   (const_int 0)]
+	  UNSPEC_VSX_STSTDC)
+	 (match_dup 3)))
+   (set (match_operand:SI 0 "register_operand" "=r")
+	(lt:SI (match_dup 2)
+	       (const_int 0)))]
+  "TARGET_P9_VECTOR"
+{
+  operands[2] = gen_reg_rtx (CCFPmode);
+  operands[3] = CONST0_RTX (SImode);
+})
+
+(define_insn "*xststdc<Fvsx>"
+  [(set (match_operand:CCFP 0 "" "=y")
+	(compare:CCFP
+	 (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa")
+		       (match_operand:SI 2 "u7bit_cint_operand" "n")]
+	  UNSPEC_VSX_STSTDC)
+	 (match_operand:SI 3 "zero_constant" "j")))]
+  "TARGET_P9_VECTOR"
+  "xststdc<Fvsx> %0,%x1,%2"
+  [(set_attr "type" "fpcompare")])
+
+;; VSX Vector Extract Exponent Double and Single Precision
+(define_insn "xvxexp<VSs>"
+  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
+	(unspec:VSX_F
+	 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")]
+	 UNSPEC_VSX_VXEXP))]
+  "TARGET_P9_VECTOR"
+  "xvxexp<VSs> %x0,%x1"
+  [(set_attr "type" "fpsimple")])
+
+;; VSX Vector Extract Significand Double and Single Precision
+(define_insn "xvxsig<VSs>"
+  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
+	(unspec:VSX_F
+	 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")]
+	 UNSPEC_VSX_VXSIG))]
+  "TARGET_P9_VECTOR"
+  "xvxsig<VSs> %x0,%x1"
+  [(set_attr "type" "fpsimple")])
+
+;; VSX Vector Insert Exponent Double and Single Precision
+(define_insn "xviexp<VSs>"
+  [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
+	(unspec:VSX_F
+	 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
+	  (match_operand:VSX_F 2 "vsx_register_operand" "wa")]
+	 UNSPEC_VSX_VIEXP))]
+  "TARGET_P9_VECTOR"
+  "xviexp<VSs> %x0,%x1,%x2"
+  [(set_attr "type" "vecsimple")])
+
+;; VSX Vector Test Data Class Double and Single Precision
+;; The corresponding elements of the result vector are all ones
+;; if any of the conditions tested by operand 3 are satisfied.
+(define_insn "xvtstdc<VSs>"
+  [(set (match_operand:<VSI> 0 "vsx_register_operand" "=wa")
+	(unspec:<VSI>
+	 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
+	  (match_operand:SI 2 "u7bit_cint_operand" "n")]
+	 UNSPEC_VSX_VTSTDC))]
+  "TARGET_P9_VECTOR"
+  "xvtstdc<VSs> %x0,%x1,%2"
+  [(set_attr "type" "vecsimple")])
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 238014)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -147,6 +147,11 @@ 
   (and (match_code "const_int")
        (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 63")))
 
+;; Return 1 if op is an unsigned 7-bit constant integer.
+(define_predicate "u7bit_cint_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 127)")))
+
 ;; Return 1 if op is a signed 8-bit constant integer.
 ;; Integer multiplication complete more quickly
 (define_predicate "s8bit_cint_operand"
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 238014)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -214,6 +214,7 @@  extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx
 extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
 extern void get_ppc476_thunk_name (char name[32]);
 extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
+extern const char *rs6000_overloaded_builtin_name (enum rs6000_builtins);
 extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
 extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size,
 					   const char *label);
Index: gcc/config/rs6000/altivec.h
===================================================================
--- gcc/config/rs6000/altivec.h	(revision 238014)
+++ gcc/config/rs6000/altivec.h	(working copy)
@@ -409,6 +409,23 @@ 
 
 #define vec_slv __builtin_vec_vslv
 #define vec_srv __builtin_vec_vsrv
+
+#define vec_extract_exp __builtin_vec_extract_exp
+#define vec_extract_sig __builtin_vec_extract_sig
+#define vec_insert_exp __builtin_vec_insert_exp
+#define vec_test_data_class __builtin_vec_test_data_class
+
+#define scalar_extract_exp __builtin_vec_scalar_extract_exp
+#define scalar_extract_sig __builtin_vec_scalar_extract_sig
+#define scalar_insert_exp __builtin_vec_scalar_insert_exp
+#define scalar_test_data_class __builtin_vec_scalar_test_data_class
+#define scalar_test_neg __builtin_vec_scalar_test_neg
+
+#define scalar_cmp_exp_gt __builtin_vec_scalar_cmp_exp_gt
+#define scalar_cmp_exp_lt __builtin_vec_scalar_cmp_exp_lt
+#define scalar_cmp_exp_eq __builtin_vec_scalar_cmp_exp_eq
+#define scalar_cmp_exp_unordered __builtin_vec_scalar_cmp_exp_unordered
+
 #endif
 
 /* Predicates.
Index: gcc/testsuite/gcc.target/powerpc/bfp/bfp.exp
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/bfp.exp	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/bfp.exp	(working copy)
@@ -0,0 +1,41 @@ 
+# Copyright (C) 2014-2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Exit immediately if this isn't a PowerPC target.
+if { ![istarget powerpc*-*-*] && ![istarget rs6000-*-*] } then {
+  return
+}
+
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+  set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib torture-options.exp
+
+# Initialize.
+dg-init
+
+if { ![istarget "powerpc*-*-aix*"] } {
+  dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c*]] "" $DEFAULT_CFLAGS
+}
+
+# All done.
+dg-finish
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_eq (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return scalar_cmp_exp_eq (exponent1, exponent2);
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-1.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+char
+compare_exponents_eq (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  if (scalar_cmp_exp_eq (exponent1, exponent2))
+    return 't';
+  else
+    return 'f';
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_eq (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return __builtin_vec_scalar_cmp_exp_eq (exponent1, exponent2);	/* { dg-error "Builtin function __builtin_vsx_scalar_cmp_exp_dp_eq requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_gt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return scalar_cmp_exp_gt (exponent1, exponent2);
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-1.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+char
+compare_exponents_gt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  if (scalar_cmp_exp_gt (exponent1, exponent2))
+    return 't';
+  else
+    return 'f';
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_gt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return __builtin_vec_scalar_cmp_exp_gt (exponent1, exponent2); /* { dg-error "Builtin function __builtin_vsx_scalar_cmp_exp_dp_gt requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_lt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return scalar_cmp_exp_lt (exponent1, exponent2);
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-1.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+char
+compare_exponents_lt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  if (scalar_cmp_exp_lt (exponent1, exponent2))
+    return 't';
+  else
+    return 'f';
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_lt (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return __builtin_vec_scalar_cmp_exp_lt (exponent1, exponent2);	/* { dg-error "Builtin function __builtin_vsx_scalar_cmp_exp_dp_lt requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return scalar_cmp_exp_unordered (exponent1, exponent2);
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-1.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+char
+compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  if (scalar_cmp_exp_unordered (exponent1, exponent2))
+    return 't';
+  else
+    return 'f';
+}
+
+/* { dg-final { scan-assembler "xscmpexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+
+int
+compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  return __builtin_vec_scalar_cmp_exp_unordered (exponent1, exponent2);	/* { dg-error "Builtin function __builtin_vsx_scalar_cmp_exp_dp_unordered requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+unsigned int
+get_exponent (double *p)
+{
+  double source = *p;
+
+  return scalar_extract_exp (source);
+}
+
+/* { dg-final { scan-assembler "xsxexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+unsigned int
+get_exponent (double *p)
+{
+  double source = *p;
+
+  return __builtin_vec_scalar_extract_exp (source); /* { dg-error "Builtin function __builtin_vsx_scalar_extract_exp requires" } */
+}
+
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test only runs on 32-bit configurations, where a compiler error
+   should be issued because this builtin is not available on 
+   32-bit configurations.  */
+
+#include <altivec.h>
+
+unsigned int
+get_exponent (double *p)
+{
+  double source = *p;
+
+  return scalar_extract_exp (source);	/* { dg-error "Builtin function __builtin_vec_scalar_extract_exp not supported in this compiler configuration" } */
+}
+
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+unsigned long long int
+get_significand (double *p)
+{
+  double source = *p;
+
+  return scalar_extract_sig (source);
+}
+
+/* { dg-final { scan-assembler "xsxsigdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+unsigned long long int
+get_significand (double *p)
+{
+  double source = *p;
+
+  return __builtin_vec_scalar_extract_sig (source);	/* { dg-error "Builtin function __builtin_vsx_scalar_extract_sig requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c	(working copy)
@@ -0,0 +1,17 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test only runs on 32-bit configurations, producing a compiler
+   error because the builtin requires 64 bits.  */
+#include <altivec.h>
+
+unsigned long long int
+get_significand (double *p)
+{
+  double source = *p;
+
+  return __builtin_vec_scalar_extract_sig (source); /* { dg-error "Builtin function __builtin_vec_scalar_extract_sig not supported in this compiler configuration" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-0.c	(working copy)
@@ -0,0 +1,20 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+double
+insert_exponent (unsigned long long int *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned long long int significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+/* { dg-final { scan-assembler "xsiexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+
+double
+insert_exponent (unsigned long long int *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned long long int significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "Builtin function __builtin_vsx_scalar_insert_exp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test only runs on 32-bit configurations, where a compiler error
+   should be issued because this builtin is not available on 
+   32-bit configurations.  */
+
+#include <altivec.h>
+
+double
+insert_exponent (unsigned long long int *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned long long int significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent); /* { dg-error "Builtin function __builtin_vec_scalar_insert_exp not supported in this compiler configuration" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-0.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (double *p)
+{
+  double source = *p;
+
+  return scalar_test_data_class (source, 3);
+}
+
+/* { dg-final { scan-assembler "xststdcdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (float *p)
+{
+  float source = *p;
+
+  return scalar_test_data_class (source, 3);
+}
+
+/* { dg-final { scan-assembler "xststdcsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (double *p)
+{
+  double source = *p;
+
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (float *p)
+{
+  float source = *p;
+
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (double *p, unsigned int condition_flag)
+{
+  double source = *p;
+
+  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (float *p, unsigned int condition_flag)
+{
+  float source = *p;
+
+  return scalar_test_data_class (source, condition_flag);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (double *p)
+{
+  double source = *p;
+
+  return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "Builtin function __builtin_vsx_scalar_test_data_class_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+unsigned int
+test_data_class (float *p)
+{
+  float source = *p;
+
+  return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "Builtin function __builtin_vsx_scalar_test_data_class_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-0.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_neg (double *p)
+{
+  double source = *p;
+
+  return scalar_test_neg (source);
+}
+
+/* { dg-final { scan-assembler "xststdcdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+unsigned int
+test_neg (float *p)
+{
+  float source = *p;
+
+  return scalar_test_neg (source);
+}
+
+/* { dg-final { scan-assembler "xststdcsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+unsigned int
+test_neg (float *p)
+{
+  float source = *p;
+
+  return __builtin_vec_scalar_test_neg_sp (source); /* { dg-error "Builtin function __builtin_vsx_scalar_test_neg_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+unsigned int
+test_neg (double *p)
+{
+  double source = *p;
+
+  return __builtin_vec_scalar_test_neg_dp (source); /* { dg-error "Builtin function __builtin_vsx_scalar_test_neg_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-0.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector int
+get_exponents (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_extract_exp (source);
+}
+
+/* { dg-final { scan-assembler "xvxexpsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_exponents (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_extract_exp (source);
+}
+
+/* { dg-final { scan-assembler "xvxexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_exponents (__vector double *p)
+{
+  __vector double source = *p;
+
+  return __builtin_vec_extract_exp (source); /* { dg-error "Builtin function __builtin_vsx_extract_exp_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector int
+get_exponents (__vector float *p)
+{
+  __vector float source = *p;
+
+  return __builtin_vec_extract_exp (source);	/* { dg-error "Builtin function __builtin_vsx_extract_exp_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-0.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector int
+get_significands (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_extract_sig (source);
+}
+
+/* { dg-final { scan-assembler "xvxsigsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_significands (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_extract_sig (source);
+}
+
+/* { dg-final { scan-assembler "xvxsigdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_significands (__vector double *p)
+{
+  __vector double source = *p;
+
+  return __builtin_vec_extract_sig (source);	/* { dg-error "Builtin function __builtin_vsx_extract_sig_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector int
+get_significands (__vector float *p)
+{
+  __vector float source = *p;
+
+  return __builtin_vec_extract_sig (source);	/* { dg-error "Builtin function __builtin_vsx_extract_sig_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-0.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector float
+make_floats (__vector unsigned int *significands_p, 
+	     __vector unsigned int *exponents_p)
+{
+  __vector unsigned int significands = *significands_p;
+  __vector unsigned int exponents = *exponents_p;
+
+  return vec_insert_exp (significands, exponents);
+}
+
+/* { dg-final { scan-assembler "xviexpsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-1.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector double
+make_doubles (__vector unsigned long long int *significands_p,
+	      __vector unsigned long long int *exponents_p)
+{
+  __vector unsigned long long int significands = *significands_p;
+  __vector unsigned long long int exponents = *exponents_p;
+
+  return vec_insert_exp (significands, exponents);
+}
+
+/* { dg-final { scan-assembler "xviexpdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector float
+make_floats (__vector unsigned int *significands_p, 
+	     __vector unsigned int *exponents_p)
+{
+  __vector unsigned int significands = *significands_p;
+  __vector unsigned int exponents = *exponents_p;
+
+  return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "Builtin function __builtin_vsx_insert_exp_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector double
+make_doubles (__vector unsigned long long int *significands_p,
+	      __vector unsigned long long int *exponents_p)
+{
+  __vector unsigned long long int significands = *significands_p;
+  __vector unsigned long long int exponents = *exponents_p;
+
+  return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "Builtin function __builtin_vsx_insert_exp_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-0.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector int
+get_data_class_flags (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 0x37);
+}
+
+/* { dg-final { scan-assembler "xvtstdcsp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-1.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_data_class_flags (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 0x37);
+}
+
+/* { dg-final { scan-assembler "xvtstdcdp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_data_class_flags (__vector double *p)
+{
+  __vector double source = *p;
+
+  return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "Builtin function __builtin_vsx_test_data_class_dp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <altivec.h>
+
+__vector int
+get_data_class_flags (__vector float *p)
+{
+  __vector float source = *p;
+
+  return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "Builtin function __builtin_vsx_test_data_class_sp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector int
+get_data_class_flags (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_data_class_flags (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector int
+get_data_class_flags (__vector float *p, unsigned int condition_flag)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+
+__vector long long int
+get_data_class_flags (__vector double *p, unsigned int condition_flag)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+}
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 238014)
+++ gcc/doc/extend.texi	(working copy)
@@ -14867,6 +14867,23 @@  int __builtin_dfp_dtstsfi_ov (unsigned int compari
 int __builtin_dfp_dtstsfi_ov (unsigned int comparison, _Decimal128 value);
 int __builtin_dfp_dtstsfi_ov_dd (unsigned int comparison, _Decimal64 value);
 int __builtin_dfp_dtstsfi_ov_td (unsigned int comparison, _Decimal128 value);
+
+unsigned int scalar_extract_exp (double source);
+unsigned long long int scalar_extract_sig (double source);
+
+double
+scalar_insert_exp (unsigned long long int significand, unsigned long long int exponent);
+
+int scalar_cmp_exp_gt (double arg1, double arg2);
+int scalar_cmp_exp_lt (double arg1, double arg2);
+int scalar_cmp_exp_eq (double arg1, double arg2);
+int scalar_cmp_exp_unordered (double arg1, double arg2);
+
+int scalar_test_data_class (float source, unsigned int condition);
+int scalar_test_data_class (double source, unsigned int condition);
+
+int scalar_test_neg (float source);
+int scalar_test_neg (double source);
 @end smallexample
 
 The @code{__builtin_darn} and @code{__builtin_darn_raw}
@@ -14877,6 +14894,50 @@  random number.  The @code{__builtin_darn_raw} func
 64-bit raw random number.  The @code{__builtin_darn_32} function
 provides a 32-bit random number.
 
+The @code{scalar_extract_sig} and @code{scalar_insert_exp}
+functions require a 64-bit environment supporting ISA 3.0 or later.
+The @code{scalar_extract_exp} and @code{vec_extract_sig} built-in
+functions return the significand and exponent respectively of their
+@code{source} arguments.  The
+@code{scalar_insert_exp} built-in function returns a double-precision
+floating point value that is constructed by assembling the values of its
+@code{significand} and @code{exponent} arguments.  The sign of the
+result is copied from the most significant bit of the
+@code{significand} argument.  The significand and exponent components
+of the result are composed of the least significant 11 bits of the
+@code{significand} argument and the least significant 52 bits of the
+@code{exponent} argument.
+
+The @code{scalar_cmp_exp_gt}, @code{scalar_cmp_exp_lt},
+@code{scalar_cmp_exp_eq}, and @code{scalar_cmp_exp_unordered} built-in
+functions return a non-zero value if @code{arg1} is greater than, less
+than, equal to, or not comparable to @code{arg2} respectively.  The
+arguments are not comparable if one or the other equals NaN (not a
+number). 
+
+The @code{scalar_test_data_class} built-in functions return a non-zero
+value if any of the condition tests enabled by the value of the
+@code{condition} variable are true.  The
+@code{condition} argument must be an unsigned integer with value not
+exceeding 127.  The
+@code{condition} argument is encoded as a bitmask with each bit
+enabling the testing of a different condition, as characterized by the
+following:
+@smallexample
+0x40    Test for NaN
+0x20    Test for +Infinity
+0x10    Test for -Infinity
+0x08    Test for +Zero
+0x04    Test for -Zero
+0x02    Test for +Denormal
+0x01    Test for -Denormal
+@end smallexample
+
+If all of the enabled test conditions are false, the return value is 0.
+
+The @code{scalar_test_neg} built-in functions return a non-zero value
+if their @code{source} argument holds a negative value.
+
 The @code{__builtin_dfp_dtstsfi_lt} function returns a non-zero value
 if and only if the number of signficant digits of its @code{value} argument
 is less than its @code{comparison} argument.  The
@@ -17607,6 +17668,66 @@  differences of the pairs of vector elements suppli
 arguments, placing the absolute differences into the corresponding
 elements of the vector result.
 
+The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 3.0 or later (@option{-mcpu=power9}):
+@smallexample
+__vector int
+vec_extract_exp (__vector float source);
+__vector long long int
+vec_extract_exp (__vector double source);
+
+__vector int
+vec_extract_sig (__vector float source);
+__vector long long int
+vec_extract_sig (__vector double source);
+
+__vector float
+vec_insert_exp (__vector unsigned int significands,  __vector unsigned int exponents);
+__vector double
+vec_insert_exp (__vector unsigned long long int significands,
+                __vector unsigned long long int exponents);
+
+__vector int vec_test_data_class (__vector float source, unsigned int condition);
+__vector long long int vec_test_data_class (__vector double source, unsigned int condition);
+@end smallexample
+
+The @code{vec_extract_sig} and @code{vec_extract_exp} built-in
+functions return vectors representing the significands and exponents
+of their @code{source} arguments respectively.  The
+@code{vec_insert_exp} built-in functions return a vector of single- or
+double-precision floating
+point values constructed by assembling the values of their
+@code{significands} and @code{exponents} arguments into the
+corresponding elements of the returned vector.  The sign of each
+element of the result is copied from the most significant bit of the
+corresponding entry within the @code{significands} argument.  The
+significand and exponent components of each element of the result are
+composed of the least significant bits of the corresponding
+@code{significands} element and the least significant bits of the
+corresponding @code{exponents} element.
+
+The @code{vec_test_data_class} built-in function returns a vector
+representing the results of testing the @code{source} vector for the
+condition selected by the @code{condition} argument.  The
+@code{condition} argument must be an unsigned integer with value not
+exceeding 127.  The
+@code{condition} argument is encoded as a bitmask with each bit
+enabling the testing of a different condition, as characterized by the
+following:
+@smallexample
+0x40    Test for NaN
+0x20    Test for +Infinity
+0x10    Test for -Infinity
+0x08    Test for +Zero
+0x04    Test for -Zero
+0x02    Test for +Denormal
+0x01    Test for -Denormal
+@end smallexample
+
+If any of the enabled test conditions is true, the corresponding entry
+in the result vector is -1.  Otherwise (all of the enabled test
+conditions are false), the corresponding entry of the result vector is 0.
+
 If the cryptographic instructions are enabled (@option{-mcrypto} or
 @option{-mcpu=power8}), the following builtins are enabled.