← board

Hardware Sqrt on aarch64 and arm32

What landed already, and what this repeats

Sqrt on x86-64 is now:

{$ifdef CPUX86_64}
function Sqrt(x: Double): Double;
var r: Double;
begin
  asm
    movsd  xmm0, x
    sqrtsd xmm0, xmm0
    movsd  r, xmm0
  end;
  Result := r;
end;
{$else}
function Sqrt(x: Double): Double;
begin
  Result := SqrtSoft(x);
end;
{$endif}

Measured on a 3M-call loop: software 575 ms, sqrtsd 18 ms.

aarch64 has fsqrt d0, d0 and arm32 (VFP) has vsqrt.f64 d0, d0. Both are IEEE-mandated correctly-rounded, so this is a pure speed change with no accuracy argument to make — the same one already argued and measured for x86-64.

Why it is worth doing here specifically

Unlike the dynamic-loader work, both targets RUN on this box under qemu-user for a statically linked binary: test/lib_math_correctly_rounded.pas was executed on i386, aarch64 and arm32 that way while fixing the parent ticket, and printed MATHROUND OK on all three. So the change is verifiable where it is written, which is not true of most cross-target work here.

Constraints

Gate

lib_math_correctly_rounded prints MATHROUND OK natively and under qemu on aarch64 and arm32, with the SqrtSoft rows still asserted there; a before/after timing on each; make lib-test green.