public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction
@ 2016-05-11 22:06 Kelvin Nilsen
  2016-05-13 21:29 ` Segher Boessenkool
  0 siblings, 1 reply; 2+ messages in thread
From: Kelvin Nilsen @ 2016-05-11 22:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Segher Boessenkool


This patch adds built-in function support for the Power9 darn
instruction.  This patch differs from the v2 patch distributed on 5 May 
in the following ways:

1. Removed "darn" macro short-hand definitions from altivec.h
2. Removed extraneous assert in rs6000.c
3. Changed the attribute type for each of the darn instructions to
"integer".
4. Removed the redundant specification of attribute length from each of
the darn instructions.
5. Replaced a %d with %u in a fprintf formatting string within rs6000.c.
6. Fixed various spelling and style errors as identified by Bernhard
Reutner-Fischer and Segher Boessenkool.
7. After further investigation and private discussion with Segher
Boessenkool, it was determined to not replace use of the
RS6000_BTC_SPECIAL flag with a new RS6000_BTC_NULLARY flag.

I have bootstrapped and tested this patch against the trunk and against
the gcc-6-branch on both powerpc64le-unknown-linux-gnu and
powerpc64-unknown-linux-gnu with no regressions.  Is this ok for trunk
and for backporting to GCC 6 after a few days of burn-in time on the
trunk?

Thanks,
Kelvin

gcc/testsuite/ChangeLog:

2016-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* gcc.target/powerpc/darn-0.c: New test.
	* gcc.target/powerpc/darn-1.c: New test.
	* gcc.target/powerpc/darn-2.c: New test.


gcc/ChangeLog:

2016-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	* config/rs6000/altivec.md (UNSPEC_DARN): New unspec constant.
	(UNSPEC_DARN_32): New unspec constant.
	(UNSPEC_DARN_RAW): New unspec constant.
	(darn_32): New instruction.
	(darn_raw): New instruction.
	(darn): New instruction.
	* config/rs6000/rs6000-builtin.def (RS6000_BUILTIN_0): Add
	support and documentation for this macro.
	(BU_P9_MISC_1): New macro definition.
	(BU_P9_64BIT_MISC_0): New macro definition.
	(BU_P9_MISC_0): New macro definition.
	(darn_32): New builtin definition.
	(darn_raw): New builtin definition.
	(darn): New builtin definition.
	* config/rs6000/rs6000.c: Add #define RS6000_BUILTIN_0 and #undef
	RS6000_BUILTIN_0 directives to surround each occurrence of
	#include "rs6000-builtin.def".
	(rs6000_builtin_mask_calculate): Add in the RS6000_BTM_MODULO and
	RS6000_BTM_64BIT flags to the returned mask, depending on
	configuration.
	(def_builtin): Correct an error in the assignments made to the
	debugging variable attr_string.
	(rs6000_expand_builtin): Add support for no-operand built-in
	functions.
	(builtin_function_type): Remove fatal_error assertion that is no
	longer valid.
	(rs6000_common_init_builtins): Add support for no-operand built-in
	functions.
	* config/rs6000/rs6000.h (RS6000_BTM_MODULO): New macro
	definition.
	(RS6000_BTM_PURE): Enhance comment to clarify intent of this flag
	definition.
	(RS6000_BTM_64BIT): New macro definition.
	* doc/extend.texi: Document __builtin_darn (void),
	__builtin_darn_raw (void), and __builtin_darn_32 (void) built-in
	functions.


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,33 @@
   [(set_attr "length" "4")
    (set_attr "type" "vecsimple")])
 
+(define_insn "darn_32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
+  "TARGET_MODULO"
+  {
+     return "darn %0,0";
+  }
+  [(set_attr "type" "integer")])
+
+(define_insn "darn_raw"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
+  "TARGET_MODULO && TARGET_64BIT"
+  {
+     return "darn %0,2";
+  }
+  [(set_attr "type" "integer")])
+
+(define_insn "darn"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+        (unspec:DI [(const_int 0)] UNSPEC_DARN))]
+  "TARGET_MODULO && TARGET_64BIT"
+  {
+     return "darn %0,1";
+  }
+  [(set_attr "type" "integer")])
+
 (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 = {
 
 \f
 /* 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,12 @@ 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_unreachable ();
 }
 
@@ -16559,10 +16629,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 +16680,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 +16897,66 @@ 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-argument %s\n", d->name);
+	  continue;
+	}
+      if (rs6000_overloaded_builtin_p (d->code))
+	{
+	  if (! (type = opaque_ftype_opaque)) 
+	    {
+	      opaque_ftype_opaque
+		= build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
+	      type = opaque_ftype_opaque;
+	    }
+	}
+      else
+	{
+	  enum insn_code icode = d->icode;
+	  if (d->name == 0)
+	    {
+	      if (TARGET_DEBUG_BUILTIN)
+		fprintf (stderr, "rs6000_builtin, bdesc_0arg[%lu] 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))
+		{
+		  v2si_ftype
+		    = build_function_type_list (opaque_V2SI_type_node, 
+						NULL_TREE);
+		  type = v2si_ftype;
+		}
+	    }
+	  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" } } */

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

* Re: [PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction
  2016-05-11 22:06 [PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction Kelvin Nilsen
@ 2016-05-13 21:29 ` Segher Boessenkool
  0 siblings, 0 replies; 2+ messages in thread
From: Segher Boessenkool @ 2016-05-13 21:29 UTC (permalink / raw)
  To: Kelvin Nilsen; +Cc: gcc-patches, Segher Boessenkool

On Wed, May 11, 2016 at 04:05:46PM -0600, Kelvin Nilsen wrote:
> I have bootstrapped and tested this patch against the trunk and against
> the gcc-6-branch on both powerpc64le-unknown-linux-gnu and
> powerpc64-unknown-linux-gnu with no regressions.  Is this ok for trunk
> and for backporting to GCC 6 after a few days of burn-in time on the
> trunk?

> 2016-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
> 
> 	* gcc.target/powerpc/darn-0.c: New test.
> 	* gcc.target/powerpc/darn-1.c: New test.
> 	* gcc.target/powerpc/darn-2.c: New test.

> 2016-05-11  Kelvin Nilsen  <kelvin@gcc.gnu.org>
> 
> 	* config/rs6000/altivec.md (UNSPEC_DARN): New unspec constant.
> 	(UNSPEC_DARN_32): New unspec constant.
> 	(UNSPEC_DARN_RAW): New unspec constant.
> 	(darn_32): New instruction.
> 	(darn_raw): New instruction.
> 	(darn): New instruction.
> 	* config/rs6000/rs6000-builtin.def (RS6000_BUILTIN_0): Add
> 	support and documentation for this macro.
> 	(BU_P9_MISC_1): New macro definition.
> 	(BU_P9_64BIT_MISC_0): New macro definition.
> 	(BU_P9_MISC_0): New macro definition.
> 	(darn_32): New builtin definition.
> 	(darn_raw): New builtin definition.
> 	(darn): New builtin definition.
> 	* config/rs6000/rs6000.c: Add #define RS6000_BUILTIN_0 and #undef
> 	RS6000_BUILTIN_0 directives to surround each occurrence of
> 	#include "rs6000-builtin.def".
> 	(rs6000_builtin_mask_calculate): Add in the RS6000_BTM_MODULO and
> 	RS6000_BTM_64BIT flags to the returned mask, depending on
> 	configuration.
> 	(def_builtin): Correct an error in the assignments made to the
> 	debugging variable attr_string.
> 	(rs6000_expand_builtin): Add support for no-operand built-in
> 	functions.
> 	(builtin_function_type): Remove fatal_error assertion that is no
> 	longer valid.
> 	(rs6000_common_init_builtins): Add support for no-operand built-in
> 	functions.
> 	* config/rs6000/rs6000.h (RS6000_BTM_MODULO): New macro
> 	definition.
> 	(RS6000_BTM_PURE): Enhance comment to clarify intent of this flag
> 	definition.
> 	(RS6000_BTM_64BIT): New macro definition.
> 	* doc/extend.texi: Document __builtin_darn (void),
> 	__builtin_darn_raw (void), and __builtin_darn_32 (void) built-in
> 	functions.

> +(define_insn "darn_32"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +        (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
> +  "TARGET_MODULO"
> +  {
> +     return "darn %0,0";
> +  }
> +  [(set_attr "type" "integer")])

Don't indent the {}; but in simple cases like this, you don't need a C
block, just the string:

+(define_insn "darn_32"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
+  "TARGET_MODULO"
+  "darn %0,0"
+  [(set_attr "type" "integer")])

> +      if (rs6000_overloaded_builtin_p (d->code))
> +	{
> +	  if (! (type = opaque_ftype_opaque)) 
> +	    {
> +	      opaque_ftype_opaque
> +		= build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
> +	      type = opaque_ftype_opaque;
> +	    }

No space after !; no space at end of line.  It's easier to read if you put
the assignment as a separate statement before the if.  Or write is as

+	  if (!opaque_ftype_opaque)
+	    opaque_ftype_opaque
+	      = build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
+	  type = opaque_ftype_opaque;

Okay with those changes, thanks!


Segher

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

end of thread, other threads:[~2016-05-13 21:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-11 22:06 [PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction Kelvin Nilsen
2016-05-13 21:29 ` 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).