The ABI for Win64 is much more complicated than just the register allocation
scheme. Win64 mandates that function metadata be present within the
compiled executable so that the "structured exception handlng" (SEH) system
can unwind the stack without executing explicit unwind code. This design is
very different from x86-32 Windows. A function requires markup specifying
where nonvolatile registers are located on the stack.
The alternate exception handler design trades memory for runtime performance
and higher resistance to stack-smashing attacks.
There are also a lot of related rules, such as that you can't modify rsp in
the middle of a function unless you are using a frame pointer, which must be
declared in the metadata. There are also strict rules about which
instructions are allowed in the prolog and epilog of a function - this is
because there is a miniature x86-64 interpreter used during exception
Brian Gladman ported the x86-64 assembly code to Windows for Visual Studio,
but I don't remember whether he added the function markup.
With the small attached patch, GMP compiles on MinGW/win64 using the
latest cross compiler. The patch fixes the assumption that 'long = 64
bits' on all intel 64 bit platforms. Under win64, long remains 32 bit
< pointer size. Also, the ABI for windows differs from linux, so the
patch disables linux-specific assembly, using the generic C instead.
It is a pity to have to disable assembly. Do you understand
the relevant differences?
Changing parameter registers is needed, I have understood.
rdi => rcx
rsi => rdx
rdx => r8
rcx => r9
Perhaps you could try this for one file, say mpn/x86_64/addmul_1.asm
to see of you can make it work. (I could then do some m4 trickery to
make that mapping happen automatically.)
One way of testing it would be to simply insert these lines at the
start of the function:
mov rdx, r8
mov rcx, r9
mov rdi, rcx
mov rsi, rdx
To test your change, move all the other mpn/x86_64/* files so that
configure does not find them. To test your addmul_1.asm, use
"tests/devel/try mpn_addmul_1" (you need to compile try.c first, of
course). Please remember to undo your setting of path_64!
It is necessary to use 'malloc-reentrant' to forbid use of alloca,
which appears to be broken under win64.
Is this something particular to GMP, or does alloca fail to work
properly also for other programs?
make check succeeds except for the tests t-locale and t-printf.
t-locale fails to compile because it tries to replace an imported
function with a local copy of localeconv. Probably GMP shouldn't do
Perhaps not. I din't write that code, and will wait for contributions
about how to handle this.
t-printf fails because the win64 printf ignores the high 32 bits of
Can the dos64 printf print 'long long' arguments at all?
I am troubled by your tests/amd64check.c change, since it
unconditionally changes the constants to 'long long'. Not all
compilers might have that type. Could you please try using the
CNST_LIMB mechanism instead?