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