[fpc-devel] *** GMX Spamverdacht *** Re: Broken frac function in FPC3.1.1 / Windows x86_64

Thorsten Engler thorsten.engler at gmx.net
Sat Apr 28 07:37:09 CEST 2018


I’ve only tested it in Delphi, so you’ll have to convert it to the right syntax for fpc, but either of these should do:

 

function Frac1(const X: Double): Double;

asm

  .align 16

  .noframe

  movq      rdx, xmm0

  shl       rdx, 32

  and       edx, $7FF00000

  cmp       edx, $43300000

  jge      @@zero

  cmp       edx, $3FE00000

  jbe      @@skip

  cvttsd2si rax, xmm0

  cvtsi2sd  xmm4, rax

  subsd     xmm0, xmm4

  jmp      @@skip

@@zero:

  xorpd     xmm0, xmm0

@@skip:

end;

 

function Frac2(const X: Double): Double;

asm

  .align 16

  .noframe

  movq      rdx, xmm0

  shl       rdx, 48

  and       dx, $7FF0

  cmp       dx, $4330

  jge      @@zero

  cmp       dx, $3FE0

  jbe      @@skip

  cvttsd2si rax, xmm0

  cvtsi2sd  xmm4, rax

  subsd     xmm0, xmm4

  jmp      @@skip

@@zero:

  xorpd     xmm0, xmm0

@@skip:

end;

 

 

From: fpc-devel <fpc-devel-bounces at lists.freepascal.org> On Behalf Of Sven Barth via fpc-devel
Sent: Friday, 27 April 2018 23:47
To: FPC developers' list <fpc-devel at lists.freepascal.org>
Cc: Sven Barth <pascaldragon at googlemail.com>
Subject: *** GMX Spamverdacht *** Re: [fpc-devel] Broken frac function in FPC3.1.1 / Windows x86_64

 

Bart <bartjunk64 at gmail.com <mailto:bartjunk64 at gmail.com> > schrieb am Fr., 27. Apr. 2018, 13:42:

On Wed, Apr 25, 2018 at 11:04 AM,  <info at wolfgang-ehrhardt.de <mailto:info at wolfgang-ehrhardt.de> > wrote:

> If you compile and run this 64-bit program on Win 64 you get a crash

And AFAICS your analysis of the cause (see bugtracker) is correct as well.

function fpc_frac_real(d: ValReal) : ValReal;compilerproc; assembler;
nostackframe;
  asm
    cvttsd2si %xmm0,%rax
    { Windows defines %xmm4 and %xmm5 as first non-parameter volatile registers;
      on SYSV systems all are considered as such, so use %xmm4 }
    cvtsi2sd %rax,%xmm4
    subsd %xmm4,%xmm0
  end;

CVTTSD2SI — Convert with Truncation Scalar Double-Precision
Floating-Point Value to Signed Integer
This should not be used to get a ValReal result.

 

The code essentially does the following (instruction by instruction):

 

=== code begin ===

 

tmpi := int64(d - trunc(d));

tmpd := double(tmpi);

Result := d - tmpd;

 

=== code end ===

 

Though why it fails with the given value is a different topic... 

 

Regards, 

Sven 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20180428/0e365004/attachment.html>


More information about the fpc-devel mailing list