This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction
- From: Kelvin Nilsen <kdnilsen at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Segher Boessenkool <segher at linux dot vnet dot ibm dot com>
- Date: Wed, 11 May 2016 16:05:46 -0600
- Subject: [PATCH v3, rs6000] Add built-in support for new Power9 darn (deliver a random number) instruction
- Authentication-results: sourceware.org; auth=none
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 = {
/* 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" } } */