Message ID | 20220124193439.GV2646553@tucnak |
---|---|
State | New |
Headers | show |
Series | dwarf2out: For ppc64le IEEE quad long double, use DW_ATE_GNU_*float128 [PR104194] | expand |
Hi, On Mon, Jan 24, 2022 at 08:34:39PM +0100, Jakub Jelinek wrote: > The following patch uses DW_ATE_GNU_{,complex_}float128 (new extensions > equal to corresponding HP extensions) instead of DW_ATE_float, > another possibility would be DW_ATE_GNU_precision attribute on the > DW_TAG_base_type that would for these multiple 16-byte float cases > (or always) emit a precision (113 for binary128, 106 for double double), > yet another one is what Ulrich mentions in his slides > (DW_AT_GNU_encoding_variant {0,1}). > > I didn't get any responses to my dwarf discuss mails yet, on IRC > Jason preferred a DW_AT_encoding change while Mark prefered > DW_AT_GNU_precision. In any case, all of these are just GNU extensions, > if/when DWARF standardizes something else, we can use it for -gdwarf-6 > or later. When we try to standardize this (in DWARF6) then I think I prefer having a separate attribute which specifies the precision, just like we already use DW_AT_byte_size to specify the size. That might also help with the different float16 encodings. But if we need a solution now (for gcc12) then using a new DW_ATE_GNU extension seems more practical. Cheers, Mark
On Mon, Jan 24, 2022 at 11:14:41PM +0100, Mark Wielaard wrote: > On Mon, Jan 24, 2022 at 08:34:39PM +0100, Jakub Jelinek wrote: > > The following patch uses DW_ATE_GNU_{,complex_}float128 (new extensions > > equal to corresponding HP extensions) instead of DW_ATE_float, > > another possibility would be DW_ATE_GNU_precision attribute on the > > DW_TAG_base_type that would for these multiple 16-byte float cases > > (or always) emit a precision (113 for binary128, 106 for double double), > > yet another one is what Ulrich mentions in his slides > > (DW_AT_GNU_encoding_variant {0,1}). > > > > I didn't get any responses to my dwarf discuss mails yet, on IRC > > Jason preferred a DW_AT_encoding change while Mark prefered > > DW_AT_GNU_precision. In any case, all of these are just GNU extensions, > > if/when DWARF standardizes something else, we can use it for -gdwarf-6 > > or later. > > When we try to standardize this (in DWARF6) then I think I prefer > having a separate attribute which specifies the precision, just like > we already use DW_AT_byte_size to specify the size. That might also > help with the different float16 encodings. > > But if we need a solution now (for gcc12) then using a new DW_ATE_GNU > extension seems more practical. Actually for debuggers, DW_AT_GNU_precision might be better. I think debuggers will just give up on unknown DW_ATE_*, they really don't know how to handle it. While if they see an unknown attribute on the base type, I'd think they'd ignore it, so treat the IEEE quad "long double" as IBM double double instead, but e.g. for __float128 or __ibm128 would be using the DW_AT_name heuristics handled fine. Yet another short term solution might be not use DW_TAG_base_type for the IEEE quad long double, but instead pretend it is a DW_TAG_typedef with DW_AT_name "long double" to __float128 DW_TAG_base_type. I bet gdb would even handle it without any changes, but of course, it would be larger than the other proposed changes. Jakub
--- include/dwarf2.def.jj 2022-01-11 23:11:23.593273249 +0100 +++ include/dwarf2.def 2022-01-24 17:46:08.699138085 +0100 @@ -732,11 +732,20 @@ DW_ATE (DW_ATE_ASCII, 0x12) DW_ATE_DUP (DW_ATE_lo_user, 0x80) DW_ATE_DUP (DW_ATE_hi_user, 0xff) +/* GNU extensions. */ +DW_ATE (DW_ATE_GNU_float128, 0x82) /* Floating-point (IEEE quad precision if + there are multiple 16-byte floating + formats). */ +DW_ATE (DW_ATE_GNU_complex_float128, 0x83) /* Complex fp + (IEEE quad precision if there + are multiple 16-byte floating + formats). */ + /* HP extensions. */ DW_ATE (DW_ATE_HP_float80, 0x80) /* Floating-point (80 bit). */ DW_ATE (DW_ATE_HP_complex_float80, 0x81) /* Complex floating-point (80 bit). */ -DW_ATE (DW_ATE_HP_float128, 0x82) /* Floating-point (128 bit). */ -DW_ATE (DW_ATE_HP_complex_float128, 0x83) /* Complex fp (128 bit). */ +DW_ATE_DUP (DW_ATE_HP_float128, 0x82) /* Floating-point (128 bit). */ +DW_ATE_DUP (DW_ATE_HP_complex_float128, 0x83) /* Complex fp (128 bit). */ DW_ATE (DW_ATE_HP_floathpintel, 0x84) /* Floating-point (82 bit IA64). */ DW_ATE (DW_ATE_HP_imaginary_float80, 0x85) DW_ATE (DW_ATE_HP_imaginary_float128, 0x86) --- gcc/dwarf2out.cc.jj 2022-01-20 11:58:12.632304188 +0100 +++ gcc/dwarf2out.cc 2022-01-24 18:27:12.862642858 +0100 @@ -13260,7 +13260,23 @@ base_type_die (tree type, bool reverse) encoding = DW_ATE_lo_user; } else - encoding = DW_ATE_float; + { + encoding = DW_ATE_float; + + /* On targets like PowerPC which support both + a double double 16-byte floating mode + (MODE_COMPOSITE_P) and some other 16-byte + floating mode (IEEE quad precision), use + DW_ATE_GNU_float128 instead of DW_ATE_float + for the latter. */ + machine_mode mode; + if (known_eq (GET_MODE_SIZE (TYPE_MODE (type)), 16) + && !MODE_COMPOSITE_P (TYPE_MODE (type))) + FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) + if (known_eq (GET_MODE_SIZE (mode), 16) + && MODE_COMPOSITE_P (mode)) + encoding = DW_ATE_GNU_float128; + } break; case FIXED_POINT_TYPE: @@ -13276,7 +13292,23 @@ base_type_die (tree type, bool reverse) a user defined type for it. */ case COMPLEX_TYPE: if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) - encoding = DW_ATE_complex_float; + { + encoding = DW_ATE_complex_float; + + /* On targets like PowerPC which support both + a double double 16-byte floating mode + (MODE_COMPOSITE_P) and some other 16-byte + floating mode (IEEE quad precision), use + DW_ATE_GNU_complex_float128 instead of + DW_ATE_float for the latter. */ + machine_mode mode; + if (known_eq (GET_MODE_SIZE (TYPE_MODE (type)), 32) + && !MODE_COMPOSITE_P (TYPE_MODE (TREE_TYPE (type)))) + FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) + if (known_eq (GET_MODE_SIZE (mode), 16) + && MODE_COMPOSITE_P (mode)) + encoding = DW_ATE_GNU_complex_float128; + } else encoding = DW_ATE_lo_user; break;