aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2022-03-10 10:22:27 +0100
committerJakub Jelinek <jakub@redhat.com>2022-03-10 10:22:27 +0100
commit6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6 (patch)
tree0358a181a3cc5f644433d25ba05c8d3560d8e81e /gcc/config
parentff060ef08cfc3e48e70071cb63449b62a86f9d6f (diff)
downloadgcc-6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6.zip
gcc-6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6.tar.gz
gcc-6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6.tar.bz2
rs6000: Fix up __SIZEOF_{FLOAT,IBM}128__ defines [PR99708]
As mentioned in the PR, right now on powerpc* __SIZEOF_{FLOAT,IBM}128__ macros are predefined unconditionally, because {ieee,ibm}128_float_type_node is always non-NULL, doesn't reflect whether __ieee128 or __ibm128 are actually supported or not. Based on patch review discussions, the following patch: 1) allows __ibm128 to be used in the sources even when !TARGET_FLOAT128_TYPE, as long as long double is double double 2) ensures ibm128_float_type_node is non-NULL only if __ibm128 is supported 3) ensures ieee128_float_type_node is non-NULL only if __ieee128 is supported (aka when TARGET_FLOAT128_TYPE) 4) predefines __SIZEOF_IBM128__ only when ibm128_float_type_node != NULL 5) newly predefines __SIZEOF_IEEE128__ if ieee128_float_type_node != NULL 6) predefines __SIZEOF_FLOAT128__ whenever ieee128_float_type_node != NULL and __float128 macro is predefined to __ieee128 7) removes ptr_*128_float_type_node which nothing uses 8) in order not to ICE during builtin initialization when ibm128_float_type_node == NULL, uses long_double_type_node as fallback for the __builtin_{,un}pack_ibm128 builtins 9) errors when those builtins are called used when ibm128_float_type_node == NULL (during their expansion) 10) moves the {,un}packif -> {,un}packtf remapping for these builtins in expansion earlier, so that we don't ICE on them if not -mabi=ieeelongdouble 2022-03-10 Jakub Jelinek <jakub@redhat.com> PR target/99708 * config/rs6000/rs6000.h (enum rs6000_builtin_type_index): Remove RS6000_BTI_ptr_ieee128_float and RS6000_BTI_ptr_ibm128_float. (ptr_ieee128_float_type_node, ptr_ibm128_float_type_node): Remove. * config/rs6000/rs6000-builtin.cc (rs6000_type_string): Return "**NULL**" if type_node is NULL first. Handle ieee128_float_type_node. (rs6000_init_builtins): Don't initialize ptr_ieee128_float_type_node and ptr_ibm128_float_type_node. Set ibm128_float_type_node and ieee128_float_type_node to NULL rather than long_double_type_node if they aren't supported. Do support __ibm128 even if !TARGET_FLOAT128_TYPE when long double is double double. (rs6000_expand_builtin): Error if bif_is_ibm128 and !ibm128_float_type_node. Remap RS6000_BIF_{,UN}PACK_IF to RS6000_BIF_{,UN}PACK_TF much earlier and only use bif_is_ibm128 check for it. * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define __SIZEOF_FLOAT128__ here and only iff __float128 macro is defined. (rs6000_cpu_cpp_builtins): Don't define __SIZEOF_FLOAT128__ here. Define __SIZEOF_IBM128__=16 if ieee128_float_type_node is non-NULL. Formatting fix. * config/rs6000/rs6000-gen-builtins.cc: Document ibm128 attribute. (struct attrinfo): Add isibm128 member. (TYPE_MAP_SIZE): Remove. (type_map): Use [] instead of [TYPE_MAP_SIZE]. For "if" use ibm128_float_type_node only if it is non-NULL, otherwise fall back to long_double_type_node. Remove "pif" entry. (parse_bif_attrs): Handle ibm128 attribute and print it for debugging. (write_decls): Output bif_ibm128_bit and bif_is_ibm128. (write_type_node): Use sizeof type_map / sizeof type_map[0] instead of TYPE_MAP_SIZE. (write_bif_static_init): Handle isibm128. * config/rs6000/rs6000-builtins.def: Document ibm128 attribute. (__builtin_pack_ibm128, __builtin_unpack_ibm128): Add ibm128 attribute. * gcc.dg/pr99708.c: New test. * gcc.target/powerpc/pr99708-2.c: New test. * gcc.target/powerpc/convert-fp-128.c (mode_kf): Define only if __FLOAT128_TYPE__ is defined.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000-builtin.cc59
-rw-r--r--gcc/config/rs6000/rs6000-builtins.def5
-rw-r--r--gcc/config/rs6000/rs6000-c.cc8
-rw-r--r--gcc/config/rs6000/rs6000-gen-builtins.cc29
-rw-r--r--gcc/config/rs6000/rs6000.h4
5 files changed, 65 insertions, 40 deletions
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 5d34c1b..e925ba9 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -402,7 +402,9 @@ rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts)
static
const char *rs6000_type_string (tree type_node)
{
- if (type_node == void_type_node)
+ if (type_node == NULL_TREE)
+ return "**NULL**";
+ else if (type_node == void_type_node)
return "void";
else if (type_node == long_integer_type_node)
return "long";
@@ -432,6 +434,8 @@ const char *rs6000_type_string (tree type_node)
return "ss";
else if (type_node == ibm128_float_type_node)
return "__ibm128";
+ else if (type_node == ieee128_float_type_node)
+ return "__ieee128";
else if (type_node == opaque_V4SI_type_node)
return "opaque";
else if (POINTER_TYPE_P (type_node))
@@ -709,9 +713,9 @@ rs6000_init_builtins (void)
For IEEE 128-bit floating point, always create the type __ieee128. If the
user used -mfloat128, rs6000-c.cc will create a define from __float128 to
__ieee128. */
- if (TARGET_FLOAT128_TYPE)
+ if (TARGET_LONG_DOUBLE_128 && (!TARGET_IEEEQUAD || TARGET_FLOAT128_TYPE))
{
- if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
+ if (!TARGET_IEEEQUAD)
ibm128_float_type_node = long_double_type_node;
else
{
@@ -721,22 +725,24 @@ rs6000_init_builtins (void)
layout_type (ibm128_float_type_node);
}
t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST);
- ptr_ibm128_float_type_node = build_pointer_type (t);
lang_hooks.types.register_builtin_type (ibm128_float_type_node,
"__ibm128");
+ }
+ else
+ ibm128_float_type_node = NULL_TREE;
+ if (TARGET_FLOAT128_TYPE)
+ {
if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
ieee128_float_type_node = long_double_type_node;
else
ieee128_float_type_node = float128_type_node;
t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST);
- ptr_ieee128_float_type_node = build_pointer_type (t);
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__ieee128");
}
-
else
- ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
+ ieee128_float_type_node = NULL_TREE;
/* Vector pair and vector quad support. */
vector_pair_type_node = make_node (OPAQUE_TYPE);
@@ -3418,6 +3424,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
return const0_rtx;
}
+ if (bif_is_ibm128 (*bifaddr) && !ibm128_float_type_node)
+ {
+ error ("%qs requires %<__ibm128%> type support",
+ bifaddr->bifname);
+ return const0_rtx;
+ }
+
if (bif_is_cpu (*bifaddr))
return cpu_expand_builtin (fcode, exp, target);
@@ -3498,6 +3511,21 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
gcc_unreachable ();
}
+ if (bif_is_ibm128 (*bifaddr) && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
+ {
+ if (fcode == RS6000_BIF_PACK_IF)
+ {
+ icode = CODE_FOR_packtf;
+ fcode = RS6000_BIF_PACK_TF;
+ uns_fcode = (size_t) fcode;
+ }
+ else if (fcode == RS6000_BIF_UNPACK_IF)
+ {
+ icode = CODE_FOR_unpacktf;
+ fcode = RS6000_BIF_UNPACK_TF;
+ uns_fcode = (size_t) fcode;
+ }
+ }
/* TRUE iff the built-in function returns void. */
bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
@@ -3642,23 +3670,6 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
if (bif_is_mma (*bifaddr))
return mma_expand_builtin (exp, target, icode, fcode);
- if (fcode == RS6000_BIF_PACK_IF
- && TARGET_LONG_DOUBLE_128
- && !TARGET_IEEEQUAD)
- {
- icode = CODE_FOR_packtf;
- fcode = RS6000_BIF_PACK_TF;
- uns_fcode = (size_t) fcode;
- }
- else if (fcode == RS6000_BIF_UNPACK_IF
- && TARGET_LONG_DOUBLE_128
- && !TARGET_IEEEQUAD)
- {
- icode = CODE_FOR_unpacktf;
- fcode = RS6000_BIF_UNPACK_TF;
- uns_fcode = (size_t) fcode;
- }
-
if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
target = NULL_RTX;
else if (target == 0
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index ae2760c..221bbc7 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -138,6 +138,7 @@
; lxvrze Needs special handling for load-rightmost, zero-extended
; endian Needs special handling for endianness
; ibmld Restrict usage to the case when TFmode is IBM-128
+; ibm128 Restrict usage to the case where __ibm128 is supported or if ibmld
;
; Each attribute corresponds to extra processing required when
; the built-in is expanded. All such special processing should
@@ -234,13 +235,13 @@
MTFSF rs6000_mtfsf {}
const __ibm128 __builtin_pack_ibm128 (double, double);
- PACK_IF packif {}
+ PACK_IF packif {ibm128}
void __builtin_set_fpscr_rn (const int[0,3]);
SET_FPSCR_RN rs6000_set_fpscr_rn {}
const double __builtin_unpack_ibm128 (__ibm128, const int<1>);
- UNPACK_IF unpackif {}
+ UNPACK_IF unpackif {ibm128}
; This is redundant with __builtin_unpack_ibm128, as it requires long
; double to be __ibm128. Should probably be deprecated.
diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index d2e480a..3b62b49 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -584,6 +584,10 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
rs6000_define_or_undefine_macro (true, "__float128=__ieee128");
else
rs6000_define_or_undefine_macro (false, "__float128");
+ if (ieee128_float_type_node && define_p)
+ rs6000_define_or_undefine_macro (true, "__SIZEOF_FLOAT128__=16");
+ else
+ rs6000_define_or_undefine_macro (false, "__SIZEOF_FLOAT128__");
}
/* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or
via the target attribute/pragma. */
@@ -623,11 +627,11 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
if (TARGET_FRSQRTES)
builtin_define ("__RSQRTEF__");
if (TARGET_FLOAT128_TYPE)
- builtin_define ("__FLOAT128_TYPE__");
+ builtin_define ("__FLOAT128_TYPE__");
if (ibm128_float_type_node)
builtin_define ("__SIZEOF_IBM128__=16");
if (ieee128_float_type_node)
- builtin_define ("__SIZEOF_FLOAT128__=16");
+ builtin_define ("__SIZEOF_IEEE128__=16");
#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
builtin_define ("__BUILTIN_CPU_SUPPORTS__");
#endif
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc b/gcc/config/rs6000/rs6000-gen-builtins.cc
index 629ead9..0bd7a53 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.cc
+++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
@@ -93,6 +93,8 @@ along with GCC; see the file COPYING3. If not see
lxvrze Needs special handling for load-rightmost, zero-extended
endian Needs special handling for endianness
ibmld Restrict usage to the case when TFmode is IBM-128
+ ibm128 Restrict usage to the case where __ibm128 is supported or
+ if ibmld
An example stanza might look like this:
@@ -392,6 +394,7 @@ struct attrinfo
bool islxvrze;
bool isendian;
bool isibmld;
+ bool isibm128;
};
/* Fields associated with a function prototype (bif or overload). */
@@ -492,8 +495,7 @@ struct typemap
maps tokens from a fntype string to a tree type. For example,
in "si_ftype_hi" we would map "si" to "intSI_type_node" and
map "hi" to "intHI_type_node". */
-#define TYPE_MAP_SIZE 86
-static typemap type_map[TYPE_MAP_SIZE] =
+static typemap type_map[] =
{
{ "bi", "bool_int" },
{ "bv16qi", "bool_V16QI" },
@@ -506,7 +508,9 @@ static typemap type_map[TYPE_MAP_SIZE] =
{ "df", "double" },
{ "di", "long_long_integer" },
{ "hi", "intHI" },
- { "if", "ibm128_float" },
+ { "if", "ibm128_float_type_node "
+ "? ibm128_float_type_node "
+ ": long_double" },
{ "ld", "long_double" },
{ "lg", "long_integer" },
{ "pbv16qi", "ptr_bool_V16QI" },
@@ -519,7 +523,6 @@ static typemap type_map[TYPE_MAP_SIZE] =
{ "pdf", "ptr_double" },
{ "pdi", "ptr_long_long_integer" },
{ "phi", "ptr_intHI" },
- { "pif", "ptr_ibm128_float" },
{ "pld", "ptr_long_double" },
{ "plg", "ptr_long_integer" },
{ "pqi", "ptr_intQI" },
@@ -1439,6 +1442,8 @@ parse_bif_attrs (attrinfo *attrptr)
attrptr->isendian = 1;
else if (!strcmp (attrname, "ibmld"))
attrptr->isibmld = 1;
+ else if (!strcmp (attrname, "ibm128"))
+ attrptr->isibm128 = 1;
else
{
diag (oldpos, "unknown attribute.\n");
@@ -1472,14 +1477,15 @@ parse_bif_attrs (attrinfo *attrptr)
"ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, "
"htmspr = %d, htmcr = %d, mma = %d, quad = %d, pair = %d, "
"mmaint = %d, no32bit = %d, 32bit = %d, cpu = %d, ldstmask = %d, "
- "lxvrse = %d, lxvrze = %d, endian = %d, ibmdld= %d.\n",
+ "lxvrse = %d, lxvrze = %d, endian = %d, ibmdld = %d, ibm128 = %d.\n",
attrptr->isinit, attrptr->isset, attrptr->isextract,
attrptr->isnosoft, attrptr->isldvec, attrptr->isstvec,
attrptr->isreve, attrptr->ispred, attrptr->ishtm, attrptr->ishtmspr,
attrptr->ishtmcr, attrptr->ismma, attrptr->isquad, attrptr->ispair,
attrptr->ismmaint, attrptr->isno32bit, attrptr->is32bit,
attrptr->iscpu, attrptr->isldstmask, attrptr->islxvrse,
- attrptr->islxvrze, attrptr->isendian, attrptr->isibmld);
+ attrptr->islxvrze, attrptr->isendian, attrptr->isibmld,
+ attrptr->isibm128);
#endif
return PC_OK;
@@ -2294,6 +2300,7 @@ write_decls (void)
fprintf (header_file, "#define bif_lxvrze_bit\t\t(0x00100000)\n");
fprintf (header_file, "#define bif_endian_bit\t\t(0x00200000)\n");
fprintf (header_file, "#define bif_ibmld_bit\t\t(0x00400000)\n");
+ fprintf (header_file, "#define bif_ibm128_bit\t\t(0x00800000)\n");
fprintf (header_file, "\n");
fprintf (header_file,
"#define bif_is_init(x)\t\t((x).bifattrs & bif_init_bit)\n");
@@ -2341,6 +2348,8 @@ write_decls (void)
"#define bif_is_endian(x)\t((x).bifattrs & bif_endian_bit)\n");
fprintf (header_file,
"#define bif_is_ibmld(x)\t((x).bifattrs & bif_ibmld_bit)\n");
+ fprintf (header_file,
+ "#define bif_is_ibm128(x)\t((x).bifattrs & bif_ibm128_bit)\n");
fprintf (header_file, "\n");
fprintf (header_file,
@@ -2385,8 +2394,10 @@ write_type_node (char *tok, bool indent)
{
if (indent)
fprintf (init_file, " ");
- typemap *entry = (typemap *) bsearch (tok, type_map, TYPE_MAP_SIZE,
- sizeof (typemap), typemap_cmp);
+ typemap *entry
+ = (typemap *) bsearch (tok, type_map,
+ sizeof type_map / sizeof type_map[0],
+ sizeof (typemap), typemap_cmp);
if (!entry)
fatal ("Type map is inconsistent.");
fprintf (init_file, "%s_type_node", entry->value);
@@ -2535,6 +2546,8 @@ write_bif_static_init (void)
fprintf (init_file, " | bif_endian_bit");
if (bifp->attrs.isibmld)
fprintf (init_file, " | bif_ibmld_bit");
+ if (bifp->attrs.isibm128)
+ fprintf (init_file, " | bif_ibm128_bit");
fprintf (init_file, ",\n");
fprintf (init_file, " /* restr_opnd */\t{%d, %d, %d},\n",
bifp->proto.restr_opnd[0], bifp->proto.restr_opnd[1],
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 17af314..523256a5 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2444,8 +2444,6 @@ enum rs6000_builtin_type_index
RS6000_BTI_ptr_long_double,
RS6000_BTI_ptr_dfloat64,
RS6000_BTI_ptr_dfloat128,
- RS6000_BTI_ptr_ieee128_float,
- RS6000_BTI_ptr_ibm128_float,
RS6000_BTI_ptr_vector_pair,
RS6000_BTI_ptr_vector_quad,
RS6000_BTI_ptr_long_long,
@@ -2541,8 +2539,6 @@ enum rs6000_builtin_type_index
#define ptr_long_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_double])
#define ptr_dfloat64_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat64])
#define ptr_dfloat128_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128])
-#define ptr_ieee128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ieee128_float])
-#define ptr_ibm128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ibm128_float])
#define ptr_vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair])
#define ptr_vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad])
#define ptr_long_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long])