Part of initial Arm64EC patchset.
On Arm64EC targets, all indirect calls must first check whether the callee is ARM64 or x64 code. If the callee is ARM64 code, the pointer is directly called; if the callee is x64, it goes through a function to translate the calling convention from ARM64 to x64.
If CFG is enabled, this check is integrated with the CFG check: the call also checks whether the pointer points to a valid target.
The translation of calling conventions is done late; as far as I can tell, the way clang normally translates function types to LLVM IR leaves enough information to do this correctly. (If it turns out some case doesn't work, we should be able to bridge the gap using attributes.) I was originally thinking about generating thunks in clang, but there are complications: we'd need to staple the thunk to the call using a bundle, and calls generated by the optimizer wouldn't have access to whatever code clang used.