On Mon, Sep 08, 2025 at 07:44:39PM +0200, Jakub Jelinek wrote:
> On Mon, Sep 08, 2025 at 06:14:06PM +0200, Jakub Jelinek wrote:
> > Yet another option would be keep doing what we were doing unless
> > GET_MODE_PRECISION is 80, in which case deal with the 2 variants based on
> > signbit_ro value.
> 
> Here it is, tested on all of x86_64-linux (-m32/-m64), m68k-linux cross
> (-mc68020) and x86_64-freebsd13.0 (-m32/-m64).
> 
> Ok for trunk if it passes full bootstrap/regtest?

Here is a new version, the only difference is abi_version_at_least
change to abi_check, so that we emit the mangling aliases for now (they
can be emitted just fine because the mangling included mangled type
(e) plus previously were always 4 or 12 hex digits longer, so it can't
clash with other long double literals or _Float128/__float128 literals
in the mangled names.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-09-10  Jakub Jelinek  <ja...@redhat.com>

        * mangle.cc (write_real_cst): Mangle Intel/Motorola extended
        80-bit formats using 20 hex digits instead of 24 or 32.

        * g++.target/i386/mangle-ldbl-1.C: New test.
        * g++.target/i386/mangle-ldbl-2.C: New test.

--- gcc/cp/mangle.cc.jj 2025-09-02 17:02:44.128176211 +0200
+++ gcc/cp/mangle.cc    2025-09-09 09:43:09.422358069 +0200
@@ -2190,6 +2190,29 @@ write_real_cst (const tree value)
   else
     i = words - 1, limit = -1, dir = -1;
 
+  if (GET_MODE_PRECISION (SCALAR_FLOAT_TYPE_MODE (type)) == 80
+      && abi_check (21))
+    {
+      /* For -fabi-version=21 and above mangle
+        Intel/Motorola extended format 1.0L as
+        3fff8000000000000000
+        rather than the previous
+        0000000000003fff8000000000000000 (x86_64)
+        00003fff8000000000000000 (ia32)
+        3fff00008000000000000000 (m68k -mc68020)
+        i.e. without any embedded padding bits.  */
+      if (words == 4)
+       i += dir;
+      else
+       gcc_assert (words == 3);
+      unsigned long val = (unsigned long) target_real[i];
+      if (REAL_MODE_FORMAT (SCALAR_FLOAT_TYPE_MODE (type))->signbit_ro == 95)
+       val >>= 16;
+      sprintf (buffer, "%04lx", val);
+      write_chars (buffer, 4);
+      i += dir;
+    }
+
   for (; i != limit; i += dir)
     {
       sprintf (buffer, "%08lx", (unsigned long) target_real[i]);
--- gcc/testsuite/g++.target/i386/mangle-ldbl-1.C.jj    2025-09-08 
19:34:51.143198289 +0200
+++ gcc/testsuite/g++.target/i386/mangle-ldbl-1.C       2025-09-08 
19:36:17.033063950 +0200
@@ -0,0 +1,8 @@
+// { dg-do compile { target { c++20 && { x86_64-*-linux* i?86-*-linux* } } } }
+// { dg-final { scan-assembler "_Z3fooILe3fff8000000000000000EEiv" } }
+// { dg-final { scan-assembler "_Z3fooILe40008000000000000000EEiv" } }
+
+template <long double a>
+int foo () { return 0; }
+
+int bar () { return foo <1.0L> () + foo <2.0L> (); }
--- gcc/testsuite/g++.target/i386/mangle-ldbl-2.C.jj    2025-09-08 
19:36:24.505965257 +0200
+++ gcc/testsuite/g++.target/i386/mangle-ldbl-2.C       2025-09-08 
19:38:56.977951557 +0200
@@ -0,0 +1,11 @@
+// { dg-do compile { target { c++20 && { x86_64-*-linux* i?86-*-linux* } } } }
+// { dg-additional-options "-fabi-version=20" }
+// { dg-final { scan-assembler "_Z3fooILe0000000000003fff8000000000000000EEiv" 
{ target { ! ia32 } } } }
+// { dg-final { scan-assembler "_Z3fooILe00000000000040008000000000000000EEiv" 
{ target { ! ia32 } } } }
+// { dg-final { scan-assembler "_Z3fooILe00003fff8000000000000000EEiv" { 
target ia32 } } }
+// { dg-final { scan-assembler "_Z3fooILe000040008000000000000000EEiv" { 
target ia32 } } }
+
+template <long double a>
+int foo () { return 0; }
+
+int bar () { return foo <1.0L> () + foo <2.0L> (); }


        Jakub

Reply via email to