linux/arch/parisc/math-emu/dfcmp.c
Thomas Gleixner 660662f857 treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 150
Based on 1 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license as published by
  the free software foundation either version 2 or at your option any
  later version this program 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
  general public license for more details you should have received a
  copy of the gnu general public license along with this program if
  not write to the free software foundation inc 59 temple place suite
  330 boston ma 02111 1307 usa

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-or-later

has been chosen to replace the boilerplate/reference in 42 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Richard Fontana <rfontana@redhat.com>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190524100845.259718220@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-05-30 11:25:19 -07:00

169 lines
4.5 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*/
/*
* BEGIN_DESC
*
* File:
* @(#) pa/spmath/dfcmp.c $Revision: 1.1 $
*
* Purpose:
* dbl_cmp: compare two values
*
* External Interfaces:
* dbl_fcmp(leftptr, rightptr, cond, status)
*
* Internal Interfaces:
*
* Theory:
* <<please update with a overview of the operation of this file>>
*
* END_DESC
*/
#include "float.h"
#include "dbl_float.h"
/*
* dbl_cmp: compare two values
*/
int
dbl_fcmp (dbl_floating_point * leftptr, dbl_floating_point * rightptr,
unsigned int cond, unsigned int *status)
/* The predicate to be tested */
{
register unsigned int leftp1, leftp2, rightp1, rightp2;
register int xorresult;
/* Create local copies of the numbers */
Dbl_copyfromptr(leftptr,leftp1,leftp2);
Dbl_copyfromptr(rightptr,rightp1,rightp2);
/*
* Test for NaN
*/
if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
|| (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) )
{
/* Check if a NaN is involved. Signal an invalid exception when
* comparing a signaling NaN or when comparing quiet NaNs and the
* low bit of the condition is set */
if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(leftp1,leftp2)
&& (Exception(cond) || Dbl_isone_signaling(leftp1)))
||
((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(rightp1,rightp2)
&& (Exception(cond) || Dbl_isone_signaling(rightp1))) )
{
if( Is_invalidtrap_enabled() ) {
Set_status_cbit(Unordered(cond));
return(INVALIDEXCEPTION);
}
else Set_invalidflag();
Set_status_cbit(Unordered(cond));
return(NOEXCEPTION);
}
/* All the exceptional conditions are handled, now special case
NaN compares */
else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(leftp1,leftp2))
||
((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
&& Dbl_isnotzero_mantissa(rightp1,rightp2)) )
{
/* NaNs always compare unordered. */
Set_status_cbit(Unordered(cond));
return(NOEXCEPTION);
}
/* infinities will drop down to the normal compare mechanisms */
}
/* First compare for unequal signs => less or greater or
* special equal case */
Dbl_xortointp1(leftp1,rightp1,xorresult);
if( xorresult < 0 )
{
/* left negative => less, left positive => greater.
* equal is possible if both operands are zeros. */
if( Dbl_iszero_exponentmantissa(leftp1,leftp2)
&& Dbl_iszero_exponentmantissa(rightp1,rightp2) )
{
Set_status_cbit(Equal(cond));
}
else if( Dbl_isone_sign(leftp1) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
/* Signs are the same. Treat negative numbers separately
* from the positives because of the reversed sense. */
else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
{
Set_status_cbit(Equal(cond));
}
else if( Dbl_iszero_sign(leftp1) )
{
/* Positive compare */
if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
{
Set_status_cbit(Lessthan(cond));
}
else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
{
Set_status_cbit(Greaterthan(cond));
}
else
{
/* Equal first parts. Now we must use unsigned compares to
* resolve the two possibilities. */
if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
}
else
{
/* Negative compare. Signed or unsigned compares
* both work the same. That distinction is only
* important when the sign bits differ. */
if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
{
Set_status_cbit(Lessthan(cond));
}
else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
{
Set_status_cbit(Greaterthan(cond));
}
else
{
/* Equal first parts. Now we must use unsigned compares to
* resolve the two possibilities. */
if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
{
Set_status_cbit(Lessthan(cond));
}
else
{
Set_status_cbit(Greaterthan(cond));
}
}
}
return(NOEXCEPTION);
}