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      | 15 ++++++++++++++-
 mingw-w64-crt/math/arm64/nearbyint.c  |  2 +-
 mingw-w64-crt/math/arm64/nearbyintf.c |  2 +-
 mingw-w64-crt/math/arm64/nearbyintl.c |  2 +-
 mingw-w64-crt/math/arm64/trunc.c      |  2 +-
 mingw-w64-crt/math/arm64/truncf.c     |  2 +-
 6 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/mingw-w64-crt/include/internal.h b/mingw-w64-crt/include/internal.h
index 0d75d63e3..0c0106ab2 100644
--- a/mingw-w64-crt/include/internal.h
+++ b/mingw-w64-crt/include/internal.h
@@ -287,7 +287,11 @@ static inline unsigned int __mingw_statusfp(void)
     return flags;
 }
 
-#define __ASM_NAKED_FUNC(name,code)  \
+/* 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. */
+#ifndef __clang__
+
+#define __ASM_NAKED_FUNC(name, rettype, args, code) \
     asm(".text\n\t" \
         ".p2align 2\n\t" \
         ".globl " __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) "\n\t" \
@@ -295,6 +299,15 @@ static inline unsigned int __mingw_statusfp(void)
         __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) ":\n\t" \
         code "\n\t");
 
+#else
+
+#define __ASM_NAKED_FUNC(name, rettype, args, code) \
+    rettype __attribute__((naked)) name args { \
+        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 44c74cf71..091d374f1 100644
--- a/mingw-w64-crt/math/arm64/nearbyint.c
+++ b/mingw-w64-crt/math/arm64/nearbyint.c
@@ -7,7 +7,7 @@
 #include <math.h>
 #include <internal.h>
 
-__ASM_NAKED_FUNC(nearbyint,
+__ASM_NAKED_FUNC(nearbyint, double, (double x),
                  "mrs x1, fpcr\n\t"
                  "frintx d0, d0\n\t"
                  "msr fpcr, x1\n\t"
diff --git a/mingw-w64-crt/math/arm64/nearbyintf.c 
b/mingw-w64-crt/math/arm64/nearbyintf.c
index 48d587343..5faab998b 100644
--- a/mingw-w64-crt/math/arm64/nearbyintf.c
+++ b/mingw-w64-crt/math/arm64/nearbyintf.c
@@ -7,7 +7,7 @@
 #include <math.h>
 #include <internal.h>
 
-__ASM_NAKED_FUNC(nearbyintf,
+__ASM_NAKED_FUNC(nearbyintf, float, (float x),
                  "mrs x1, fpcr\n\t"
                  "frintx s0, s0\n\t"
                  "msr fpcr, x1\n\t"
diff --git a/mingw-w64-crt/math/arm64/nearbyintl.c 
b/mingw-w64-crt/math/arm64/nearbyintl.c
index 72e912c43..5090fb5ef 100644
--- a/mingw-w64-crt/math/arm64/nearbyintl.c
+++ b/mingw-w64-crt/math/arm64/nearbyintl.c
@@ -7,7 +7,7 @@
 #include <math.h>
 #include <internal.h>
 
-__ASM_NAKED_FUNC(nearbyintl,
+__ASM_NAKED_FUNC(nearbyintl, long double, (long double x),
                  "mrs x1, fpcr\n\t"
                  "frintx d0, d0\n\t"
                  "msr fpcr, x1\n\t"
diff --git a/mingw-w64-crt/math/arm64/trunc.c b/mingw-w64-crt/math/arm64/trunc.c
index 0054b87e0..a1923618b 100644
--- a/mingw-w64-crt/math/arm64/trunc.c
+++ b/mingw-w64-crt/math/arm64/trunc.c
@@ -7,6 +7,6 @@
 #include <math.h>
 #include <internal.h>
 
-__ASM_NAKED_FUNC(trunc,
+__ASM_NAKED_FUNC(trunc, double, (double x),
                  "frintz d0, d0\n\t"
                  "ret")
diff --git a/mingw-w64-crt/math/arm64/truncf.c 
b/mingw-w64-crt/math/arm64/truncf.c
index f32215097..bc6ede45a 100644
--- a/mingw-w64-crt/math/arm64/truncf.c
+++ b/mingw-w64-crt/math/arm64/truncf.c
@@ -7,6 +7,6 @@
 #include <math.h>
 #include <internal.h>
 
-__ASM_NAKED_FUNC(truncf,
+__ASM_NAKED_FUNC(truncf, float, (float x),
                  "frintz s0, s0\n\t"
                  "ret")
-- 
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