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
>

Reply via email to