Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2018-04

Re: Broken frac functionin FPC3.1.1 / Windows x86_64

3 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J. Gareth Moreton

That's great to hear! Glad to help.

For functions with no stack frame, the
compiler simply puts RET at the very end
of the routine and is all that's needed.
For functions with a stack frame, either
LEAVE or MOV RSP, RBP; POP RBP must
precede it. The optional parameter after
RET is the number of bytes allocated to
the stack by parameters that aren't in
registers.

So what happens now? Do we submit a patch?

Gareth aka. Kit

Reply by email

Thorsten Engler
to J. Gareth Moreton
Show quoted text 5 lines
From: fpc-devel On Behalf Of J. Gareth Moreton For functions with a stack frame, either LEAVE or MOV RSP, RBP; POP RBP must precede it.

It's not quite that simple, at least under windows: https://docs.microsoft.com/en-us/cpp/build/prolog-and-epilog

But yes, this documents that there can be multiple epilogues, so the additional ret would be fine in this regard.

Following this exact format is required so that the stack unwinder during processing of SEH (structured exception handling) which is performed by the OS can correctly restore the value of non-volatile registers that has been saved on the stack.

Fortunately, as our function in this case doesn't use the stack at all and doesn't contain calls to other functions, this can be skipped.

So what happens now? Do we submit a patch?

I think Sven Barth was going to fix this up anyway?

Cheers,
Thorsten

Reply by email

J. Gareth Moreton

Hi Florian.  Thorsten and I got down to a fairly optimised version of Frac, in both speed and size:

****

function Frac(const X: ValReal): ValReal; assembler; nostackframe; asm
  movq      rax,  xmm0
  shr       rax,  48
  and       ax,   $7FF0
  cmp       ax,   $4330
  jge       @@zero
  cvttsd2si rax,  xmm0
  cvtsi2sd  xmm4, rax
  subsd     xmm0, xmm4
  ret
@@zero:
  xorpd     xmm0, xmm0
end;

****

It fits into just three 16-byte blocks and is the fastest overall from our tests, although there's a slight penalty if it jumps to @@zero that seems to be architecture-dependent (e.g. it slows down for me, but Thorsten didn't see much). Aligning @@zero to a 16-byte boundary may fix this for some, but it doesn't for me.  Oh the joy of processor intracacies!

Gareth aka. Kit.

On Sun 29/04/18 19:28 , Florian Klaempfl sent:

Thorsten Engler wrote 14 lines
> -----Original Message----- > From: fpc-devel On Behalf > Of Florian Klämpfl > So something like > > cmp edx, $43300000 > jge @@zero > cmp edx, $3FE00000 > .align 16 > jbe @@skip > > might be much better. That ended up making things worse in some cases.

Can you take a look at the generated machine code if delphi uses proper multi byte nops. If not, the align might make things indeed worse.

Reply by email