diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-03-10 10:22:27 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-03-10 10:22:27 +0100 |
commit | 6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6 (patch) | |
tree | 0358a181a3cc5f644433d25ba05c8d3560d8e81e /gcc/config | |
parent | ff060ef08cfc3e48e70071cb63449b62a86f9d6f (diff) | |
download | gcc-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.cc | 59 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-builtins.def | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-c.cc | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-gen-builtins.cc | 29 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 4 |
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]) |