--
--	Inmos Libraries
--	Copyright (C) 1988, 1989, 1990, 1991, 1993  Inmos Limited
--
--	This library is free software; you can redistribute it and/or
--	modify it under the terms of the GNU Lesser General Public
--	License as published by the Free Software Foundation; either
--	version 2 of the License, or (at your option) any later version.
--
--	This library is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--	Lesser General Public License for more details.
--
--	You should have received a copy of the GNU Lesser General Public
--	License along with this library; if not, write to the Free Software
--	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
--

--** @module forall

--{{{  #options and #comments
#OPTION "E V"  -- no compiler libs, no vector space
#COMMENT "T8 compiler library, V1.4 10/07/90"
#COMMENT "(c) Copyright INMOS Limited 1988"
--}}}

#PRAGMA TRANSLATE DNEXTAFTER "DNEXTAFTER%O"

#INCLUDE "realvals.inc"

-- replaced the T8 code with the TA code because there is no good FPU
-- implementation possible ( the previous one was wrong with -0.0 and
-- infinities ); 10-July-90 SRH
--{{{  TA and T8 code the same
REAL64 FUNCTION DNEXTAFTER (VAL REAL64 Y, Z)

  --{{{  history
  -- Beta-2 (27feb87)
  -- 18-jun-87
  -- V1.1, 21-Feb-89
  -- Corrected test for Y being positive; removed code that
  -- changed -0's into +0's for Y negative; corrected test
  -- that checked if Z was zero given that Y was zero;
  -- corrected test that Z was positive given that Y was
  -- zero; V1.4, 10-July-90 SRH ( Due to TA code being used
  -- for T8 as well, the version number has been chosen as the
  -- larger of the two ( V1.2 and V1.4 ); hence the previous TA
  -- version was V1.1, 21-Feb-89, and the previous T8 versions
  -- were V1.1, 21-Feb-89, V1.2, 12-Feb-90, and V1.3, 25-Jun-90.
  -- V1.3 of TA never existed. )
  --}}}

  #INCLUDE "endian.inc" -- 4-Sep-07

  REAL64 X :
  VALOF
    [2]INT X RETYPES X:
    VAL [2]INT Y RETYPES Y:
    VAL [2]INT Z RETYPES Z:
    INT frac1, frac2, exp1, exp2:
    INT Carry :
    SEQ
      exp1, frac1 := SHIFTLEFT (0, (Y [hi] << 1), DRealShift)
      exp2, frac2 := SHIFTLEFT (0, (Z [hi] << 1), DRealShift)
      IF
        (exp1 = DRealExp) AND ((frac1 \/ Y [lo]) <> 0)
          --{{{  at least one NaN
          IF
            (exp2 = DRealExp) AND ((frac2 \/ Z [lo]) <> 0)
              --{{{  precedence rule for NaNs
              IF
                frac1 > frac2
                  X := Y
                frac1 < frac2
                  X := Z
                Y[lo] > Z[lo]
                  X := Y
                TRUE
                  X := Z
              --}}}
            TRUE
              X := Y
          --}}}
        (exp2 = DRealExp) AND ((frac2 \/ Z [lo]) <> 0) -- fixed 18-jun-87 PWT
          X := Z
        --{{{  Y zero
        ((Y [hi] << 1) \/ Y [lo]) = 0
          IF
            ( (Z [hi] << 1) = (Y[hi] << 1) ) AND (Z [lo] = Y [lo])  -- Z is +/- zero
              X := Y
            (Z [hi] /\ (MOSTNEG INT) ) = 0 -- we already know that Z is not +/- zero
              SEQ -- Z positive
                X [lo] := 1
                X [hi] := 0
            TRUE
              SEQ -- Z negative
                X [lo] := 1
                X [hi] := (MOSTNEG INT)
        --}}}
        --{{{  Y positive
        ( Y [hi] /\ (MOSTNEG INT) ) = 0 -- we already know that Y is not +/- zero
          IF
            (Z [hi] = Y [hi]) AND (Z [lo] = Y [lo])
              X := Y
            (Z [hi] > Y [hi]) OR ((Z [hi] = Y [hi]) AND (Z [lo] > Y [lo]))
              SEQ
                Carry,  X [lo] := LONGSUM ( Y[lo],  1,  0)
                Carry,  X [hi] := LONGSUM ( Y[hi],  0,  Carry)
            TRUE
              SEQ
                Carry,  X [lo] := LONGDIFF ( Y[lo],  1,  0)
                Carry,  X [hi] := LONGDIFF ( Y[hi],  0,  Carry)
        --}}}
        --{{{  Y negative
        TRUE
          IF
            (Z [hi] = Y [hi]) AND (Z [lo] = Y [lo])
              X := Y
            ((Z [hi] >< (MOSTNEG INT)) < (Y [hi] >< (MOSTNEG INT))) OR
                ((Z [hi] = Y [hi]) AND (Z [lo] < Y [lo]))
              SEQ -- leave -0's if they arise
                Carry,  X [lo] := LONGDIFF ( Y[lo],  1,  0)
                Carry,  X [hi] := LONGDIFF ( Y[hi],  0,  Carry)
            TRUE
              SEQ
                Carry,  X [lo] := LONGSUM ( Y[lo],  1,  0)
                Carry,  X [hi] := LONGSUM ( Y[hi],  0,  Carry)
        --}}}
    RESULT X
:
--}}}


#IF (TARGET.BITS.PER.WORD = 16)

--{{{  #options and #comments
#OPTION "E V"  -- no compiler libs, no vector space
#COMMENT "T2 compiler library, V1.2 10/07/90"
#COMMENT "(c) Copyright INMOS Limited 1988"
--}}}

#PRAGMA TRANSLATE DNEXTAFTER "DNEXTAFTER%O"

#INCLUDE "realvals.inc"

--{{{  T2
REAL64 FUNCTION DNEXTAFTER (VAL REAL64 Y, Z)

  --{{{  history
  -- Function version (24 Jun 87)
  -- V1.1, 21-Feb-90
  -- Corrected test for Y being positive; removed code that
  -- changed -0's into +0's for Y negative; corrected test
  -- that checked if Z was zero given that Y was zero;
  -- corrected test that Z was positive given that Y was
  -- zero; V1.2, 10-Jul-90 SRH
  --}}}

  REAL64 X :
  VALOF
    --{{{  VALS
    VAL SignBit    IS #80000000(INT32) :
    --}}}
    VAL [4]INT Y RETYPES Y:
    VAL [4]INT Z RETYPES Z:
    [4]INT X RETYPES X:
    INT frac1, frac2, exp1, exp2:
    SEQ
      exp1, frac1 := SHIFTLEFT (0,  (Y [3] << 1),  DRealShift)
      exp2, frac2 := SHIFTLEFT (0,  (Z [3] << 1),  DRealShift)
      IF
        (exp1 = DRealExp) AND (((frac1 \/ Y [2]) \/ (Y[1]\/ Y[0])) <> 0)
          --{{{  at least one NaN
          IF
            (exp2 = DRealExp) AND (((frac2 \/ Z[2]) \/ (Z[1] \/ Z[0])) <> 0)
              --{{{  precedence rule for NaNs
              IF
                frac1 > frac2
                  X := Y
                frac1 < frac2
                  X := Z
                Y[2] > Z[2]
                  X := Y
                Z[2] > Y[2]
                  X := Z
                Y[1] > Z[1]
                  X := Y
                Z[1] > Y[1]
                  X := Z
                Y[0] > Z[0]
                  X := Y
                TRUE
                  X := Z
              --}}}
            TRUE
              X := Y
          --}}}
        (exp2 = DRealExp) AND (((frac2 \/ Z[2]) \/ (Z[1] \/ Z[0])) <> 0)
          X := Z
        --{{{  Y Zero
        [2]INT32 X RETYPES X :
        VAL [2]INT32 Y RETYPES Y:
        VAL [2]INT32 Z RETYPES Z:
        ((Y [1] << 1) \/ Y [0]) = 0(INT32)
          IF
            ( (Z [1] << 1) = (Y [1] << 1) ) AND (Z [0] = Y [0]) -- Z is +/- zero
              X := Y
            ( Z [1] /\ (MOSTNEG INT32) ) = 0( INT32 ) -- we know that Z is not +/- zero
              SEQ -- Z is positive
                X [0] := 1(INT32)
                X [1] := 0(INT32)
            TRUE
              SEQ -- Z negative
                X [0] := 1(INT32)
                X [1] := SignBit
        --}}}
        --{{{  Y positive
        [2]INT32 X RETYPES X :
        VAL [2]INT32 Y RETYPES Y:
        VAL [2]INT32 Z RETYPES Z:
        (Y [1] /\ (MOSTNEG INT32)) = 0( INT32 ) -- we know that Y is not +/- zero
          IF
            (Z [1] = Y [1]) AND (Z [0] = Y [0])
              X := Y
            (Z [1] > Y [1]) OR ((Z [1] = Y [1]) AND (Z [0] > Y [0]))
              --{{{  sum
              INT carry :
              VAL [4]INT Y RETYPES Y:
              [4]INT X RETYPES X:
              SEQ
                carry,  X[0] := LONGSUM ( Y[0],  1,  0)
                carry,  X[1] := LONGSUM ( Y[1],  0,  carry)
                carry,  X[2] := LONGSUM ( Y[2],  0,  carry)
                carry,  X[3] := LONGSUM ( Y[3],  0,  carry)
              --}}}
            TRUE
              --{{{  difference
              INT Borrow :
              VAL [4]INT Y RETYPES Y:
              [4]INT X RETYPES X:
              SEQ
                Borrow, X[0] := LONGDIFF ( Y[0], 1, 0)
                Borrow, X[1] := LONGDIFF ( Y[1], 0, Borrow)
                Borrow, X[2] := LONGDIFF ( Y[2], 0, Borrow)
                Borrow, X[3] := LONGDIFF ( Y[3], 0, Borrow)
              --}}}
        --}}}
        --{{{  Y negative
        [2]INT32 X RETYPES X :
        VAL [2]INT32 Y RETYPES Y:
        VAL [2]INT32 Z RETYPES Z:
        TRUE
          IF
            (Z [1] = Y [1]) AND (Z [0] = Y [0])
              X := Y
            ((Z [1] >< SignBit) < (Y [1] >< SignBit)) OR
                ((Z [1] = Y [1]) AND (Z [0] < Y [0]))
              --{{{  take difference
              INT Borrow :
              VAL [4]INT Y RETYPES Y:
              [4]INT X RETYPES X:
              SEQ
                Borrow, X[0] := LONGDIFF ( Y[0], 1, 0)
                Borrow, X[1] := LONGDIFF ( Y[1], 0, Borrow)
                Borrow, X[2] := LONGDIFF ( Y[2], 0, Borrow)
                Borrow, X[3] := LONGDIFF ( Y[3], 0, Borrow)
              --}}}
            TRUE
              --{{{  take sum
              INT carry :
              VAL [4]INT Y RETYPES Y:
              [4]INT X RETYPES X:
              SEQ
                carry,  X[0] := LONGSUM ( Y[0],  1,  0)
                carry,  X[1] := LONGSUM ( Y[1],  0,  carry)
                carry,  X[2] := LONGSUM ( Y[2],  0,  carry)
                carry,  X[3] := LONGSUM ( Y[3],  0,  carry)
              --}}}
        --}}}
    RESULT X
:
--}}}

#ENDIF
