--
--	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

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

--{{{  #options and #comments
#OPTION "E V"  -- no compiler libraries, no vector space
#COMMENT "T8 compiler library, V1.0 28/03/90"
#COMMENT "(c) Copyright INMOS Limited 1990"
--}}}

#PRAGMA TRANSLATE ROUNDSN "ROUNDSN%O"

#INCLUDE "realvals.inc"

INT FUNCTION ROUNDSN ( VAL INT Yexp, Yfrac, Yguard )

  --{{{  specification
  -- Purpose: Takes the individual parts of an IEEE single precision real and
  --          constructs the whole
  -- In:      Yexp - the biased exponent, i.e. actual exponent + 127
  -- In:      Yfrac - the fraction part INCLUDING the implicit bit
  -- In:      Yguard - holds the least significant bits of the fraction of Y
  -- Returned:The constructed REAL32 retyped as an INT
  -- Notes:   The sign bit is always made 0.
  --          The rounding mode is round-to-nearest.
  --}}}

  --{{{  declarations
  VAL INT WordSize  IS BitsPerWord :
  
  INT X :  -- the destination of the construction
  INT Places, Xexp, Xfrac, Xguard :
  --}}}
  VALOF
    --{{{  main body
    SEQ
      IF
        ( Yfrac \/ Yguard ) = 0 -- regardless of Yexp, X is zero ( remember that
          -- Yfrac includes the implicit bit to the left of the binary point )
          X := 0
        TRUE
          SEQ
            Places, Xfrac, Xguard := NORMALISE ( Yfrac, Yguard )
            Xexp := Yexp - Places  -- to balance the normalisation
            IF
              Xexp <= ( - WordSize )  -- must round down to zero
                SEQ
                  Xexp := 0
                  Xfrac := 0
                  Xguard := 0
              Xexp <= 0  -- will be denormalised number
                SEQ
                  Xfrac, Xguard := SHIFTRIGHT( Xfrac, Xguard, ( 1 - Xexp ) )
                  Xexp := 0
              TRUE
                SKIP
    
            IF
              Xexp < RealExp
                SEQ
                  INT dummy :
                  -- remove the leading bit from Xfrac; pack Xexp and Xfrac into X
                  -- the 1 added to RealShift means that the sign bit will be 0
                  dummy, X := SHIFTRIGHT( Xexp, Xfrac << 1, RealShift + 1 )
                  IF
                    ( Xfrac /\ RealRBit ) = 0  -- round bit not set => round
                                               -- down by leaving alone
                      SKIP
                    ( ( Xguard \/ ( Xfrac /\ RealXcess ) ) \/ ( X /\ 1 ) ) = 0
                      SKIP  -- the round bit is set, but all other bits which
                            -- have not made it into X are 0, and the lowest
                            -- bit of X is 0; therefore leave lowest bit of X
                            -- alone, i.e. we round down
                    TRUE
                      X := X + 1  -- round up
              TRUE  -- overflow
                X := RealInf
    --}}}
    RESULT X
:

#ENDIF
