On Fri, Oct 31, 2025 at 3:53 PM Mark Harmstone <[email protected]> wrote:
>
> Windows differs slightly from the standard aarch64 ABI in that
> sizeof(long double) == sizeof(double),[0] which is followed on MSVC and
> Clang but not GCC:
>
> $ cat ld.c
> static_assert(sizeof(long double) == sizeof(double));
>
> $ /opt/msvc/bin/arm64/cl.exe /c /nologo ld.c
> ld.c
>
> $ clang -target aarch64-w64-mingw32 -std=c23 -c ld.c
>
> $ aarch64-w64-mingw32-gcc -c ld.c
> ld.c:1:1: error: static assertion failed
> 1 | static_assert(sizeof(long double) == sizeof(double));
>
> The biggest casualty of this is mingw64-runtime, which assumes that if
> these types are different sizes it needs to do x87 emulation. As this
> package is essential to compile pretty much anything, it's safe to say that
> nobody is yet using aarch64-w64-mingw32 in earnest and this change won't
> break anybody's workflow.
>
> Change long double so that it is DFmode rather than TFmode, and disable
> the soft-fp code that's now broken due to the lack of a TFmode type.
>
> [0] https://learn.microsoft.com/en-us/cpp/c-language/type-long-double
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64.cc (aarch64_c_mode_for_floating_type): Set
> long double to DFmode if LONG_DOUBLE_IS_64BIT set.
> * config/aarch64/cygming.h (LONG_DOUBLE_IS_64_BIT): Define.
>
> libgcc/ChangeLog:
>
> * config.host: Replace aarch64/t-softfp with aarch64/t-softfp-mingw
> for mingw.
> * config/aarch64/t-soft-mingw: New file.
> ---
> gcc/config/aarch64/aarch64.cc | 8 +++++++-
> gcc/config/aarch64/cygming.h | 2 ++
> libgcc/config.host | 2 +-
> libgcc/config/aarch64/t-softfp-mingw | 12 ++++++++++++
> 4 files changed, 22 insertions(+), 2 deletions(-)
> create mode 100644 libgcc/config/aarch64/t-softfp-mingw
>
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 6f6dea67e0d..1b872564c0c 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -29700,7 +29700,13 @@ static machine_mode
> aarch64_c_mode_for_floating_type (enum tree_index ti)
> {
> if (ti == TI_LONG_DOUBLE_TYPE)
> - return TFmode;
> + {
> +#ifdef LONG_DOUBLE_IS_64BIT
> + return DFmode;
> +#else
> + return TFmode;
> +#endif
I think the following is better which is more in line with the rest of
GCC target defines:
```
#ifndef LONG_DOUBLE_128BIT
#define LONG_DOUBLE_128BIT 1
#endif
return LONG_DOUBLE_128BIT ? TFmode : DFmode;
```
> + }
> return default_mode_for_floating_type (ti);
> }
>
> diff --git a/gcc/config/aarch64/cygming.h b/gcc/config/aarch64/cygming.h
> index 7e2203c3e92..efa1a0c62b6 100644
> --- a/gcc/config/aarch64/cygming.h
> +++ b/gcc/config/aarch64/cygming.h
> @@ -136,6 +136,8 @@ still needed for compilation. */
> #undef LONG_TYPE_SIZE
> #define LONG_TYPE_SIZE 32
>
> +#define LONG_DOUBLE_IS_64BIT
And then here:
```
#undef LONG_DOUBLE_128BIT
#define LONG_DOUBLE_128BIT 0
```
> +
> #undef DEFAULT_SIGNED_CHAR
> #define DEFAULT_SIGNED_CHAR 1
>
> diff --git a/libgcc/config.host b/libgcc/config.host
> index 82ea1772f51..3c89ffe586d 100644
> --- a/libgcc/config.host
> +++ b/libgcc/config.host
> @@ -468,7 +468,7 @@ aarch64-*-mingw*)
> tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
> tmake_file="${tmake_file} ${cpu_type}/t-mingw"
> tmake_file="${tmake_file} ${cpu_type}/t-lse"
> - tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm"
> + tmake_file="${tmake_file} ${cpu_type}/t-softfp-mingw t-softfp t-crtfm"
I suspect you still need TF mode for soft-float to emulate _Float128.
Is there a reason why you need a special target makefile for mingw
here?
Or is _Float128 just not supported on aarch64 mingw? Or you didn't
know that _Float128 existed and was supported in GCC?
Thanks,
Andrew
> ;;
> alpha*-*-linux*)
> tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee t-crtfm
> alpha/t-linux"
> diff --git a/libgcc/config/aarch64/t-softfp-mingw
> b/libgcc/config/aarch64/t-softfp-mingw
> new file mode 100644
> index 00000000000..143486b2774
> --- /dev/null
> +++ b/libgcc/config/aarch64/t-softfp-mingw
> @@ -0,0 +1,12 @@
> +softfp_int_modes := si di ti
> +softfp_extensions := bfsf
> +softfp_truncations := dfbf sfbf hfbf
> +softfp_exclude_libgcc2 := n
> +softfp_extras += fixhfti fixunshfti floattihf floatuntihf \
> + floatdibf floatundibf floattibf floatuntibf \
> + floatbitinthf floatbitintbf
> +
> +TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes
> +
> +LIB2ADD += $(srcdir)/config/aarch64/sfp-exceptions.c
> +SHLIB_MAPFILES += $(srcdir)/config/aarch64/libgcc-softfp.ver
> --
> 2.51.0
>