linux/arch/parisc/math-emu/sfcmp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
   4 *
   5 * Floating-point emulation code
   6 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
   7 */
   8/*
   9 * BEGIN_DESC
  10 *
  11 *  File:
  12 *      @(#)    pa/spmath/sfcmp.c               $Revision: 1.1 $
  13 *
  14 *  Purpose:
  15 *      sgl_cmp: compare two values
  16 *
  17 *  External Interfaces:
  18 *      sgl_fcmp(leftptr, rightptr, cond, status)
  19 *
  20 *  Internal Interfaces:
  21 *
  22 *  Theory:
  23 *      <<please update with a overview of the operation of this file>>
  24 *
  25 * END_DESC
  26*/
  27
  28
  29#include "float.h"
  30#include "sgl_float.h"
  31    
  32/*
  33 * sgl_cmp: compare two values
  34 */
  35int
  36sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr,
  37          unsigned int cond, unsigned int *status)
  38                                           
  39                       /* The predicate to be tested */
  40                         
  41    {
  42    register unsigned int left, right;
  43    register int xorresult;
  44        
  45    /* Create local copies of the numbers */
  46    left = *leftptr;
  47    right = *rightptr;
  48
  49    /*
  50     * Test for NaN
  51     */
  52    if(    (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  53        || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) )
  54        {
  55        /* Check if a NaN is involved.  Signal an invalid exception when 
  56         * comparing a signaling NaN or when comparing quiet NaNs and the
  57         * low bit of the condition is set */
  58        if( (  (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  59            && Sgl_isnotzero_mantissa(left) 
  60            && (Exception(cond) || Sgl_isone_signaling(left)))
  61           ||
  62            (  (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  63            && Sgl_isnotzero_mantissa(right) 
  64            && (Exception(cond) || Sgl_isone_signaling(right)) ) )
  65            {
  66            if( Is_invalidtrap_enabled() ) {
  67                Set_status_cbit(Unordered(cond));
  68                return(INVALIDEXCEPTION);
  69            }
  70            else Set_invalidflag();
  71            Set_status_cbit(Unordered(cond));
  72            return(NOEXCEPTION);
  73            }
  74        /* All the exceptional conditions are handled, now special case
  75           NaN compares */
  76        else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  77            && Sgl_isnotzero_mantissa(left))
  78           ||
  79            ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  80            && Sgl_isnotzero_mantissa(right)) )
  81            {
  82            /* NaNs always compare unordered. */
  83            Set_status_cbit(Unordered(cond));
  84            return(NOEXCEPTION);
  85            }
  86        /* infinities will drop down to the normal compare mechanisms */
  87        }
  88    /* First compare for unequal signs => less or greater or
  89     * special equal case */
  90    Sgl_xortointp1(left,right,xorresult);
  91    if( xorresult < 0 )
  92        {
  93        /* left negative => less, left positive => greater.
  94         * equal is possible if both operands are zeros. */
  95        if( Sgl_iszero_exponentmantissa(left) 
  96          && Sgl_iszero_exponentmantissa(right) )
  97            {
  98            Set_status_cbit(Equal(cond));
  99            }
 100        else if( Sgl_isone_sign(left) )
 101            {
 102            Set_status_cbit(Lessthan(cond));
 103            }
 104        else
 105            {
 106            Set_status_cbit(Greaterthan(cond));
 107            }
 108        }
 109    /* Signs are the same.  Treat negative numbers separately
 110     * from the positives because of the reversed sense.  */
 111    else if( Sgl_all(left) == Sgl_all(right) )
 112        {
 113        Set_status_cbit(Equal(cond));
 114        }
 115    else if( Sgl_iszero_sign(left) )
 116        {
 117        /* Positive compare */
 118        if( Sgl_all(left) < Sgl_all(right) )
 119            {
 120            Set_status_cbit(Lessthan(cond));
 121            }
 122        else
 123            {
 124            Set_status_cbit(Greaterthan(cond));
 125            }
 126        }
 127    else
 128        {
 129        /* Negative compare.  Signed or unsigned compares
 130         * both work the same.  That distinction is only
 131         * important when the sign bits differ. */
 132        if( Sgl_all(left) > Sgl_all(right) )
 133            {
 134            Set_status_cbit(Lessthan(cond));
 135            }
 136        else
 137            {
 138            Set_status_cbit(Greaterthan(cond));
 139            }
 140        }
 141        return(NOEXCEPTION);
 142    }
 143