Hi!

As mentioned in the PR, we emit the same
        .uleb128 0x3     # (DIE (0x42) DW_TAG_base_type)
        .byte   0x10     # DW_AT_byte_size
        .byte   0x4      # DW_AT_encoding
        .4byte  .LASF2   # DW_AT_name: "long double"
(0x4 is DW_ATE_float) whether we on powerpc64le-linux use
-mabi=ibmlongdouble or -mabi=ieeelongdouble.
http://lists.dwarfstd.org/pipermail/dwarf-discuss-dwarfstd.org/2022-January/004859.html
lists some options how to handle that and Ulrich mentioned it in his
Cauldron talk too:
https://slideslive.com/38902369/precise-target-floatingpoint-emulation-in-gdb?ref=account-folder-9307-folders
pages 8-16.

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.

Bootstrap/regtest pending on powerpc64le-linux (both defaulting to
ibmlongdouble and ieeelongdouble), ok for trunk if it passes?

2022-01-24  Jakub Jelinek  <ja...@redhat.com>

        PR debug/104194
        * dwarf2.def (DW_ATE_GNU_float128, DW_ATE_GNU_complex_float128): New
        DW_AT_encoding values.

        * dwarf2out.c (base_type_die): Use DW_ATE_GNU_float128 instead of
        DW_ATE_float for 16-byte non-composite mode if target supports also
        composite modes.  Similarly use DW_AT_GNU_complex_float128 instead
        of DW_ATE_complex_float for 32-byte complex mode with non-composite
        inner mode if target supports also composite modes.

--- 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;

        Jakub

Reply via email to