A shame about the title, since most of this advice is also good for x86-64 assembly being portable between Macs and *NIX systems. There’s more you need to if you want portable to include Windows, because the register usage is different on the Windows ABI and because the way of addressing global symbols can be different.
I’m also curious about whether the Apple NEON extensions were upstreamed to clang: can you use them if you use LLVM’s assembler rather than the GNU one?
Not really? The biggest difference I know of is that variadic functions always take their parameters on the stack. Which matters only if calling variadic functions, which doesn’t happen often. Similarly, char is signed, not unsigned, which matters very, very little.
A shame about the title, since most of this advice is also good for x86-64 assembly being portable between Macs and *NIX systems. There’s more you need to if you want portable to include Windows, because the register usage is different on the Windows ABI and because the way of addressing global symbols can be different.
I’m also curious about whether the Apple NEON extensions were upstreamed to clang: can you use them if you use LLVM’s assembler rather than the GNU one?
Yes (do they even actually originate with Apple or have they been in LLVM from the beginning?):
No no no no! clang does not imply Apple, please not like this! >_<
Better might be
#ifdef __APPLE__
.Isn’t the C ABI being materially different on Apple ARM64 platforms vs AArch64 EABI also something that needs to be considered?
Not really? The biggest difference I know of is that variadic functions always take their parameters on the stack. Which matters only if calling variadic functions, which doesn’t happen often. Similarly, char is signed, not unsigned, which matters very, very little.
“Portable” and “assembly language” are not two terms I would expect to see together.