On ARM64EC, function declarations have additional nuances:
- Function names are mangled by prefixing them with "#"
- An unmangled symbol is defined as a weak anti-dependency alias to the mangled
  symbol
- An entry thunk is generated to convert from the x86_64 calling convention to
  the ARM64EC calling convention, used by the emulator
- A .hybmp section entry is generated to associate the function with its entry
  thunk

The compiler can handle all of this if provided with the necessary information.
Naked functions are the most convenient way to achieve this.

Use naked functions only on Clang. GCC doesn’t support them on ARM targets and
has broken behavior on x86_64 by emitting .seh_endprologue.
---
 mingw-w64-crt/include/internal.h      | 8 ++++++++
 mingw-w64-crt/math/arm64/nearbyint.c  | 7 +++++++
 mingw-w64-crt/math/arm64/nearbyintf.c | 7 +++++++
 mingw-w64-crt/math/arm64/nearbyintl.c | 7 +++++++
 mingw-w64-crt/math/arm64/trunc.c      | 7 +++++++
 mingw-w64-crt/math/arm64/truncf.c     | 7 +++++++
 6 files changed, 43 insertions(+)

diff --git a/mingw-w64-crt/include/internal.h b/mingw-w64-crt/include/internal.h
index b30ae0e5f..445928045 100644
--- a/mingw-w64-crt/include/internal.h
+++ b/mingw-w64-crt/include/internal.h
@@ -287,6 +287,8 @@ static inline unsigned int __mingw_statusfp(void)
     return flags;
 }
 
+#ifndef __clang__
+
 #define __ASM_FUNC_CODE(name,code)  \
     asm(".text\n\t" \
         ".p2align 2\n\t" \
@@ -295,6 +297,12 @@ static inline unsigned int __mingw_statusfp(void)
         __MINGW64_STRINGIFY(__MINGW_USYMBOL(trunc)) ":\n\t"             \
         code "\n\t");
 
+#else
+
+#define __ASM_FUNC_CODE(name,code) asm(code "\n\t");
+
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/mingw-w64-crt/math/arm64/nearbyint.c 
b/mingw-w64-crt/math/arm64/nearbyint.c
index 64ade2750..02e433722 100644
--- a/mingw-w64-crt/math/arm64/nearbyint.c
+++ b/mingw-w64-crt/math/arm64/nearbyint.c
@@ -7,8 +7,15 @@
 #include <math.h>
 #include <internal.h>
 
+#ifdef __clang__
+double __attribute__((naked)) nearbyint(double x)
+{
+#endif
 __ASM_FUNC_CODE(nearbyint,
                 "mrs x1, fpcr\n\t"
                 "frintx d0, d0\n\t"
                 "msr fpcr, x1\n\t"
                 "ret")
+#ifdef __clang__
+}
+#endif
diff --git a/mingw-w64-crt/math/arm64/nearbyintf.c 
b/mingw-w64-crt/math/arm64/nearbyintf.c
index 362f596eb..e87dc9078 100644
--- a/mingw-w64-crt/math/arm64/nearbyintf.c
+++ b/mingw-w64-crt/math/arm64/nearbyintf.c
@@ -7,8 +7,15 @@
 #include <math.h>
 #include <internal.h>
 
+#ifdef __clang__
+float __attribute__((naked)) nearbyintf(float x)
+{
+#endif
 __ASM_FUNC_CODE(nearbyintf,
                 "mrs x1, fpcr\n\t"
                 "frintx s0, s0\n\t"
                 "msr fpcr, x1\n\t"
                 "ret")
+#ifdef __clang__
+}
+#endif
diff --git a/mingw-w64-crt/math/arm64/nearbyintl.c 
b/mingw-w64-crt/math/arm64/nearbyintl.c
index 9e70b1ba4..3ac05a77d 100644
--- a/mingw-w64-crt/math/arm64/nearbyintl.c
+++ b/mingw-w64-crt/math/arm64/nearbyintl.c
@@ -7,8 +7,15 @@
 #include <math.h>
 #include <internal.h>
 
+#ifdef __clang__
+long double __attribute__((naked)) nearbyintl(long double x)
+{
+#endif
 __ASM_FUNC_CODE(nearbyintl,
                 "mrs x1, fpcr\n\t"
                 "frintx d0, d0\n\t"
                 "msr fpcr, x1\n\t"
                 "ret")
+#ifdef __clang__
+}
+#endif
diff --git a/mingw-w64-crt/math/arm64/trunc.c b/mingw-w64-crt/math/arm64/trunc.c
index 672f3aa05..aed0f3a60 100644
--- a/mingw-w64-crt/math/arm64/trunc.c
+++ b/mingw-w64-crt/math/arm64/trunc.c
@@ -7,6 +7,13 @@
 #include <math.h>
 #include <internal.h>
 
+#ifdef __clang__
+double __attribute__((naked)) trunc(double x)
+{
+#endif
 __ASM_FUNC_CODE(trunc,
                 "frintz d0, d0\n\t"
                 "ret")
+#ifdef __clang__
+}
+#endif
diff --git a/mingw-w64-crt/math/arm64/truncf.c 
b/mingw-w64-crt/math/arm64/truncf.c
index cdffb95f5..d3a0fa7d4 100644
--- a/mingw-w64-crt/math/arm64/truncf.c
+++ b/mingw-w64-crt/math/arm64/truncf.c
@@ -7,6 +7,13 @@
 #include <math.h>
 #include <internal.h>
 
+#ifdef __clang__
+float __attribute__((naked)) truncf(float x)
+{
+#endif
 __ASM_FUNC_CODE(truncf,
                 "frintz s0, s0\n\t"
                 "ret")
+#ifdef __clang__
+}
+#endif
-- 
2.48.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to