GMP patch: MinGW/win64 port

Myria myriachan at
Sat Mar 1 11:03:00 CET 2008

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.

----- Original Message ----- 
From: "Torbjorn Granlund" <tg at>
To: "Wesley W. Terpstra" <wesley at>
Cc: "MLton developers" <mlton at>; <gmp-bugs at>
Sent: Wednesday, February 27, 2008 07:56
Subject: Re: GMP patch: MinGW/win64 port

I apologize for the slow reply to the message below, almost 3 months!

"Wesley W. Terpstra" <wesley at> writes:

  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?

gmp-bugs mailing list
gmp-bugs at 

More information about the gmp-bugs mailing list