I have an existing Unix project that I am porting to Windows, this includes a handful of assembler versions. For example:
blake3.c
extern void blake3_compress_xof_sse2(P1, P2, P3, P4, P5, P6);
static void blake3_caller( ... )
{
blake3_compress_xof_sse2(P1, P2, P3, P4, P5, P6);
}
blake3.s
.intel_syntax noprefix
.global zfs_blake3_compress_xof_sse2
.p2align 6
blake3_compress_xof_sse2:
movups xmm0, xmmword ptr [rdi] # P1
...
Because all the .s are from Unix, I've had to convert the argument passing from
Unix: rdi, rsi, rdx, rcx, r8, r9
Windows: rdx, rcx, r8, r9, rsp+0x28, rsp+0x30
(and as well, saving rdi, rsi, xmm6-xmm15)
Then I stumbled across __attribute__((sysv_abi))
.
I would be very neat if I could just tell the compiler to use the Unix parameter order: rdi, rsi, rdx, rcx, r8, r9
So I define the assembler function in C, as:
extern void __attribute__((sysv_abi)) blake3_compress_xof_sse2(P1, P2, P3, P4, P5, P6);
but I am disappointed to see when I dump registers entering blake3_compress_xof_sse2:
P1 is still in rdx
and not as I had hoped, rdi
.
Is there some way to get this to work? It would be very beneficial to not have to tweak all the .s files for Windows. (or have a separate copy of .s files for Windows)
Compile time, I use clang to compile all the source files, .c and .s, into a libkern.a. Then at the end, link a driver.c with MSVC and the libkern.a for the final driver. Oh yeah, this is in kernel mode. But since both blake3.c and blake3.s are inside libkern.a, I would not have thought that should matter.