On Tue, 1 Apr 2025, Jacek Caban wrote:

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

Does this hold for GCC on e.g. aarch64 linux as well, or do you mean the in-progress aarch64-mingw target?

and has broken behavior on x86_64 by emitting .seh_endprologue.

Right, that probably disqualifies using it overall.


Regarding me not liking global scope asm function definitions; I'm ambivalent about whether I like naked functions more or less than global scope asm. Using naked functions is better in the sense that it is clear on a C level what the functions are. But it's also an even more obscure feature which is even more of a tricky case to use - as noted by your observations about which compilers support it above.

Anyway, again this was just a note for the record; I do agree that it's reasonable to use the feature here for arm64ec.

Before proceeding with this direction, I'd like to get a grasp of how many functions this change will cover. I'd guess that essentially any arm64 function in a .S file will need to be wrapped in this form, at least if we want to be able to call them from x86_64 code? Is this the case for only these couple of fucntions covered in this series, or will there be dozens of similar functions converted afterwards?

---
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,

This ifdeffery feels quite ugly TBH. Ideally I wouldn't want to have any such ifdefs within the implementation files. Is there any way that we hide these details inside the macro?

Then we'd need to pass the function signature through the macro, which is tricky, especially for the function arguments.

But I have a faint memory that it may be possible to pass such things within parentheses, e.g. we could do __ASM_FUNC_CODE(pow, double, (double x, double y), "<code>").

If I'm mistaken, then it's indeed more tricky, but perhaps we could at least make a version for functions that take one argument and returns the same type?

// Martin

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

Reply via email to