public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH,rs6000] Add IEEE 128 support for several existing built-in functions
@ 2017-06-21 22:43 Kelvin Nilsen
  2017-06-23 15:59 ` Segher Boessenkool
  0 siblings, 1 reply; 2+ messages in thread
From: Kelvin Nilsen @ 2017-06-21 22:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool


This patch adds IEEE 128 support to the existing scalar_insert_exp,
scalar_extract_exp, scalar_extract_sig, scalar_test_data_class, and
scalar_test_neg rs6000 built-in functions.  Test programs are provided
to exercise the new IEEE 128 functionality and to validate forms of
these built-in functions that do not depend on IEEE 128 support.

The patch has been boostrapped and tested on powerpc64le-unknown-linux
(both P8 and P9 targets) and powerpc-unknown-linux (beg-endian, with
both -m32 and -m64 target options) with no regressions.

Is this ok for the trunk?

gcc/ChangeLog:

2017-06-19  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
	array entries to represent __ieee128 versions of the
	scalar_test_data_class, scalar_test_neg, scalar_extract_exp,
	scalar_extract_sig, and scalar_insert_exp built-in functions.
	(altivec_resolve_overloaded_builtin): Add special case handling
	for the __builtin_scalar_insert_exp function, as represented by
	the P9V_BUILTIN_VEC_VSIEDP constant.
	* config/rs6000/rs6000-builtin.def (VSEEQP): Add scalar	extract
	exponent support for __ieee128 argument.
	(VSESQP): Add scalar extract signature support for __ieee128
	argument.
	(VSTDCNQP): Add scalar test negative support for __ieee128
	argument.
	(VSIEQP): Add scalar insert exponent support for __int128 argument
	with __ieee128 result.
	(VSIEQPF): Add scalar insert exponent support for __ieee128
	argument with __ieee128 result.
	(VSTDCQP): Add scalar test data class support for __ieee128
	argument.
	(VSTDCNQP): Add overload support for scalar test negative with
	__ieee128 argument.
	(VSTDCQP): Add overload support for scalar test data class
	__ieee128 argument.
	* config/rs6000/vsx.md (UNSPEC_VSX_SIEXPQP): New constant.
	(xsxexpqp): New insn for VSX scalar extract exponent quad
	precision.
	(xsxsigqp): New insn for VSX scalar extract significand quad
	precision.
	(xsiexpqpf): New insn for VSX scalar insert exponent quad
	precision with floating point argument.
	(xststdcqp): New expand for VSX scalar test data class quad
	precision.
	(xststdcnegqp): New expand for VSX scalar test negative quad
	precision.
	(xststdcqp): New insn to match expansions for VSX scalar test data
	class quad precision and VSX scalar test negative quad precision.
	* config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
	special case operand checking to enforce that second operand of
	VSX scalar test data class with quad precision argument is a 7-bit
	unsigned literal.
	* doc/extend.texi (PowerPC AltiVec Built-in Functions): Add
	prototypes and descriptions of __ieee128 versions of
	scalar_extract_exp, scalar_extract_sig, scalar_insert_exp,
	scalar_test_data_class, and scalar_test_neg built-in functions.

gcc/testsuite/ChangeLog:

2017-06-19  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target/powerpc/bfp/scalar-cmp-exp-eq-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-eq-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-gt-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-gt-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-lt-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-lt-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-5.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-6.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-exp-7.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-3.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-5.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-6.c: New test.
	* gcc.target/powerpc/bfp/scalar-extract-sig-7.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-10.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-11.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-12.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-13.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-14.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-15.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-6.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-7.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-8.c: New test.
	* gcc.target/powerpc/bfp/scalar-insert-exp-9.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-10.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-11.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-12.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-13.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-14.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-15.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-8.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-data-class-9.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-4.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-5.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-6.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-7.c: New test.
	* gcc.target/powerpc/bfp/scalar-test-neg-8.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-4.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-exp-5.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-4.c: New test.
	* gcc.target/powerpc/bfp/vec-extract-sig-5.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-10.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-11.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-8.c: New test.
	* gcc.target/powerpc/bfp/vec-insert-exp-9.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-8.c: New test.
	* gcc.target/powerpc/bfp/vec-test-data-class-9.c: New test.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 248105)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -14834,7 +14834,8 @@ rs6000_expand_binop_builtin (enum insn_code icode,
 	  return CONST0_RTX (tmode);
 	}
     }
-  else if (icode == CODE_FOR_xststdcdp
+  else if (icode == CODE_FOR_xststdcqp
+	   || icode == CODE_FOR_xststdcdp
 	   || icode == CODE_FOR_xststdcsp
 	   || icode == CODE_FOR_xvtstdcdp
 	   || icode == CODE_FOR_xvtstdcsp)
Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 248105)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -352,6 +352,7 @@
    UNSPEC_VSX_SXEXPDP
    UNSPEC_VSX_SXSIGDP
    UNSPEC_VSX_SIEXPDP
+   UNSPEC_VSX_SIEXPQP
    UNSPEC_VSX_SCMPEXPDP
    UNSPEC_VSX_STSTDC
    UNSPEC_VSX_VXEXP
@@ -3439,6 +3440,15 @@
 \f
 ;; ISA 3.0 Binary Floating-Point Support
 
+;; VSX Scalar Extract Exponent Quad-Precision
+(define_insn "xsxexpqp"
+  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
+	(unspec:DI [(match_operand:KF 1 "altivec_register_operand" "v")]
+	 UNSPEC_VSX_SXEXPDP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsxexpqp %0,%1"
+  [(set_attr "type" "vecmove")])
+
 ;; VSX Scalar Extract Exponent Double-Precision
 (define_insn "xsxexpdp"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3448,6 +3458,15 @@
   "xsxexpdp %0,%x1"
   [(set_attr "type" "integer")])
 
+;; VSX Scalar Extract Significand Quad-Precision
+(define_insn "xsxsigqp"
+  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
+	(unspec:TI [(match_operand:KF 1 "altivec_register_operand" "v")]
+	 UNSPEC_VSX_SXSIGDP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsxsigqp %0,%1"
+  [(set_attr "type" "vecmove")])
+
 ;; VSX Scalar Extract Significand Double-Precision
 (define_insn "xsxsigdp"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3457,6 +3476,26 @@
   "xsxsigdp %0,%x1"
   [(set_attr "type" "integer")])
 
+;; VSX Scalar Insert Exponent Quad-Precision Floating Point Argument
+(define_insn "xsiexpqpf"
+  [(set (match_operand:KF 0 "altivec_register_operand" "=v")
+	(unspec:KF [(match_operand:KF 1 "altivec_register_operand" "v")
+		    (match_operand:DI 2 "altivec_register_operand" "v")]
+	 UNSPEC_VSX_SIEXPQP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsiexpqp %0,%1,%2"
+  [(set_attr "type" "vecmove")])
+
+;; VSX Scalar Insert Exponent Quad-Precision
+(define_insn "xsiexpqp"
+  [(set (match_operand:KF 0 "altivec_register_operand" "=v")
+	(unspec:KF [(match_operand:TI 1 "altivec_register_operand" "v")
+		    (match_operand:DI 2 "altivec_register_operand" "v")]
+	 UNSPEC_VSX_SIEXPQP))]
+  "TARGET_P9_VECTOR && TARGET_64BIT"
+  "xsiexpqp %0,%1,%2"
+  [(set_attr "type" "vecmove")])
+
 ;; VSX Scalar Insert Exponent Double-Precision
 (define_insn "xsiexpdp"
   [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
@@ -3505,6 +3544,27 @@
   "xscmpexpdp %0,%x1,%x2"
   [(set_attr "type" "fpcompare")])
 
+;; VSX Scalar Test Data Class Quad-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 "xststdcqp"
+  [(set (match_dup 3)
+	(compare:CCFP
+	 (unspec:KF
+	  [(match_operand:KF 1 "vsx_register_operand" "v")
+	   (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);
+})
+
 ;; 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.
@@ -3526,8 +3586,25 @@
   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.
+;; The VSX Scalar Test Negative Quad-Precision
+(define_expand "xststdcnegqp"
+  [(set (match_dup 2)
+	(compare:CCFP
+	 (unspec:KF
+	  [(match_operand:KF 1 "altivec_register_operand" "v")
+	   (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);
+})
+
+;; The VSX Scalar Test Negative Double- and Single-Precision
 (define_expand "xststdcneg<Fvsx>"
   [(set (match_dup 2)
 	(compare:CCFP
@@ -3545,6 +3622,17 @@
   operands[3] = CONST0_RTX (SImode);
 })
 
+(define_insn "*xststdcqp"
+  [(set (match_operand:CCFP 0 "" "=y")
+	(compare:CCFP
+	 (unspec:KF [(match_operand:KF 1 "altivec_register_operand" "v")
+		     (match_operand:SI 2 "u7bit_cint_operand" "n")]
+	  UNSPEC_VSX_STSTDC)
+	 (match_operand:SI 3 "zero_constant" "j")))]
+  "TARGET_P9_VECTOR"
+  "xststdcqp %0,%1,%2"
+  [(set_attr "type" "fpcompare")])
+
 (define_insn "*xststdc<Fvsx>"
   [(set (match_operand:CCFP 0 "" "=y")
 	(compare:CCFP
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 248105)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -4649,27 +4649,39 @@ const struct altivec_builtin_types altivec_overloa
     RS6000_BTI_bool_int, RS6000_BTI_float, RS6000_BTI_INTSI, 0 },
   { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCDP,
     RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCQP,
+    RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, RS6000_BTI_INTSI, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCSP, P9V_BUILTIN_VSTDCSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, RS6000_BTI_INTSI, 0 },
   { P9V_BUILTIN_VEC_VSTDCDP, P9V_BUILTIN_VSTDCDP,
     RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 },
+  { P9V_BUILTIN_VEC_VSTDCQP, P9V_BUILTIN_VSTDCQP,
+    RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, RS6000_BTI_INTSI, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 },
   { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNDP,
     RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNQP,
+    RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSTDCNSP, P9V_BUILTIN_VSTDCNSP,
     RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 },
   { P9V_BUILTIN_VEC_VSTDCNDP, P9V_BUILTIN_VSTDCNDP,
     RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 },
+  { P9V_BUILTIN_VEC_VSTDCNQP, P9V_BUILTIN_VSTDCNQP,
+    RS6000_BTI_bool_int, RS6000_BTI_ieee128_float, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEDP,
     RS6000_BTI_UINTSI, RS6000_BTI_double, 0, 0 },
+  { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEQP,
+    RS6000_BTI_UINTDI, RS6000_BTI_ieee128_float, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESDP,
     RS6000_BTI_UINTDI, RS6000_BTI_double, 0, 0 },
+  { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESQP,
+    RS6000_BTI_UINTTI, RS6000_BTI_ieee128_float, 0, 0 },
 
   { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDP,
     RS6000_BTI_double, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 },
@@ -4676,6 +4688,11 @@ const struct altivec_builtin_types altivec_overloa
   { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDPF,
     RS6000_BTI_double, RS6000_BTI_double, RS6000_BTI_UINTDI, 0 },
 
+  { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEQP,
+    RS6000_BTI_ieee128_float, RS6000_BTI_UINTTI, RS6000_BTI_UINTDI, 0 },
+  { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEQPF,
+    RS6000_BTI_ieee128_float, RS6000_BTI_ieee128_float, 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,
@@ -6506,6 +6523,52 @@ altivec_resolve_overloaded_builtin (location_t loc
 	      unsupported_builtin = true;
 	  }
       }
+    else if (fcode == P9V_BUILTIN_VEC_VSIEDP)
+      {
+	int overloaded_code;
+	int arg1_mode = TYPE_MODE (types[0]);
+
+	if (nargs != 2)
+	  {
+	    error ("scalar_insert_exp only accepts 2 arguments");
+	    return error_mark_node;
+	  }
+
+	/* If supplied first argument is wider than 64 bits, resolve to
+	   128-bit variant of built-in function.  */
+	if (GET_MODE_PRECISION (arg1_mode) > 64)
+	  {
+	    /* if first argument is of float variety, choose variant
+	       that expects __ieee128 argument.  Otherwise, expect
+	       __int128 argument.  */
+	    if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
+	      overloaded_code = P9V_BUILTIN_VSIEQPF;
+	    else
+	      overloaded_code = P9V_BUILTIN_VSIEQP;
+	  }
+	else
+	  {
+	    /* if first argument is of float variety, choose variant
+	       that expects double argument.  Otherwise, expect
+	       long long int argument.  */
+	    if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
+	      overloaded_code = P9V_BUILTIN_VSIEDPF;
+	    else
+	      overloaded_code = P9V_BUILTIN_VSIEDP;
+	  }
+	while (desc->code && desc->code == fcode &&
+	       desc->overloaded_code != overloaded_code)
+	  desc++;
+	if (desc->code && (desc->code == fcode)
+	    && rs6000_builtin_type_compatible (types[0], desc->op1)
+	    && rs6000_builtin_type_compatible (types[1], desc->op2))
+	  {
+	    if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE)
+	      return altivec_build_resolved_builtin (args, n, desc);
+	    else
+	      unsupported_builtin = true;
+	  }
+      }
     else
       {
 	/* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 248105)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -2000,6 +2000,10 @@ BU_P9V_OVERLOAD_3 (RLMI,	"rlmi")
 BU_P9V_64BIT_VSX_1 (VSEEDP,	"scalar_extract_exp",	CONST,	xsxexpdp)
 BU_P9V_64BIT_VSX_1 (VSESDP,	"scalar_extract_sig",	CONST,	xsxsigdp)
 
+BU_P9V_64BIT_VSX_1 (VSEEQP,	"scalar_extract_expq",	CONST,	xsxexpqp)
+BU_P9V_64BIT_VSX_1 (VSESQP,	"scalar_extract_sigq",	CONST,	xsxsigqp)
+
+BU_P9V_VSX_1 (VSTDCNQP,	"scalar_test_neg_qp",	CONST,	xststdcnegqp)
 BU_P9V_VSX_1 (VSTDCNDP,	"scalar_test_neg_dp",	CONST,	xststdcnegdp)
 BU_P9V_VSX_1 (VSTDCNSP,	"scalar_test_neg_sp",	CONST,	xststdcnegsp)
 
@@ -2015,11 +2019,15 @@ BU_P9V_VSX_1 (XXBRH_V8HI,	"xxbrh_v8hi",	CONST,	p9_
 BU_P9V_64BIT_VSX_2 (VSIEDP,	"scalar_insert_exp",	CONST,	xsiexpdp)
 BU_P9V_64BIT_VSX_2 (VSIEDPF,	"scalar_insert_exp_dp",	CONST,	xsiexpdpf)
 
+BU_P9V_64BIT_VSX_2 (VSIEQP,	"scalar_insert_exp_q",	CONST,	xsiexpqp)
+BU_P9V_64BIT_VSX_2 (VSIEQPF,	"scalar_insert_exp_qp",	CONST,	xsiexpqpf)
+
 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 (VSTDCQP,	"scalar_test_data_class_qp",	CONST,	xststdcqp)
 BU_P9V_VSX_2 (VSTDCDP,	"scalar_test_data_class_dp",	CONST,	xststdcdp)
 BU_P9V_VSX_2 (VSTDCSP,	"scalar_test_data_class_sp",	CONST,	xststdcsp)
 
@@ -2028,6 +2036,7 @@ 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 (VSTDCNQP,	"scalar_test_neg_qp")
 BU_P9V_OVERLOAD_1 (VSTDCNDP,	"scalar_test_neg_dp")
 BU_P9V_OVERLOAD_1 (VSTDCNSP,	"scalar_test_neg_sp")
 
@@ -2037,6 +2046,7 @@ BU_P9V_OVERLOAD_1 (REVB,	"revb")
 BU_P9V_OVERLOAD_2 (VSIEDP,	"scalar_insert_exp")
 
 BU_P9V_OVERLOAD_2 (VSTDC,	"scalar_test_data_class")
+BU_P9V_OVERLOAD_2 (VSTDCQP,	"scalar_test_data_class_qp")
 BU_P9V_OVERLOAD_2 (VSTDCDP,	"scalar_test_data_class_dp")
 BU_P9V_OVERLOAD_2 (VSTDCSP,	"scalar_test_data_class_sp")
 
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-3.c	(revision 249075)
@@ -0,0 +1,32 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (!compare_exponents_eq (&x, &y))
+    abort ();
+  if (compare_exponents_eq (&x, &z))
+    abort ();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-4.c	(revision 249075)
@@ -0,0 +1,34 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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';
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_eq (&x, &y) == 'f')
+    abort ();
+  if (compare_exponents_eq (&x, &z) == 't')
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-3.c	(revision 249075)
@@ -0,0 +1,31 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_gt (&x, &y))
+    abort ();
+  if (!compare_exponents_gt (&x, &z))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-4.c	(revision 249075)
@@ -0,0 +1,34 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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';
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_gt (&x, &y) == 't')
+    abort ();
+  if (compare_exponents_gt (&x, &z) == 'f')
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-3.c	(revision 249075)
@@ -0,0 +1,31 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_lt (&x, &y))
+    abort ();
+  if (!compare_exponents_lt (&z, &x))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-4.c	(revision 249075)
@@ -0,0 +1,34 @@
+/* { dg-do run  { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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';
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_lt (&x, &y) == 't')
+    abort ();
+  if (compare_exponents_lt (&z, &x) == 'f')
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-3.c	(revision 249175)
@@ -0,0 +1,36 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+int
+compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  /* This test succeeds if either exponent1 or exponent2 is NaN. */
+  return scalar_cmp_exp_unordered (exponent1, exponent2);
+}
+
+int
+main ()
+{
+  /* NaN is denoted by exponent = 2047 and fraction != 0 */
+  unsigned long long int nan_image = 0x7ff0000000000003LL;
+  double *nan_ptr = (double *) &nan_image;
+
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (!compare_exponents_unordered (&x, nan_ptr))
+    abort ();
+  if (compare_exponents_unordered (&x, &z))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-4.c	(revision 249175)
@@ -0,0 +1,39 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on 32-bit and 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+char
+compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
+{
+  double exponent1 = *exponent1_p;
+  double exponent2 = *exponent2_p;
+
+  /* This test succeeds if either exponent1 or exponent2 is NaN. */
+  if (scalar_cmp_exp_unordered (exponent1, exponent2))
+    return 't';
+  else
+    return 'f';
+}
+
+int
+main ()
+{
+  /* NaN is denoted by exponent = 2047 and fraction != 0 */
+  unsigned long long int nan_image = 0x7ff0000000000003LL;
+  double *nan_ptr = (double *) &nan_image;
+
+  double x = (double) (0x1100LL << 50);
+  double y = (double) (0x1101LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (compare_exponents_unordered (&x, nan_ptr) == 'f')
+    abort ();
+  if (compare_exponents_unordered (&x, &z) == 't')
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-3.c	(revision 248801)
@@ -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_exponent (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_extract_exp (source);
+}
+
+/* { dg-final { scan-assembler "xsxexpqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c	(revision 249075)
@@ -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 long long int
+get_exponent (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return __builtin_vec_scalar_extract_exp (source); /* { dg-error "Builtin function __builtin_vsx_scalar_extract_expq requires" } */
+}
+
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-5.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 long long int
+get_exponent (__ieee128 *p)
+{
+  __ieee128 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-exp-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-6.c	(revision 249312)
@@ -0,0 +1,30 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+unsigned int
+get_unbiased_exponent (double *p)
+{
+  double source = *p;
+
+  return scalar_extract_exp (source) - 1023;
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (get_unbiased_exponent (&x) != 62)
+    abort ();
+  if (get_unbiased_exponent (&z) != 49)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-7.c	(revision 249175)
@@ -0,0 +1,30 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+unsigned long long int
+get_unbiased_exponent (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_extract_exp (source) - 16383;
+}
+
+int
+main ()
+{
+  __ieee128 x = (__ieee128) (((__int128) 0x1100LL) << 114);
+  __ieee128 z = (__ieee128) (((__int128) 0x1101LL) << 112);
+
+  if (get_unbiased_exponent (&x) != 126)
+    abort ();
+  if (get_unbiased_exponent (&z) != 124)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-3.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-3.c	(revision 248801)
@@ -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 __int128
+get_significand (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_extract_sig (source);
+}
+
+/* { dg-final { scan-assembler "xsxsigqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c	(revision 249075)
@@ -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 __int128
+get_significand (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return __builtin_vec_scalar_extract_sig (source);	/* { dg-error "Builtin function __builtin_vsx_scalar_extract_sigq requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-5.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 __int128 /* { dg-error "'__int128' is not supported on this target" } */
+get_significand (__ieee128 *p)
+{
+  __ieee128 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-extract-sig-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-6.c	(revision 249175)
@@ -0,0 +1,30 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+unsigned long long int
+get_significand (double *p)
+{
+  double source = *p;
+
+  return scalar_extract_sig (source);
+}
+
+int
+main ()
+{
+  double x = (double) (0x1100LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (get_significand (&x) != 0x11000000000000ULL)
+    abort ();
+  if (get_significand (&z) != 0x11010000000000ULL)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-7.c	(revision 249175)
@@ -0,0 +1,36 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+unsigned __int128
+get_significand (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_extract_sig (source);
+}
+
+int
+main ()
+{
+  __ieee128 x = (__ieee128) (((__int128) 0x1100LL) << 114);
+  __ieee128 z = (__ieee128) (((__int128) 0x1101LL) << 112);
+
+  /* 113 bits in the significand */
+  /* our constant mantissas have 13 bits */
+
+  unsigned __int128 first_anticipated_result = ((__int128) 0x1100LL) << 100;
+  unsigned __int128 second_anticipated_result = ((__int128) 0x1101LL) << 100;
+
+  if (get_significand (&x) != first_anticipated_result)
+    abort ();
+  if (get_significand (&z) != second_anticipated_result)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c	(revision 248801)
@@ -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>
+
+__ieee128
+insert_exponent (__ieee128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  __ieee128 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_qp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-11.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-11.c	(revision 248801)
@@ -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>
+
+__ieee128
+insert_exponent (__ieee128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  __ieee128 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-insert-exp-12.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-12.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-12.c	(revision 249175)
@@ -0,0 +1,40 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+#define BIAS_FOR_DOUBLE_EXP 1023
+
+int
+main ()
+{
+  unsigned long long int significand_1 = 0x18000000000000LL;
+  unsigned long long int significand_2 = 0x1a000000000000LL;
+  unsigned long long int exponent_1 = 62 + BIAS_FOR_DOUBLE_EXP;
+  unsigned long long int exponent_2 = 49 + BIAS_FOR_DOUBLE_EXP;
+
+  double x = (double) (0x1800ULL << 50);
+  double z = (double) (0x1a00ULL << 37);
+
+
+  if (insert_exponent (&significand_1, &exponent_1) != x)
+    abort ();
+  if (insert_exponent (&significand_2, &exponent_2) != z)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-13.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-13.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-13.c	(revision 249312)
@@ -0,0 +1,43 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+double
+insert_exponent (double *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  double significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+#define BIAS_FOR_DOUBLE_EXP 1023
+
+int
+main ()
+{
+  unsigned long long int significand_1 = 0x11000000000000LL;
+  unsigned long long int significand_2 = 0x11010000000000LL;
+  unsigned long long int exponent_1 = 62 + BIAS_FOR_DOUBLE_EXP;
+  unsigned long long int exponent_2 = 49 + BIAS_FOR_DOUBLE_EXP;
+
+  double *significand_1_ptr = (double *) &significand_1;
+  double *significand_2_ptr = (double *) &significand_2;
+
+
+  double x = (double) (0x1100LL << 50);
+  double z = (double) (0x1101LL << 37);
+
+  if (insert_exponent (significand_1_ptr, &exponent_1) != x)
+    abort ();
+  if (insert_exponent (significand_2_ptr, &exponent_2) != z)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-14.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-14.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-14.c	(revision 249312)
@@ -0,0 +1,40 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+__ieee128
+insert_exponent (unsigned __int128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned __int128 significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+#define BIAS_FOR_QUAD_EXP 16383
+
+int
+main ()
+{
+  /* most-significant bit @13, shift it to position 113 */
+  unsigned __int128 significand_1 = ((__int128) 0x1100) << 100;
+  unsigned __int128 significand_2 = ((__int128) 0x1101) << 100;
+  unsigned long long int exponent_1 = 126 + BIAS_FOR_QUAD_EXP;
+  unsigned long long int exponent_2 = 124 + BIAS_FOR_QUAD_EXP;
+
+  __ieee128 x = (__ieee128) (((__int128) 0x1100LL) << 114);
+  __ieee128 z = (__ieee128) (((__int128) 0x1101LL) << 112);
+
+  if (insert_exponent (&significand_1, &exponent_1) != x)
+    abort ();
+  if (insert_exponent (&significand_2, &exponent_2) != z)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-15.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-15.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-15.c	(revision 249312)
@@ -0,0 +1,43 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed only on 64-bit configurations.  */
+#include <altivec.h>
+#include <stdlib.h>
+
+__ieee128
+insert_exponent (__ieee128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  __ieee128 significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+#define BIAS_FOR_QUAD_EXP 16383
+
+int
+main ()
+{
+  /* most-significant bit @13, shift it to position 113 */
+  unsigned __int128 significand_1 = ((unsigned __int128) 0x1100) << 100;
+  unsigned __int128 significand_2 = ((unsigned __int128) 0x1101) << 100;
+  unsigned long long int exponent_1 = 126 + BIAS_FOR_QUAD_EXP;
+  unsigned long long int exponent_2 = 124 + BIAS_FOR_QUAD_EXP;
+
+  __ieee128 *significand_1_ptr = (__ieee128 *) &significand_1;
+  __ieee128 *significand_2_ptr = (__ieee128 *) &significand_2;
+
+  __ieee128 x = (__ieee128) (((__int128) 0x1100LL) << 114);
+  __ieee128 z = (__ieee128) (((__int128) 0x1101LL) << 112);
+
+  if (insert_exponent (significand_1_ptr, &exponent_1) != x)
+    abort ();
+  if (insert_exponent (significand_2_ptr, &exponent_2) != z)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-6.c	(revision 248801)
@@ -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>
+
+__ieee128
+insert_exponent (unsigned __int128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned __int128 significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+/* { dg-final { scan-assembler "xsiexpqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c	(revision 248801)
@@ -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>
+
+__ieee128
+insert_exponent (unsigned __int128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  unsigned __int128 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_q requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.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>
+
+__ieee128
+insert_exponent (unsigned __int128 *significand_p, /* { dg-error "'__int128' is not supported on this target" } */
+		 unsigned long long int *exponent_p)
+{
+  unsigned __int128 significand = *significand_p;  /* { dg-error "'__int128' is not supported on this target" } */
+  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-insert-exp-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-9.c	(revision 248801)
@@ -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>
+
+__ieee128
+insert_exponent (__ieee128 *significand_p,
+		 unsigned long long int *exponent_p)
+{
+  __ieee128 significand = *significand_p;
+  unsigned long long int exponent = *exponent_p;
+
+  return scalar_insert_exp (significand, exponent);
+}
+
+/* { dg-final { scan-assembler "xsiexpqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c	(revision 248801)
@@ -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>
+#include <stdbool.h>
+
+bool
+test_data_class (__ieee128 *p, const int condition_flag)
+{
+  __ieee128 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-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c	(revision 249075)
@@ -0,0 +1,15 @@
+/* { 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>
+#include <stdbool.h>
+
+bool
+test_data_class (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "Builtin function __builtin_vsx_scalar_test_data_class_qp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-12.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-12.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-12.c	(working copy)
@@ -0,0 +1,44 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_denormal (double *p)
+{
+  double source = *p;
+
+  /*
+    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
+  */
+  return scalar_test_data_class (source, 3);
+}
+
+int
+main ()
+{
+  /* A Denormal number has a biased exponent value of zero and a
+   *   non-zero fraction value.  */
+  double denormal_plus = scalar_insert_exp (0x0008000000000000ULL, 0x0ULL);
+  double denormal_minus = scalar_insert_exp (0x8008000000000000ULL, 0x0ULL);
+  double not_denormal = scalar_insert_exp (0x8000000000000000ULL, 1023ULL);
+
+  if (!test_denormal (&denormal_plus))
+    abort ();
+  if (!test_denormal (&denormal_minus))
+    abort ();
+  if (test_denormal (&not_denormal))
+    abort ();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-13.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-13.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-13.c	(revision 249312)
@@ -0,0 +1,47 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_zero (float *p)
+{
+  float source = *p;
+
+  /*
+    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
+  */
+  return scalar_test_data_class (source, 12);
+}
+
+int
+main ()
+{
+  /* A Zero value has a biased exponent value of zero and a zero
+   * fraction value.  The sign may be either positive or negative.  */
+  unsigned int zero_plus_image = 0x0;
+  unsigned int zero_minus_image = 0x80000000;
+  unsigned int non_zero_image = 0x60000000;
+
+  float *zero_plus_p = (float *) &zero_plus_image;
+  float *zero_minus_p = (float *) &zero_minus_image;
+  float *not_zero_p = (float *) &non_zero_image;
+
+  if (!test_zero (zero_plus_p))
+    abort ();
+  if (!test_zero (zero_minus_p))
+    abort ();
+  if (test_zero (not_zero_p))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-14.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-14.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-14.c	(revision 249312)
@@ -0,0 +1,54 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_nan (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  /*
+    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
+  */
+  return scalar_test_data_class (source, 0x40);
+}
+
+int
+main ()
+{
+  /* NaN is represented with the maximum biased exponent value and a
+   *  non-zero fraction value. The sign bit ignored.  If the
+   *  high-order bit of the fraction field is 0, then the NaN is a
+   *  Signaling NaN.  Otherwise, it is a Quiet NaN.  */
+  __int128 signal_significand = (__int128) 0xffffffff;
+  __int128 quiet_significand = (((__int128) 0x1) << 112) | 0xffffffff;
+  __int128 a_number_significand = (((__int128) 0x1) << 112);
+  unsigned long long int nan_exponent = 0x7fff;
+  unsigned long long int a_number_exponent = 16383;
+
+  __ieee128 signaling_nan =
+    scalar_insert_exp (signal_significand, nan_exponent);
+  __ieee128 quiet_nan =
+    scalar_insert_exp (quiet_significand, nan_exponent);
+  __ieee128 a_number =
+    scalar_insert_exp (a_number_significand, a_number_exponent);
+
+  if (!test_nan (&signaling_nan))
+    abort ();
+  if (!test_nan (&quiet_nan))
+    abort ();
+  if (test_nan (&a_number))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-15.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-15.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-15.c	(working copy)
@@ -0,0 +1,56 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_infinity (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  /*
+    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
+  */
+  return scalar_test_data_class (source, 0x30);
+}
+
+int
+main ()
+{
+  /* Infinity is represented by a biased exponent value of:
+   *   255 in single format
+   *   2047 in double format
+   *   32767 in ieee128 format
+   * and a zero fraction value.  */
+  __int128 plus_significand = (__int128) 0;
+  __int128 minus_significand = ((__int128) 0x1) << 127;
+  __int128 a_number_significand = (((__int128) 0x1) << 112);
+
+  unsigned long long int infinite_exponent = 0x7fff;
+  unsigned long long int a_number_exponent = 16383;
+
+  __ieee128 plus_infinity =
+    scalar_insert_exp (plus_significand, infinite_exponent);
+  __ieee128 minus_infinity =
+    scalar_insert_exp (minus_significand, infinite_exponent);
+  __ieee128 a_number =
+    scalar_insert_exp (a_number_significand, a_number_exponent);
+
+  if (!test_infinity (&plus_infinity))
+    abort ();
+  if (!test_infinity (&minus_infinity))
+    abort ();
+  if (test_infinity (&a_number))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-8.c	(revision 248801)
@@ -0,0 +1,17 @@
+/* { 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>
+#include <stdbool.h>
+
+bool
+test_data_class (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_test_data_class (source, 3);
+}
+
+/* { dg-final { scan-assembler "xststdcqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c	(revision 248801)
@@ -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>
+#include <stdbool.h>
+
+bool
+test_data_class (__ieee128 *p)
+{
+  __ieee128 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-neg-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-4.c	(revision 248801)
@@ -0,0 +1,17 @@
+/* { 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>
+#include <stdbool.h>
+
+bool
+test_neg (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_test_neg (source);
+}
+
+/* { dg-final { scan-assembler "xststdcqp" } } */
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c	(revision 248801)
@@ -0,0 +1,15 @@
+/* { 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>
+#include <stdbool.h>
+
+bool
+test_neg (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return __builtin_vec_scalar_test_neg_qp (source); /* { dg-error "Builtin function __builtin_vsx_scalar_test_neg_qp requires" } */
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-6.c	(revision 249075)
@@ -0,0 +1,30 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_neg (double *p)
+{
+  double source = *p;
+
+  return scalar_test_neg (source);
+}
+
+int
+main ()
+{
+  double neg_number = (double) -1;
+  double plus_number = (double) 1;
+
+  if (!test_neg (&neg_number))
+    abort ();
+  if (test_neg (&plus_number))
+    abort ();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-7.c	(revision 249075)
@@ -0,0 +1,29 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_neg (float *p)
+{
+  float source = *p;
+
+  return scalar_test_neg (source);
+}
+
+int
+main ()
+{
+  float neg_number = (float) -1;
+  float plus_number = (float) 1;
+
+  if (!test_neg (&neg_number))
+    abort ();
+  if (test_neg (&plus_number))
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-8.c	(revision 249075)
@@ -0,0 +1,30 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+bool
+test_neg (__ieee128 *p)
+{
+  __ieee128 source = *p;
+
+  return scalar_test_neg (source);
+}
+
+int
+main ()
+{
+  __ieee128 neg_number = (__ieee128) -1;
+  __ieee128 plus_number = (__ieee128) 1;
+
+  if (!test_neg (&neg_number))
+    abort ();
+  if (test_neg (&plus_number))
+    abort ();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-4.c	(revision 249175)
@@ -0,0 +1,39 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector unsigned int
+get_exponents (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_extract_exp (source);
+}
+
+unsigned int bias_float_exp (int unbiased_exp)
+{
+  return (unsigned int) (unbiased_exp + 127);
+}
+
+int
+main ()
+{
+  __vector float argument;
+  __vector unsigned int result;
+
+  argument[0] = (float) (0x1 << 10);
+  argument[1] = (float) (0x1 << 9);
+  argument[2] = (float) (0x1 << 8);
+  argument[3] = (float) (0x1 << 7);
+
+  result = get_exponents (&argument);
+  if ((result[0] != bias_float_exp (10)) ||
+      (result[1] != bias_float_exp (9)) ||
+      (result[2] != bias_float_exp (8)) || (result[3] != bias_float_exp (7)))
+    abort();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-5.c	(working copy)
@@ -0,0 +1,37 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector unsigned long long int
+get_exponents (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_extract_exp (source);
+}
+
+unsigned long long int
+bias_double_exp (long long int unbiased_exp)
+{
+  return (unsigned long long int) (unbiased_exp + 1023);
+}
+
+int
+main ()
+{
+  __vector double argument;
+  __vector unsigned long long int result;
+
+  argument[0] = (double) (0x1 << 22);
+  argument[1] = (double) (0x1 << 23);
+
+  result = get_exponents (&argument);
+  if ((result[0] != bias_double_exp (22)) ||
+      (result[1] != bias_double_exp (23)))
+    abort();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-4.c	(revision 249175)
@@ -0,0 +1,33 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector unsigned int
+get_significands (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_extract_sig (source);
+}
+
+int
+main ()
+{
+  __vector float argument;
+  __vector unsigned int result;
+
+  argument[0] = (float) (0x1234 << 10);
+  argument[1] = (float) (0x4321 << 9);
+  argument[2] = (float) (0xbabe << 8);
+  argument[3] = (float) (0xcafe << 7);
+
+  result = get_significands (&argument);
+  if ((result[0] != 0x91a000) || (result[1] != 0x864200) ||
+      (result[2] != 0xbabe00) || (result[3] != 0xcafe00))
+    abort();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-5.c	(revision 249175)
@@ -0,0 +1,31 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector unsigned long long int
+get_significands (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_extract_sig (source);
+}
+
+int
+main ()
+{
+  __vector double argument;
+  __vector unsigned long long int result;
+
+  argument[0] = (double) (0xbabeLL << 22);
+  argument[1] = (double) (0xcafeLL << 23);
+
+  result = get_significands (&argument);
+  if ((result[0] != (0xbabeULL << 37)) || (result[1] != (0xcafeULL << 37)))
+    abort();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-10.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-10.c	(revision 249312)
@@ -0,0 +1,44 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector float
+make_floats (__vector float *significands_p, 
+	     __vector unsigned int *exponents_p)
+{
+  __vector float significands = *significands_p;
+  __vector unsigned int exponents = *exponents_p;
+
+  return vec_insert_exp (significands, exponents);
+}
+
+int
+main ()
+{
+  __vector unsigned int significands;
+  __vector float *significands_p = (__vector float *) &significands;
+  __vector unsigned int exponents;
+  __vector float result;
+
+  /* 24 bits in significand, plus the sign bit: 0x80ffffff */
+  significands[0] = 0x00800000;	/*  1.0 */
+  significands[1] = 0x00c00000;	/*  1.5 */
+  significands[2] = 0x80e00000;	/* -1.75 */
+  significands[3] = 0x80c00000;	/* -1.5 */
+
+  exponents[0] = 127;		/*  exp = 0: 1.0 */
+  exponents[1] = 128;		/*  exp = 1: 3.0 */
+  exponents[2] = 129;		/*  exp = 2: -7.0 */
+  exponents[3] = 125;		/* exp = -2: -0.375 */
+
+  result = make_floats (significands_p, &exponents);
+  if ((result[0] != 1.0f) ||
+      (result[1] != 3.0f) || (result[2] != -7.0f) || (result[3] != -0.375f))
+    abort();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-11.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-11.c	(revision 249312)
@@ -0,0 +1,39 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+__vector double
+make_doubles (__vector double *significands_p,
+	      __vector unsigned long long int *exponents_p)
+{
+  __vector double significands = *significands_p;
+  __vector unsigned long long int exponents = *exponents_p;
+
+  return vec_insert_exp (significands, exponents);
+}
+
+int
+main ()
+{
+  __vector unsigned long long int significands;
+  __vector double *significands_p = (__vector double *) &significands;
+  __vector unsigned long long int exponents;
+  __vector double result;
+
+  /* 53 bits in significand, plus the sign bit: 0x8000_0000_0000_0000 */
+  significands[0] = 0x0010000000000000;	/*  1.0 */
+  significands[1] = 0x801c000000000000;	/* -1.75 */
+
+  exponents[0] = 1023;		/*  exp = 0: 1.0 */
+  exponents[1] = 1021;		/* exp = -2: -0.4375 (7/16) */
+
+  result = make_doubles (significands_p, &exponents);
+  if ((result[0] != 1.0) || (result[1] != -0.4375))
+    abort();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-8.c	(revision 249312)
@@ -0,0 +1,43 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+int
+main ()
+{
+  __vector unsigned int significands;
+  __vector unsigned int exponents;
+  __vector float result;
+
+  /* 24 bits in significand, plus the sign bit: 0x80ffffff */
+  significands[0] = 0x00800000;	/* 1.0 */
+  significands[1] = 0x00c00000;	/* 1.5 */
+  significands[2] = 0x80e00000;	/* -1.75 */
+  significands[3] = 0x80c00000;	/* -1.5 */
+
+  exponents[0] = 127;		/*  exp = 0: 1.0 */
+  exponents[1] = 128;		/*  exp = 1: 3.0.0 */
+  exponents[2] = 129;		/*  exp = 2: -7.0 */
+  exponents[3] = 125;		/* exp = -2: -0.375 */
+
+  result = make_floats (&significands, &exponents);
+  if ((result[0] != 1.0f) ||
+      (result[1] != 3.0f) || (result[2] != -7.0f) || (result[3] != -0.375f))
+    abort();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-9.c	(revision 249312)
@@ -0,0 +1,38 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.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);
+}
+
+int
+main ()
+{
+  __vector unsigned long long int significands;
+  __vector unsigned long long int exponents;
+  __vector double result;
+
+  /* 53 bits in significand, plus the sign bit: 0x8000_0000_0000_0000 */
+  significands[0] = 0x0010000000000000;	/*  1.0 */
+  significands[1] = 0x801c000000000000;	/* -1.75 */
+
+  exponents[0] = 1023;		/*  exp = 0: 1.0 */
+  exponents[1] = 1021;		/* exp = -2: -0.4375 (7/16) */
+
+  result = make_doubles (&significands, &exponents);
+  if ((result[0] != 1.0) || (result[1] != -0.4375))
+    abort();
+  return 0;
+}
+
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-8.c	(revision 249312)
@@ -0,0 +1,112 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+/* Flags to select tests:
+    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  */
+
+__vector bool int
+test_nan (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 0x40);
+}
+
+__vector bool int
+test_infinity (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 0x30);
+}
+
+__vector bool int
+test_zero (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 0x0c);
+}
+
+__vector bool int
+test_denormal (__vector float *p)
+{
+  __vector float source = *p;
+
+  return vec_test_data_class (source, 0x03);
+}
+
+float 
+float_scalar_insert_exp (unsigned int significand, unsigned int exponent)
+{
+  float result;
+  unsigned int *result_as_uip = (unsigned int *) &result;
+
+  *result_as_uip = (significand & ~0x800000) | ((exponent & 0xff) << 23);
+  return result;
+}
+
+int
+main ()
+{
+  __vector float argument;
+  __vector bool result;
+
+  unsigned int signaling_significand = 0x00a00000;
+  unsigned int quiet_significand = 0x00c00000;
+  unsigned int one_significand = 0x00800000;
+  unsigned int three_significand = 0x00c00000;
+  unsigned int five_significand = 0x00a00000;
+  unsigned int zero_significand = 0x00000000;
+  unsigned int minus_zero_significand = 0x80000000;
+
+  /* A NaN is represented with the maximum biased exponent value and a
+   *  non-zero fraction value. The sign bit ignored.  If the
+   *  high-order bit of the fraction field is 0, then the NaN
+   *  is a Signaling NaN.  Otherwise, it is a Quiet NaN.  */
+  argument[0] = float_scalar_insert_exp (signaling_significand, 255);
+  argument[1] = float_scalar_insert_exp (quiet_significand, 255);
+  argument[2] = 1.0f;
+  argument[3] = -0.07f;
+  result = test_nan (&argument);
+  if (!result[0] || !result[1] || result[2] || result[3])
+    abort ();
+
+  /* Infinity is represented by a biased exponent value of:
+   *   255 in single format
+   *   2047 in double format
+   * and a zero fraction value.  The difference between +infinity and
+   * -infinity is the value of the sign bit.  */
+  argument[2] = float_scalar_insert_exp (zero_significand, 255);
+  argument[3] = float_scalar_insert_exp (minus_zero_significand, 255);
+  result = test_infinity (&argument);
+  if (result[0] || result[1] || !result[2] || !result[3])
+    abort ();
+
+  /* A Zero value has a biased exponent value of zero and a zero
+   *   fraction value.  The sign may be either positive or negative.  */
+  argument[1] = float_scalar_insert_exp (minus_zero_significand, 0);
+  argument[2] = float_scalar_insert_exp (zero_significand, 0);
+  result = test_zero (&argument);
+  if (result[0] || !result[1] || !result[2] || result[3])
+    abort ();
+
+  /* A Denormal number has a biased exponent value of zero and a
+   *   non-zero fraction value.  */
+  argument[0] = float_scalar_insert_exp (five_significand, 0);
+  argument[3] = float_scalar_insert_exp (three_significand, 0);
+  result = test_denormal (&argument);
+  if (!result[0] || result[1] || result[2] || !result[3])
+    abort ();
+}
Index: gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-9.c	(revision 249312)
@@ -0,0 +1,125 @@
+/* { dg-do run { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mcpu=power9" } */
+
+#include <altivec.h>
+#include <stdlib.h>
+
+/* Flags to select tests:
+    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  */
+
+__vector bool long long int
+test_nan (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 0x40);
+}
+
+__vector bool long long int
+test_infinity (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 0x30);
+}
+
+__vector bool long long int
+test_zero (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 0x0c);
+}
+
+__vector bool long long int
+test_denormal (__vector double *p)
+{
+  __vector double source = *p;
+
+  return vec_test_data_class (source, 0x03);
+}
+
+int
+main ()
+{
+  __vector double special_argument;
+  __vector double nonspecial_argument;
+  __vector bool long long int result;
+
+  unsigned long long int signaling_significand =
+    0x0017000000000000ULL;
+  unsigned long long int quiet_significand =
+    0x001f000000000000ULL;
+  unsigned long long int one_significand =
+    0x0010000000000000ULL;
+  unsigned long long int three_significand =
+    0x0018000000000000ULL;
+  unsigned long long int five_significand =
+    0x0014000000000000ULL;
+  unsigned long long int zero_significand =
+    0x0000000000000000ULL;
+  unsigned long long int minus_zero_significand =
+    0x8000000000000000ULL;
+
+  nonspecial_argument[0] = -3.825;
+  nonspecial_argument[1] = 3.14159;
+
+  /* A NaN is represented with the maximum biased exponent value and a
+   *  non-zero fraction value. The sign bit ignored.  If the
+   *  high-order bit of the fraction field is 0, then the NaN
+   *  is a Signaling NaN.  Otherwise, it is a Quiet NaN.  */
+  special_argument[0] = scalar_insert_exp (signaling_significand, 2047);
+  special_argument[1] = scalar_insert_exp (quiet_significand, 2047);
+  result = test_nan (&special_argument);
+  if (!result[0] || !result[1])
+    abort ();
+  result = test_nan (&nonspecial_argument);
+  if (result[0] || result[1])
+    abort ();
+
+  /* Infinity is represented by a biased exponent value of:
+   *   255 in single format
+   *   2047 in double format
+   * and a zero fraction value.  The difference between +infinity and
+   * -infinity is the value of the sign bit.  */
+  special_argument[0] = scalar_insert_exp (zero_significand, 2047);
+  special_argument[1] = scalar_insert_exp (minus_zero_significand, 2047);
+  result = test_infinity (&special_argument);
+  if (!result[0] || !result[1])
+    abort ();
+  result = test_infinity (&nonspecial_argument);
+  if (result[0] || result[1])
+    abort ();
+
+  /* A Zero value has a biased exponent value of zero and a zero
+   *   fraction value.  The sign may be either positive or negative.  */
+  special_argument[0] = scalar_insert_exp (minus_zero_significand, 0);
+  special_argument[1] = scalar_insert_exp (zero_significand, 0);
+  result = test_zero (&special_argument);
+  if (!result[0] || !result[1])
+    abort ();
+  result = test_zero (&nonspecial_argument);
+  if (result[0] || result[1])
+    abort ();
+
+  /* A Denormal number has a biased exponent value of zero and a
+   *   non-zero fraction value.  */
+  special_argument[0] = scalar_insert_exp (five_significand, 0);
+  special_argument[1] = scalar_insert_exp (three_significand, 0);
+  result = test_denormal (&special_argument);
+  if (!result[0] || !result[1])
+    abort ();
+  result = test_denormal (&nonspecial_argument);
+  if (result[0] || result[1])
+    abort ();
+  return 0;
+}
+
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 248105)
+++ gcc/doc/extend.texi	(working copy)
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988-2017 Free Software Foundation, Inc.
+c Copyright (C) 1988-2017 Free Software Foundation, Inc.
 
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
@@ -15154,7 +15154,10 @@ long long __builtin_darn_raw (void);
 int __builtin_darn_32 (void);
 
 unsigned int scalar_extract_exp (double source);
+unsigned long long int scalar_extract_exp (__ieee128 source);
+
 unsigned long long int scalar_extract_sig (double source);
+unsigned __int128 scalar_extract_sig (__ieee128 source);
 
 double
 scalar_insert_exp (unsigned long long int significand, unsigned long long int exponent);
@@ -15161,6 +15164,11 @@ scalar_insert_exp (unsigned long long int signific
 double
 scalar_insert_exp (double significand, unsigned long long int exponent);
 
+ieee_128
+scalar_insert_exp (unsigned __int128 significand, unsigned long long int exponent);
+ieee_128
+scalar_insert_exp (ieee_128 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);
@@ -15168,9 +15176,11 @@ int scalar_cmp_exp_unordered (double arg1, double
 
 bool scalar_test_data_class (float source, const int condition);
 bool scalar_test_data_class (double source, const int condition);
+bool scalar_test_data_class (__ieee128 source, const int condition);
 
 bool scalar_test_neg (float source);
 bool scalar_test_neg (double source);
+bool scalar_test_neg (__ieee128 source);
 
 int __builtin_byte_in_set (unsigned char u, unsigned long long set);
 int __builtin_byte_in_range (unsigned char u, unsigned int range);
@@ -15210,18 +15220,23 @@ functions require a 64-bit environment supporting
 The @code{scalar_extract_exp} and @code{scalar_extract_sig} built-in
 functions return the significand and the biased exponent value
 respectively of their @code{source} arguments.
-Within the result returned by @code{scalar_extract_sig},
-the @code{0x10000000000000} bit is set if the
+When supplied with a 64-bit @code{source} argument, the
+result returned by @code{scalar_extract_sig} has
+the @code{0x10000000000000} bit set if the
 function's @code{source} argument is in normalized form.
 Otherwise, this bit is set to 0.
+When supplied with a 128-bit @code{source} argument, the
+@code{0x10000000000000000000000000000} bit of the result is
+treated similarly.
 Note that the sign of the significand is not represented in the result
 returned from the @code{scalar_extract_sig} function.  Use the
 @code{scalar_test_neg} function to test the sign of its @code{double}
 argument.
 
-The @code{scalar_insert_exp} 
-function requires a 64-bit environment supporting ISA 3.0 or later.
-The @code{scalar_insert_exp} built-in function returns a double-precision
+The @code{scalar_insert_exp}
+functions require a 64-bit environment supporting ISA 3.0 or later.
+When supplied with a 64-bit first argument, 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
@@ -15228,8 +15243,16 @@ result is copied from the most significant bit of
 @code{significand} argument.  The significand and exponent components
 of the result are composed of the least significant 11 bits of the
 @code{exponent} argument and the least significant 52 bits of the
-@code{significand} argument.
+@code{significand} argument respectively.
 
+When supplied with a 128-bit first argument, the
+@code{scalar_insert_exp} built-in function returns a quad-precision
+ieee floating point value.  The sign bit 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 15 bits of the @code{exponent} argument and the
+least significant 112 bits of the @code{significand} argument respectively.
+
 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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH,rs6000] Add IEEE 128 support for several existing built-in functions
  2017-06-21 22:43 [PATCH,rs6000] Add IEEE 128 support for several existing built-in functions Kelvin Nilsen
@ 2017-06-23 15:59 ` Segher Boessenkool
  0 siblings, 0 replies; 2+ messages in thread
From: Segher Boessenkool @ 2017-06-23 15:59 UTC (permalink / raw)
  To: Kelvin Nilsen; +Cc: gcc-patches

Hi Kelvin,

On Wed, Jun 21, 2017 at 04:42:46PM -0600, Kelvin Nilsen wrote:
> This patch adds IEEE 128 support to the existing scalar_insert_exp,
> scalar_extract_exp, scalar_extract_sig, scalar_test_data_class, and
> scalar_test_neg rs6000 built-in functions.  Test programs are provided
> to exercise the new IEEE 128 functionality and to validate forms of
> these built-in functions that do not depend on IEEE 128 support.


> 	* config/rs6000/rs6000-builtin.def (VSEEQP): Add scalar	extract

Stray tab (after "scalar").

> +;; VSX Scalar Extract Exponent Quad-Precision
> +(define_insn "xsxexpqp"
> +  [(set (match_operand:DI 0 "altivec_register_operand" "=v")
> +	(unspec:DI [(match_operand:KF 1 "altivec_register_operand" "v")]
> +	 UNSPEC_VSX_SXEXPDP))]
> +  "TARGET_P9_VECTOR && TARGET_64BIT"
> +  "xsxexpqp %0,%1"
> +  [(set_attr "type" "vecmove")])

TARGET_64BIT should probably be removed (and if not, a comment would help).

You also may want to explain the low half of the TI result is zeroed, but
we ignore it here?  (Because some other insns use TI).  Or maybe that is
obvious to people who actually know the instructions ;-)

> +;; VSX Scalar Extract Significand Quad-Precision
> +(define_insn "xsxsigqp"
> +  [(set (match_operand:TI 0 "altivec_register_operand" "=v")
> +	(unspec:TI [(match_operand:KF 1 "altivec_register_operand" "v")]
> +	 UNSPEC_VSX_SXSIGDP))]
> +  "TARGET_P9_VECTOR && TARGET_64BIT"
> +  "xsxsigqp %0,%1"
> +  [(set_attr "type" "vecmove")])

Should this be UNSPEC_VSX_SXSIGQP?  Or, if we can use the same unspec for
all data sizes, its name should not say "DP" :-)

(And TARGET_64BIT; please check it everywhere).

> +;; VSX Scalar Test Data Class Quad-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 "xststdcqp"
> +  [(set (match_dup 3)
> +	(compare:CCFP
> +	 (unspec:KF
> +	  [(match_operand:KF 1 "vsx_register_operand" "v")
> +	   (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)))]

So this is specialised to only testing the "eq" part.  That is fine, but
please add a comment?

> +  operands[4] = CONST0_RTX (SImode);

Please write const0_rtx, instead, for scalar integer modes.

> +(define_insn "*xststdcqp"
> +  [(set (match_operand:CCFP 0 "" "=y")
> +	(compare:CCFP
> +	 (unspec:KF [(match_operand:KF 1 "altivec_register_operand" "v")
> +		     (match_operand:SI 2 "u7bit_cint_operand" "n")]
> +	  UNSPEC_VSX_STSTDC)
> +	 (match_operand:SI 3 "zero_constant" "j")))]

Can't you just write (const_int 0) here?

> +	if (GET_MODE_PRECISION (arg1_mode) > 64)
> +	  {
> +	    /* if first argument is of float variety, choose variant
> +	       that expects __ieee128 argument.  Otherwise, expect
> +	       __int128 argument.  */

"If".

> +	else
> +	  {
> +	    /* if first argument is of float variety, choose variant

(again).

> +/* { dg-do compile { target { powerpc*-*-* } } } */

Btw, tests in gcc.target/powerpc do not need this line: from powerpc.exp:

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

(and compile is the default action).

Doesn't hurt either of course.

>  The @code{scalar_extract_exp} and @code{scalar_extract_sig} built-in
>  functions return the significand and the biased exponent value
>  respectively of their @code{source} arguments.
> -Within the result returned by @code{scalar_extract_sig},
> -the @code{0x10000000000000} bit is set if the
> +When supplied with a 64-bit @code{source} argument, the
> +result returned by @code{scalar_extract_sig} has
> +the @code{0x10000000000000} bit set if the
>  function's @code{source} argument is in normalized form.
>  Otherwise, this bit is set to 0.
> +When supplied with a 128-bit @code{source} argument, the
> +@code{0x10000000000000000000000000000} bit of the result is
> +treated similarly.

Which bit is that?  Hard to tell...  Maybe write
@code{0x00010000000000000000000000000000} (and @code{0x0010000000000000})
to make it easier to read?


Please consider the trivialities above; the patch is okay for trunk.
Thanks,


Segher

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-06-23 15:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-21 22:43 [PATCH,rs6000] Add IEEE 128 support for several existing built-in functions Kelvin Nilsen
2017-06-23 15:59 ` Segher Boessenkool

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).