If I may add a possible solution, would code akin to the following fix the problems? (Pray that the mail list formatting doesn't mess it all up!)
---- {$WARN 7121 off : Check size of memory operand "$1: memory-operand-size is $2 bits, but expected [$3 bits]"} {$ASMMODE Intel} const MAX_DOUBLE_WITH_FRAC: Double = 4503599627370496; SIGN_MASK: QWord = $7FFFFFFFFFFFFFFF; function SafeFrac(X: ValReal): ValReal; assembler; nostackframe; asm MOVSD XMM5, [RIP+SIGN_MASK] MOVSD XMM4, XMM0 ANDPD XMM4, XMM5 { Remove sign bit } COMISD XMM4, [RIP+MAX_DOUBLE_WITH_FRAC] { If less than, then ZF = 0, PF = 0 and CF = 1} JNC @IsZero { If carry flag is clear, the absolute value is too large to contain a fractional component (and potentially too large to fit into RAX) } CVTTSD2SI RAX, XMM0 CVTSI2SD XMM4, RAX SUBPD XMM0, XMM4 RET @IsZero: XORPD XMM0, XMM0 end; ---- The first MOVSD could be removed and simply be merged with ANDPD to save on a register, but I wrote it this way to take advantage of instruction prefetching and offer a slight speed boost. There is one minor functional change though... when testing this function, I discovered that if you try to pass infinity or minus infinity, the result is zero, whereas currently with Frac, it triggers SIGFPE. Gareth aka. Kit
_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel