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