I want to hand-write some inline assembly for part of a function but only have that assembly used when compiling for the architecture it's written for, falling back to a generic C implementation on other architectures.
What's the best way to have the compiler use the inline assembly when it's on a matching architecture? Is there a syntax for the asm
block that specifies that it's only for a particular architecture, or should I use the autoconf target triplet in the configure script to define a preprocessor symbol? For example
configure.ac:
case $host in
x86_64-*)
AC_DEFINE([AMD64])
;;
esac
.c source file:
void f() {
#ifdef AMD64
asm (/* ... */)
#else
/* C code */
#endif
}
I suppose for larger or standalone functions the selection of assembly or C could similarly be done with an AM_CONDITIONAL
to select a different source file (.c
or platform-specific .s
).
Are there other options? Is this idiomatic?
Edit: The question is more about whether there are alternatives such as
asm "i386" ( ... )
or
asm "aarch64" ( ... )
or some alternative that doesn't involve preprocessor ifdef
s.
Edit 2: I was looking for the Function Multiversioning feature of GCC where multiple alternative implementations can be provided depending on the specific architecture, and the best version is automatically selected by the linker at runtime. I'll put that in an answer if I'm permitted to reopen the question.
Edit 3: The question applies to both architecture families like x86/amd64/arm64, but also to instruction set architectures (ISAs) like x86-SSE2, amd64-AVX, and so on.