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? 2025-09-08 Jakub Jelinek <[email protected]> * 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-08 19:29:46.176227000 +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_version_at_least (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
