mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 18:41:23 +00:00
660662f857
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>
143 lines
3.7 KiB
C
143 lines
3.7 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/sfcmp.c $Revision: 1.1 $
|
|
*
|
|
* Purpose:
|
|
* sgl_cmp: compare two values
|
|
*
|
|
* External Interfaces:
|
|
* sgl_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 "sgl_float.h"
|
|
|
|
/*
|
|
* sgl_cmp: compare two values
|
|
*/
|
|
int
|
|
sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr,
|
|
unsigned int cond, unsigned int *status)
|
|
|
|
/* The predicate to be tested */
|
|
|
|
{
|
|
register unsigned int left, right;
|
|
register int xorresult;
|
|
|
|
/* Create local copies of the numbers */
|
|
left = *leftptr;
|
|
right = *rightptr;
|
|
|
|
/*
|
|
* Test for NaN
|
|
*/
|
|
if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
|
|
|| (Sgl_exponent(right) == SGL_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( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
|
|
&& Sgl_isnotzero_mantissa(left)
|
|
&& (Exception(cond) || Sgl_isone_signaling(left)))
|
|
||
|
|
( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
|
|
&& Sgl_isnotzero_mantissa(right)
|
|
&& (Exception(cond) || Sgl_isone_signaling(right)) ) )
|
|
{
|
|
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( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
|
|
&& Sgl_isnotzero_mantissa(left))
|
|
||
|
|
((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
|
|
&& Sgl_isnotzero_mantissa(right)) )
|
|
{
|
|
/* 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 */
|
|
Sgl_xortointp1(left,right,xorresult);
|
|
if( xorresult < 0 )
|
|
{
|
|
/* left negative => less, left positive => greater.
|
|
* equal is possible if both operands are zeros. */
|
|
if( Sgl_iszero_exponentmantissa(left)
|
|
&& Sgl_iszero_exponentmantissa(right) )
|
|
{
|
|
Set_status_cbit(Equal(cond));
|
|
}
|
|
else if( Sgl_isone_sign(left) )
|
|
{
|
|
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( Sgl_all(left) == Sgl_all(right) )
|
|
{
|
|
Set_status_cbit(Equal(cond));
|
|
}
|
|
else if( Sgl_iszero_sign(left) )
|
|
{
|
|
/* Positive compare */
|
|
if( Sgl_all(left) < Sgl_all(right) )
|
|
{
|
|
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( Sgl_all(left) > Sgl_all(right) )
|
|
{
|
|
Set_status_cbit(Lessthan(cond));
|
|
}
|
|
else
|
|
{
|
|
Set_status_cbit(Greaterthan(cond));
|
|
}
|
|
}
|
|
return(NOEXCEPTION);
|
|
}
|