Support for w*ndows

Niels Möller nisse at lysator.liu.se
Sat Nov 26 22:16:18 CET 2011


Torbjorn Granlund <tg at gmplib.org> writes:

> How exactly does W64_ENTRY look like?  (I suppose W64_EXIT is tiny.)

It looks like this. Note that I use <,> as quote characters, which
causes some difficulties since this macro uses relational operators with
m4 eval. I guess it would be possible to make it smaller using some m4
loop construct, but I'm not sure that would make it more readable.

dnl W64_ENTRY(nargs, xmm_used)
define(<W64_ENTRY>, <
  changequote([,])dnl
  ifelse(<<<<<<<<<<<<<<< ignored; only for balancing)
  ifelse(W64_ABI,yes,[
    ifelse(eval($2 > 6), 1, [
      sub	   [$]eval(8 + 16*($2 - 6)), %rsp
      movdqa	   %xmm6, 0(%rsp)
    ])
    ifelse(eval($2 > 7), 1, [
      movdqa	   %xmm7, 16(%rsp)
    ])
    ifelse(eval($2 > 8), 1, [
      movdqa	   %xmm8, 32(%rsp)
    ])
    ifelse(eval($2 > 9), 1, [
      movdqa	   %xmm9, 48(%rsp)
    ])
    ifelse(eval($2 > 10), 1, [
      movdqa	   %xmm10, 64(%rsp)
    ])
    ifelse(eval($2 > 11), 1, [
      movdqa	   %xmm11, 80(%rsp)
    ])
    ifelse(eval($2 > 12), 1, [
      movdqa	   %xmm12, 96(%rsp)
    ])
    ifelse(eval($2 > 13), 1, [
      movdqa	   %xmm13, 112(%rsp)
    ])
    ifelse(eval($2 > 14), 1, [
      movdqa	   %xmm14, 128(%rsp)
    ])
    ifelse(eval($2 > 15), 1, [
      movdqa	   %xmm15, 144(%rsp)
    ])
    ifelse(eval($1 >= 1), 1, [
      push	   %rdi
      mov	   %rcx, %rdi
    ])
    ifelse(eval($1 >= 2), 1, [
      push	   %rsi
      mov	   %rdx, %rsi
    ])
    ifelse(eval($1 >= 3), 1, [
      mov	   %r8, %rdx
    ])
    ifelse(eval($1 >= 4), 1, [
      mov	   %r9, %rcx
    ])
    ifelse(eval($1 >= 5), 1, [
      mov	   56(%rsp), %r8
    ])
  ])
  changequote(<,>)dnl
>)

And then W64_EXIT takes the same arguments, and restores the callee-save
registers and the stack.

> While this idea is appealing, I worry that the overhead might hurt
> "small bignum" performance, compared to even the C code.

Probably not an issue for nettle, since all assembly functions (with the
possible exceptions of memxor and rc4 with small arguments) do quite a
lot of work. I wanted to get something non-intrusive working, and I
don't care much if w64 gets a small penalty in overhead.

> Have you considered I more sophisticated approach with renaming
> registers?

I'm sure it could be optimized.

I usually use symbolic names for all registers. Martin's first shot at
w64 support had alternative register allocation done individually for
each file, which is possible but less maintainable.

> There will be one remaining compatibility issue: Intel syntax vs MIT
> assembly syntax.  While cygwin and mingw have no problems with the MIT
> syntax, M$'s assembler almost surely does.

I wouldn't give a high priority to supporting M$ assembler. If it's easy
to build with mingw, either natively on w*ndows, or as a cross compiler
on a unix host, I think that's good enough.

> The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile
> and must be considered destroyed on function calls.

And %xmm0 - %xmm5.
 
> The registers RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered
> nonvolatile and must be saved and restored by a function that uses them.

And %xmm6 - %xmm15.

/nisse

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list