unit mul_Xsig;

interface

uses fpu_types;

procedure mul32_Xsig (x: PXsig; const ba: u32);
procedure mul64_Xsig (x: PXsig; const b: pu64);
procedure mul_Xsig_Xsig (x: PXsig; const b: PXsig);

implementation

procedure mul32_Xsig (x: PXsig; const ba: u32);
  var
    y:  Xsig;
    zl: u32;
    b, z: u64;
  begin
    b := ba;

    z := b * x^.lsw;
    y.lsw := z shr 32;

    z  := b * x^.midw;
    y.midw := z shr 32;
    zl := z;
    y.lsw := y.lsw + zl;
    if (zl > y.lsw) then
      Inc(y.midw);

    z  := b * x^.msw;
    y.msw := z shr 32;
    zl := z;
    y.midw := y.midw + zl;
    if (zl > y.midw) then
      Inc(y.msw);

    x^ := y;

  end;


procedure mul64_Xsig (x: PXsig; const b: pu64);
  var
    yh, yl: Xsig;
  begin

    yh := x^;
    yl := x^;
    mul32_Xsig(@yh, b^ shr 32);
    mul32_Xsig(@yl, b^);

    x^.msw  := yh.msw;
    x^.midw := yh.midw + yl.msw;
    if (yh.midw > x^.midw) then
      Inc(x^.msw);
    x^.lsw := yh.lsw + yl.midw;
    if (yh.lsw > x^.lsw) then
      begin
      Inc(x^.midw);
      if (x^.midw = 0) then
        Inc(x^.msw);
      end;

  end;


procedure mul_Xsig_Xsig (x: PXsig; const b: PXsig);
  var
    yh: u32;
    y, z: u64;
  begin

    y  := b^.lsw;
    y  := y * x^.msw;
    yh := y shr 32;

    z := b^.msw;
    z := z shl 32;
    z := z + b^.midw;
    mul64_Xsig(x, @z);

    x^.lsw := x^.lsw + yh;
    if (yh > x^.lsw) then
      begin
      Inc(x^.midw);
      if (x^.midw = 0) then
        Inc(x^.msw);
      end;
  end;


end.
