cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dfcmp.c (4617B)


      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/dfcmp.c		$Revision: 1.1 $
     13 *
     14 *  Purpose:
     15 *	dbl_cmp: compare two values
     16 *
     17 *  External Interfaces:
     18 *	dbl_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
     30#include "float.h"
     31#include "dbl_float.h"
     32    
     33/*
     34 * dbl_cmp: compare two values
     35 */
     36int
     37dbl_fcmp (dbl_floating_point * leftptr, dbl_floating_point * rightptr,
     38	  unsigned int cond, unsigned int *status)
     39                                           
     40                       /* The predicate to be tested */
     41                         
     42    {
     43    register unsigned int leftp1, leftp2, rightp1, rightp2;
     44    register int xorresult;
     45        
     46    /* Create local copies of the numbers */
     47    Dbl_copyfromptr(leftptr,leftp1,leftp2);
     48    Dbl_copyfromptr(rightptr,rightp1,rightp2);
     49    /*
     50     * Test for NaN
     51     */
     52    if(    (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
     53        || (Dbl_exponent(rightp1) == DBL_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( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
     59	    && Dbl_isnotzero_mantissa(leftp1,leftp2) 
     60	    && (Exception(cond) || Dbl_isone_signaling(leftp1)))
     61	   ||
     62	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
     63	    && Dbl_isnotzero_mantissa(rightp1,rightp2) 
     64	    && (Exception(cond) || Dbl_isone_signaling(rightp1))) )
     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( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
     77	    && Dbl_isnotzero_mantissa(leftp1,leftp2))
     78	   ||
     79	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
     80	    && Dbl_isnotzero_mantissa(rightp1,rightp2)) )
     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    Dbl_xortointp1(leftp1,rightp1,xorresult);
     91    if( xorresult < 0 )
     92        {
     93        /* left negative => less, left positive => greater.
     94         * equal is possible if both operands are zeros. */
     95        if( Dbl_iszero_exponentmantissa(leftp1,leftp2) 
     96	  && Dbl_iszero_exponentmantissa(rightp1,rightp2) )
     97            {
     98	    Set_status_cbit(Equal(cond));
     99	    }
    100	else if( Dbl_isone_sign(leftp1) )
    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(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
    112        {
    113        Set_status_cbit(Equal(cond));
    114        }
    115    else if( Dbl_iszero_sign(leftp1) )
    116        {
    117        /* Positive compare */
    118	if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
    119	    {
    120	    Set_status_cbit(Lessthan(cond));
    121	    }
    122	else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
    123	    {
    124	    Set_status_cbit(Greaterthan(cond));
    125	    }
    126	else
    127	    {
    128	    /* Equal first parts.  Now we must use unsigned compares to
    129	     * resolve the two possibilities. */
    130	    if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
    131		{
    132		Set_status_cbit(Lessthan(cond));
    133		}
    134	    else 
    135		{
    136		Set_status_cbit(Greaterthan(cond));
    137		}
    138	    }
    139	}
    140    else
    141        {
    142        /* Negative compare.  Signed or unsigned compares
    143         * both work the same.  That distinction is only
    144         * important when the sign bits differ. */
    145	if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
    146	    {
    147	    Set_status_cbit(Lessthan(cond));
    148	    }
    149	else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
    150	    {
    151	    Set_status_cbit(Greaterthan(cond));
    152	    }
    153	else
    154	    {
    155	    /* Equal first parts.  Now we must use unsigned compares to
    156	     * resolve the two possibilities. */
    157	    if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
    158		{
    159		Set_status_cbit(Lessthan(cond));
    160		}
    161	    else 
    162		{
    163		Set_status_cbit(Greaterthan(cond));
    164		}
    165	    }
    166        }
    167	return(NOEXCEPTION);
    168    }