Index: gcc/config/rs6000/altivec.h
===================================================================
--- gcc/config/rs6000/altivec.h	(revision 235884)
+++ gcc/config/rs6000/altivec.h	(working copy)
@@ -382,6 +382,11 @@
 #define vec_vsubuqm __builtin_vec_vsubuqm
 #define vec_vupkhsw __builtin_vec_vupkhsw
 #define vec_vupklsw __builtin_vec_vupklsw
+
+/* Non-Vector additions added in ISA 3.0. */
+#define darn __builtin_darn
+#define darn_32 __builtin_darn_32
+#define darn_raw __builtin_darn_raw
 #endif

 /* Predicates.
Index: gcc/config/rs6000/altivec.md
===================================================================
--- gcc/config/rs6000/altivec.md	(revision 235884)
+++ gcc/config/rs6000/altivec.md	(working copy)
@@ -73,6 +73,9 @@
    UNSPEC_VUNPACK_LO_SIGN_DIRECT
    UNSPEC_VUPKHPX
    UNSPEC_VUPKLPX
+   UNSPEC_DARN
+   UNSPEC_DARN_32
+   UNSPEC_DARN_RAW
    UNSPEC_DST
    UNSPEC_DSTT
    UNSPEC_DSTST
@@ -3590,6 +3593,37 @@
   [(set_attr "length" "4")
    (set_attr "type" "vecsimple")])

+(define_insn "darn_32"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
+  "TARGET_MODULO"
+  {
+     return "darn %0,0";
+  }
+  [(set_attr "type" "add")
+   (set_attr "length" "4")])
+
+(define_insn "darn_raw"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
+  "TARGET_MODULO && TARGET_64BIT"
+  {
+     return "darn %0,2";
+  }
+  [(set_attr "type" "add")
+   (set_attr "length" "4")])
+
+(define_insn "darn"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (unspec:DI [(const_int 0)] UNSPEC_DARN))]
+  "TARGET_MODULO && TARGET_64BIT"
+  {
+     return "darn %0,1";
+  }
+  [(set_attr "type" "add")
+   (set_attr "length" "4")])
+
+
 (define_expand "bcd<bcd_add_sub>_<code>"
   [(parallel [(set (reg:CCFP 74)
 		   (compare:CCFP
Index: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 235884)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -24,6 +24,7 @@
    <http://www.gnu.org/licenses/>.  */

 /* Before including this file, some macros must be defined:
+   RS6000_BUILTIN_0 -- 0 arg builtins
    RS6000_BUILTIN_1 -- 1 arg builtins
    RS6000_BUILTIN_2 -- 2 arg builtins
    RS6000_BUILTIN_3 -- 3 arg builtins
@@ -43,6 +44,10 @@
 	ATTR	builtin attribute information.
 	ICODE	Insn code of the function that implents the builtin.  */

+#ifndef RS6000_BUILTIN_0
+  #error "RS6000_BUILTIN_0 is not defined."
+#endif
+
 #ifndef RS6000_BUILTIN_1
   #error "RS6000_BUILTIN_1 is not defined."
 #endif
@@ -637,6 +642,41 @@
 		     | RS6000_BTC_TERNARY),				\
 		    CODE_FOR_ ## ICODE)			/* ICODE */

+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
+   instructions don't require either the DFP or VSX options, just the
basic
+   ISA 3.0 enablement since they operate on general purpose registers.  */
+#define BU_P9_MISC_1(ENUM, NAME, ATTR, ICODE)				\
+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_MODULO,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_UNARY),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
+   instructions don't require either the DFP or VSX options, just the
basic
+   ISA 3.0 enablement since they operate on general purpose registers,
+   and they require 64-bit addressing.  */
+#define BU_P9_64BIT_MISC_0(ENUM, NAME, ATTR, ICODE)			\
+  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_MODULO                                   \
+                     | RS6000_BTM_64BIT,		/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_SPECIAL),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
+/* Miscellaneous builtins for instructions added in ISA 3.0.  These
+   instructions don't require either the DFP or VSX options, just the
basic
+   ISA 3.0 enablement since they operate on general purpose registers.  */
+#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE)                      \
+  RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
+		    "__builtin_" NAME,			/* NAME */	\
+		    RS6000_BTM_MODULO,			/* MASK */	\
+		    (RS6000_BTC_ ## ATTR		/* ATTR */	\
+		     | RS6000_BTC_SPECIAL),				\
+		    CODE_FOR_ ## ICODE)			/* ICODE */
+
 /* 128-bit long double floating point builtins.  */
 #define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE)				\
   RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,		/* ENUM */	\
@@ -1653,6 +1693,11 @@ BU_P8V_MISC_3 (BCDSUB_OV,	"bcdsub_ov",	CONST,	bcds
 BU_DFP_MISC_2 (PACK_TD,		"pack_dec128",		CONST,	packtd)
 BU_DFP_MISC_2 (UNPACK_TD,	"unpack_dec128",	CONST,	unpacktd)

+/* 0 argument general-purpose register functions added in ISA 3.0
(power9).  */
+BU_P9_MISC_0 (DARN_32,		"darn_32", 		MISC, darn_32)
+BU_P9_64BIT_MISC_0 (DARN_RAW,	"darn_raw", 		MISC, darn_raw)
+BU_P9_64BIT_MISC_0 (DARN,	"darn",			MISC, darn)
+
 BU_LDBL128_2 (PACK_TF,		"pack_longdouble",	CONST,	packtf)
 BU_LDBL128_2 (UNPACK_TF,	"unpack_longdouble",	CONST,	unpacktf)

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 235884)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1128,6 +1128,7 @@ struct processor_costs ppca2_cost = {


 /* Table that classifies rs6000 builtin functions (pure, const, etc.).  */
+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -1140,6 +1141,9 @@ struct processor_costs ppca2_cost = {
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+  { NAME, ICODE, MASK, ATTR },
+
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
   { NAME, ICODE, MASK, ATTR },

@@ -1185,6 +1189,7 @@ static const struct rs6000_builtin_info_type rs600
 #include "rs6000-builtin.def"
 };

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -3634,6 +3639,8 @@ rs6000_builtin_mask_calculate (void)
 	  | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL      : 0)
 	  | ((TARGET_P8_VECTOR)		    ? RS6000_BTM_P8_VECTOR : 0)
 	  | ((TARGET_P9_VECTOR)		    ? RS6000_BTM_P9_VECTOR : 0)
+	  | ((TARGET_MODULO)		    ? RS6000_BTM_MODULO    : 0)
+	  | ((TARGET_64BIT)		    ? RS6000_BTM_64BIT    : 0)
 	  | ((TARGET_CRYPTO)		    ? RS6000_BTM_CRYPTO	   : 0)
 	  | ((TARGET_HTM)		    ? RS6000_BTM_HTM	   : 0)
 	  | ((TARGET_DFP)		    ? RS6000_BTM_DFP	   : 0)
@@ -12268,7 +12275,7 @@ def_builtin (const char *name, tree type, enum rs6
       /* const function, function only depends on the inputs.  */
       TREE_READONLY (t) = 1;
       TREE_NOTHROW (t) = 1;
-      attr_string = ", pure";
+      attr_string = ", const";
     }
   else if ((classify & RS6000_BTC_PURE) != 0)
     {
@@ -12276,7 +12283,7 @@ def_builtin (const char *name, tree type, enum rs6
 	 external state.  */
       DECL_PURE_P (t) = 1;
       TREE_NOTHROW (t) = 1;
-      attr_string = ", const";
+      attr_string = ", pure";
     }
   else if ((classify & RS6000_BTC_FP) != 0)
     {
@@ -12308,6 +12315,7 @@ def_builtin (const char *name, tree type, enum rs6

 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc).  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12320,6 +12328,7 @@ def_builtin (const char *name, tree type, enum rs6
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
@@ -12341,6 +12350,7 @@ static const struct builtin_description bdesc_3arg

 /* DST operations: void foo (void *, const int, const char).  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12353,6 +12363,7 @@ static const struct builtin_description bdesc_3arg
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12374,6 +12385,7 @@ static const struct builtin_description bdesc_dst[

 /* Simple binary operations: VECc = foo (VECa, VECb).  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12386,6 +12398,7 @@ static const struct builtin_description bdesc_dst[
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
   { MASK, ICODE, NAME, ENUM },
@@ -12405,6 +12418,7 @@ static const struct builtin_description bdesc_2arg
 #include "rs6000-builtin.def"
 };

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12417,6 +12431,7 @@ static const struct builtin_description bdesc_2arg
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12439,6 +12454,7 @@ static const struct builtin_description bdesc_alti
 };

 /* SPE predicates.  */
+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12451,6 +12467,7 @@ static const struct builtin_description bdesc_alti
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12471,6 +12488,7 @@ static const struct builtin_description bdesc_spe_
 };

 /* SPE evsel predicates.  */
+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12483,6 +12501,7 @@ static const struct builtin_description bdesc_spe_
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12503,6 +12522,7 @@ static const struct builtin_description bdesc_spe_
 };

 /* PAIRED predicates.  */
+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12515,6 +12535,7 @@ static const struct builtin_description bdesc_spe_
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12536,6 +12557,7 @@ static const struct builtin_description bdesc_pair

 /* ABS* operations.  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12548,6 +12570,7 @@ static const struct builtin_description bdesc_pair
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12570,6 +12593,7 @@ static const struct builtin_description bdesc_abs[
 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
    foo (VECa).  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12582,6 +12606,7 @@ static const struct builtin_description bdesc_abs[
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
   { MASK, ICODE, NAME, ENUM },

@@ -12601,7 +12626,43 @@ static const struct builtin_description bdesc_1arg
 #include "rs6000-builtin.def"
 };

+/* Simple no-argument operations: result = __builtin_darn_32 () */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_Q
+#undef RS6000_BUILTIN_S
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+  { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_0arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
 /* HTM builtins.  */
+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12614,6 +12675,7 @@ static const struct builtin_description bdesc_1arg
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12633,6 +12695,7 @@ static const struct builtin_description bdesc_htm[
 #include "rs6000-builtin.def"
 };

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -12717,7 +12780,6 @@ rs6000_expand_mtfsf_builtin (enum insn_code icode,
   return NULL_RTX;
 }

-
 static rtx
 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
 {
@@ -15157,10 +15219,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx s
     }

   unsigned attr = rs6000_builtin_info[uns_fcode].attr &
RS6000_BTC_TYPE_MASK;
+  /* RS6000_BTC_SPECIAL represents no-operand operators.  */
   gcc_assert (attr == RS6000_BTC_UNARY
 	      || attr == RS6000_BTC_BINARY
-	      || attr == RS6000_BTC_TERNARY);
-
+	      || attr == RS6000_BTC_TERNARY
+	      || attr == RS6000_BTC_SPECIAL);
+
   /* Handle simple unary operations.  */
   d = bdesc_1arg;
   for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
@@ -15179,6 +15243,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx s
     if (d->code == fcode)
       return rs6000_expand_ternop_builtin (d->icode, exp, target);

+  /* Handle simple no-argument operations. */
+  d = bdesc_0arg;
+  for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+    if (d->code == fcode)
+      return rs6000_expand_zeroop_builtin (d->icode, target);
+
+  gcc_assert (false);
   gcc_unreachable ();
 }

@@ -16559,10 +16630,6 @@ builtin_function_type (machine_mode mode_ret, mach
   while (num_args > 0 && h.mode[num_args] == VOIDmode)
     num_args--;

-  if (num_args == 0)
-    fatal_error (input_location,
-		 "internal error: builtin function %s had no type", name);
-
   ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
   if (!ret_type && h.uns_p[0])
     ret_type = builtin_mode_to_type[h.mode[0]][0];
@@ -16614,6 +16681,7 @@ rs6000_common_init_builtins (void)
   tree opaque_ftype_opaque = NULL_TREE;
   tree opaque_ftype_opaque_opaque = NULL_TREE;
   tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
+  tree v2si_ftype = NULL_TREE;
   tree v2si_ftype_qi = NULL_TREE;
   tree v2si_ftype_v2si_qi = NULL_TREE;
   tree v2si_ftype_int_qi = NULL_TREE;
@@ -16830,6 +16898,69 @@ rs6000_common_init_builtins (void)

       def_builtin (d->name, type, d->code);
     }
+
+  /* Add the simple no-argument operators.  */
+  d = bdesc_0arg;
+  for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+    {
+      machine_mode mode0;
+      tree type;
+      HOST_WIDE_INT mask = d->mask;
+
+      if ((mask & builtin_mask) != mask)
+	{
+	  if (TARGET_DEBUG_BUILTIN)
+	    fprintf (stderr, "rs6000_builtin, skip no-argumen %s\n", d->name);
+	  continue;
+	}
+
+      if (rs6000_overloaded_builtin_p (d->code))
+	{
+	  if (! (type = opaque_ftype_opaque))
+	    type = opaque_ftype_opaque
+	      = build_function_type_list (opaque_V4SI_type_node,
+					  NULL_TREE);
+	}
+      else
+        {
+	  enum insn_code icode = d->icode;
+	  if (d->name == 0)
+	    {
+	      if (TARGET_DEBUG_BUILTIN)
+		fprintf (stderr, "rs6000_builtin, bdesc_0arg[%ld] no name\n",
+			 (long unsigned)i);
+
+	      continue;
+	    }
+
+          if (icode == CODE_FOR_nothing)
+	    {
+	      if (TARGET_DEBUG_BUILTIN)
+		fprintf (stderr,
+			 "rs6000_builtin, skip no-argument %s (no code)\n",
+			 d->name);
+
+	      continue;
+	    }
+
+          mode0 = insn_data[icode].operand[0].mode;
+
+	  if (mode0 == V2SImode)
+	    {
+	      /* code for SPE */
+	      if (! (type = v2si_ftype))
+		type = v2si_ftype
+		  = build_function_type_list (opaque_V2SI_type_node,
+					      NULL_TREE);
+	    }
+
+	  else
+	    type = builtin_function_type (mode0, VOIDmode, VOIDmode, VOIDmode,
+					  d->code, d->name);
+	}
+
+      def_builtin (d->name, type, d->code);
+    }
 }

 /* Set up AIX/Darwin/64-bit Linux quad floating point routines.  */
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 235884)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -656,6 +656,11 @@ extern int rs6000_vector_align[];
 #define MASK_PROTOTYPE			OPTION_MASK_PROTOTYPE
 #endif

+#ifdef TARGET_MODULO
+#define RS6000_BTM_MODULO		OPTION_MASK_MODULO
+#endif
+
+
 /* For power systems, we want to enable Altivec and VSX builtins even
if the
    user did not use -maltivec or -mvsx to allow the builtins to be used
inside
    of #pragma GCC target or the target attribute to change the code
level for a
@@ -2644,7 +2649,9 @@ extern int frame_pointer_needed;

 #define RS6000_BTC_MISC		0x00000000	/* No special attributes.  */
 #define RS6000_BTC_CONST	0x00000100	/* uses no global state.  */
-#define RS6000_BTC_PURE		0x00000200	/* reads global state/mem.  */
+#define RS6000_BTC_PURE		0x00000200	/* reads global
+						   state/mem and does
+						   not modify global state.  */
 #define RS6000_BTC_FP		0x00000400	/* depends on rounding mode.  */
 #define RS6000_BTC_ATTR_MASK	0x00000700	/* Mask of the attributes.  */

@@ -2680,6 +2687,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_DFP		MASK_DFP	/* Decimal floating point.  */
 #define RS6000_BTM_HARD_FLOAT	MASK_SOFT_FLOAT	/* Hardware floating
point.  */
 #define RS6000_BTM_LDBL128	MASK_MULTIPLE	/* 128-bit long double.  */
+#define RS6000_BTM_64BIT	MASK_64BIT	/* 64-bit addressing.  */

 #define RS6000_BTM_COMMON	(RS6000_BTM_ALTIVEC			\
 				 | RS6000_BTM_VSX			\
@@ -2699,6 +2707,7 @@ extern int frame_pointer_needed;

 /* Define builtin enum index.  */

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
@@ -2711,6 +2720,7 @@ extern int frame_pointer_needed;
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X

+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
@@ -2730,6 +2740,7 @@ enum rs6000_builtins
   RS6000_BUILTIN_COUNT
 };

+#undef RS6000_BUILTIN_0
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 235884)
+++ gcc/doc/extend.texi	(working copy)
@@ -13897,6 +13897,23 @@ The @code{__builtin_divde}, @code{__builtin_divdeo
 64-bit environment support ISA 2.06 or later.

 The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 3.0 or later (@option{-mcpu=power9}
+or @option{-mmodulo}):
+@smallexample
+long long __builtin_darn (void);
+long long __builtin_darn_raw (void);
+int __builtin_darn_32 (void);
+@end smallexample
+
+The @code{__builtin_darn} and @code{__builtin_darn_raw}
+functions require a
+64-bit environment supporting ISA 3.0 or later.
+The @code{__builtin_darn} function provides a 64-bit conditioned
+random number.  The @code{__builtin_darn_raw} function provides a
+64-bit raw random number.  The @code{__builtin_darn_32} function
+provides a 32-bit random number.
+
+The following built-in functions are available for the PowerPC family
 of processors when hardware decimal floating point
 (@option{-mhard-dfp}) is available:
 @smallexample
Index: gcc/testsuite/gcc.target/powerpc/darn-0.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darn-0.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/darn-0.c	(working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations.  */
+#include <altivec.h>
+
+int get_random()
+{
+  return __builtin_darn_32 ();
+}
+
+/* { dg-final { scan-assembler	   "darn" } } */
Index: gcc/testsuite/gcc.target/powerpc/darn-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darn-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/darn-1.c	(working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <altivec.h>
+
+long long get_conditioned_random()
+{
+  return __builtin_darn ();
+}
+
+/* { dg-final { scan-assembler	   "darn" } } */
Index: gcc/testsuite/gcc.target/powerpc/darn-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darn-2.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/darn-2.c	(working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <altivec.h>
+
+long long get_raw_random()
+{
+  return __builtin_darn_raw ();
+}
+
+/* { dg-final { scan-assembler	   "darn" } } */
