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";
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))
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
{
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);
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);
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;
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
; 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
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.
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. */
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
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:
bool islxvrze;
bool isendian;
bool isibmld;
+ bool isibm128;
};
/* Fields associated with a function prototype (bif or overload). */
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" },
{ "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" },
{ "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" },
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");
"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;
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");
"#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,
{
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);
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],
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,
#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])
--- /dev/null
+/* PR target/99708 */
+/* { dg-do compile } */
+
+#ifdef __SIZEOF_FLOAT128__
+__float128 f = 1.0;
+#endif
+long double l = 1.0;
#define mode_sf float
#define mode_df double
typedef float __attribute__((mode(IF))) mode_if;
+#ifdef __FLOAT128_TYPE__
typedef float __attribute__((mode(KF))) mode_kf;
+#endif
#define mode_sd _Decimal32
#define mode_dd _Decimal64
#define mode_td _Decimal128
--- /dev/null
+/* PR target/99708 */
+/* { dg-do compile } */
+
+#ifdef __SIZEOF_IBM128__
+__ibm128 f = 1.0;
+#endif
+#ifdef __SIZEOF_IEEE128__
+__ieee128 g = 1.0;
+#endif
+long double h = 1.0;
+
+void
+foo (void)
+{
+#ifdef __SIZEOF_IBM128__
+ f += 2.0;
+#endif
+#ifdef __SIZEOF_IEEE128__
+ g += 2.0;
+#endif
+ h += 2.0;
+}