1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * Linux/PA-RISC Project (http://www.parisc-linux.org/) 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Floating-point emulation code 5*1da177e4SLinus Torvalds * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 8*1da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 9*1da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 10*1da177e4SLinus Torvalds * any later version. 11*1da177e4SLinus Torvalds * 12*1da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 13*1da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*1da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*1da177e4SLinus Torvalds * GNU General Public License for more details. 16*1da177e4SLinus Torvalds * 17*1da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 18*1da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 19*1da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20*1da177e4SLinus Torvalds */ 21*1da177e4SLinus Torvalds /* 22*1da177e4SLinus Torvalds * BEGIN_DESC 23*1da177e4SLinus Torvalds * 24*1da177e4SLinus Torvalds * File: 25*1da177e4SLinus Torvalds * @(#) pa/spmath/dfcmp.c $Revision: 1.1 $ 26*1da177e4SLinus Torvalds * 27*1da177e4SLinus Torvalds * Purpose: 28*1da177e4SLinus Torvalds * dbl_cmp: compare two values 29*1da177e4SLinus Torvalds * 30*1da177e4SLinus Torvalds * External Interfaces: 31*1da177e4SLinus Torvalds * dbl_fcmp(leftptr, rightptr, cond, status) 32*1da177e4SLinus Torvalds * 33*1da177e4SLinus Torvalds * Internal Interfaces: 34*1da177e4SLinus Torvalds * 35*1da177e4SLinus Torvalds * Theory: 36*1da177e4SLinus Torvalds * <<please update with a overview of the operation of this file>> 37*1da177e4SLinus Torvalds * 38*1da177e4SLinus Torvalds * END_DESC 39*1da177e4SLinus Torvalds */ 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds 42*1da177e4SLinus Torvalds 43*1da177e4SLinus Torvalds #include "float.h" 44*1da177e4SLinus Torvalds #include "dbl_float.h" 45*1da177e4SLinus Torvalds 46*1da177e4SLinus Torvalds /* 47*1da177e4SLinus Torvalds * dbl_cmp: compare two values 48*1da177e4SLinus Torvalds */ 49*1da177e4SLinus Torvalds int 50*1da177e4SLinus Torvalds dbl_fcmp (dbl_floating_point * leftptr, dbl_floating_point * rightptr, 51*1da177e4SLinus Torvalds unsigned int cond, unsigned int *status) 52*1da177e4SLinus Torvalds 53*1da177e4SLinus Torvalds /* The predicate to be tested */ 54*1da177e4SLinus Torvalds 55*1da177e4SLinus Torvalds { 56*1da177e4SLinus Torvalds register unsigned int leftp1, leftp2, rightp1, rightp2; 57*1da177e4SLinus Torvalds register int xorresult; 58*1da177e4SLinus Torvalds 59*1da177e4SLinus Torvalds /* Create local copies of the numbers */ 60*1da177e4SLinus Torvalds Dbl_copyfromptr(leftptr,leftp1,leftp2); 61*1da177e4SLinus Torvalds Dbl_copyfromptr(rightptr,rightp1,rightp2); 62*1da177e4SLinus Torvalds /* 63*1da177e4SLinus Torvalds * Test for NaN 64*1da177e4SLinus Torvalds */ 65*1da177e4SLinus Torvalds if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 66*1da177e4SLinus Torvalds || (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) ) 67*1da177e4SLinus Torvalds { 68*1da177e4SLinus Torvalds /* Check if a NaN is involved. Signal an invalid exception when 69*1da177e4SLinus Torvalds * comparing a signaling NaN or when comparing quiet NaNs and the 70*1da177e4SLinus Torvalds * low bit of the condition is set */ 71*1da177e4SLinus Torvalds if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 72*1da177e4SLinus Torvalds && Dbl_isnotzero_mantissa(leftp1,leftp2) 73*1da177e4SLinus Torvalds && (Exception(cond) || Dbl_isone_signaling(leftp1))) 74*1da177e4SLinus Torvalds || 75*1da177e4SLinus Torvalds ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) 76*1da177e4SLinus Torvalds && Dbl_isnotzero_mantissa(rightp1,rightp2) 77*1da177e4SLinus Torvalds && (Exception(cond) || Dbl_isone_signaling(rightp1))) ) 78*1da177e4SLinus Torvalds { 79*1da177e4SLinus Torvalds if( Is_invalidtrap_enabled() ) { 80*1da177e4SLinus Torvalds Set_status_cbit(Unordered(cond)); 81*1da177e4SLinus Torvalds return(INVALIDEXCEPTION); 82*1da177e4SLinus Torvalds } 83*1da177e4SLinus Torvalds else Set_invalidflag(); 84*1da177e4SLinus Torvalds Set_status_cbit(Unordered(cond)); 85*1da177e4SLinus Torvalds return(NOEXCEPTION); 86*1da177e4SLinus Torvalds } 87*1da177e4SLinus Torvalds /* All the exceptional conditions are handled, now special case 88*1da177e4SLinus Torvalds NaN compares */ 89*1da177e4SLinus Torvalds else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) 90*1da177e4SLinus Torvalds && Dbl_isnotzero_mantissa(leftp1,leftp2)) 91*1da177e4SLinus Torvalds || 92*1da177e4SLinus Torvalds ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) 93*1da177e4SLinus Torvalds && Dbl_isnotzero_mantissa(rightp1,rightp2)) ) 94*1da177e4SLinus Torvalds { 95*1da177e4SLinus Torvalds /* NaNs always compare unordered. */ 96*1da177e4SLinus Torvalds Set_status_cbit(Unordered(cond)); 97*1da177e4SLinus Torvalds return(NOEXCEPTION); 98*1da177e4SLinus Torvalds } 99*1da177e4SLinus Torvalds /* infinities will drop down to the normal compare mechanisms */ 100*1da177e4SLinus Torvalds } 101*1da177e4SLinus Torvalds /* First compare for unequal signs => less or greater or 102*1da177e4SLinus Torvalds * special equal case */ 103*1da177e4SLinus Torvalds Dbl_xortointp1(leftp1,rightp1,xorresult); 104*1da177e4SLinus Torvalds if( xorresult < 0 ) 105*1da177e4SLinus Torvalds { 106*1da177e4SLinus Torvalds /* left negative => less, left positive => greater. 107*1da177e4SLinus Torvalds * equal is possible if both operands are zeros. */ 108*1da177e4SLinus Torvalds if( Dbl_iszero_exponentmantissa(leftp1,leftp2) 109*1da177e4SLinus Torvalds && Dbl_iszero_exponentmantissa(rightp1,rightp2) ) 110*1da177e4SLinus Torvalds { 111*1da177e4SLinus Torvalds Set_status_cbit(Equal(cond)); 112*1da177e4SLinus Torvalds } 113*1da177e4SLinus Torvalds else if( Dbl_isone_sign(leftp1) ) 114*1da177e4SLinus Torvalds { 115*1da177e4SLinus Torvalds Set_status_cbit(Lessthan(cond)); 116*1da177e4SLinus Torvalds } 117*1da177e4SLinus Torvalds else 118*1da177e4SLinus Torvalds { 119*1da177e4SLinus Torvalds Set_status_cbit(Greaterthan(cond)); 120*1da177e4SLinus Torvalds } 121*1da177e4SLinus Torvalds } 122*1da177e4SLinus Torvalds /* Signs are the same. Treat negative numbers separately 123*1da177e4SLinus Torvalds * from the positives because of the reversed sense. */ 124*1da177e4SLinus Torvalds else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2)) 125*1da177e4SLinus Torvalds { 126*1da177e4SLinus Torvalds Set_status_cbit(Equal(cond)); 127*1da177e4SLinus Torvalds } 128*1da177e4SLinus Torvalds else if( Dbl_iszero_sign(leftp1) ) 129*1da177e4SLinus Torvalds { 130*1da177e4SLinus Torvalds /* Positive compare */ 131*1da177e4SLinus Torvalds if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) 132*1da177e4SLinus Torvalds { 133*1da177e4SLinus Torvalds Set_status_cbit(Lessthan(cond)); 134*1da177e4SLinus Torvalds } 135*1da177e4SLinus Torvalds else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) 136*1da177e4SLinus Torvalds { 137*1da177e4SLinus Torvalds Set_status_cbit(Greaterthan(cond)); 138*1da177e4SLinus Torvalds } 139*1da177e4SLinus Torvalds else 140*1da177e4SLinus Torvalds { 141*1da177e4SLinus Torvalds /* Equal first parts. Now we must use unsigned compares to 142*1da177e4SLinus Torvalds * resolve the two possibilities. */ 143*1da177e4SLinus Torvalds if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) ) 144*1da177e4SLinus Torvalds { 145*1da177e4SLinus Torvalds Set_status_cbit(Lessthan(cond)); 146*1da177e4SLinus Torvalds } 147*1da177e4SLinus Torvalds else 148*1da177e4SLinus Torvalds { 149*1da177e4SLinus Torvalds Set_status_cbit(Greaterthan(cond)); 150*1da177e4SLinus Torvalds } 151*1da177e4SLinus Torvalds } 152*1da177e4SLinus Torvalds } 153*1da177e4SLinus Torvalds else 154*1da177e4SLinus Torvalds { 155*1da177e4SLinus Torvalds /* Negative compare. Signed or unsigned compares 156*1da177e4SLinus Torvalds * both work the same. That distinction is only 157*1da177e4SLinus Torvalds * important when the sign bits differ. */ 158*1da177e4SLinus Torvalds if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) 159*1da177e4SLinus Torvalds { 160*1da177e4SLinus Torvalds Set_status_cbit(Lessthan(cond)); 161*1da177e4SLinus Torvalds } 162*1da177e4SLinus Torvalds else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) 163*1da177e4SLinus Torvalds { 164*1da177e4SLinus Torvalds Set_status_cbit(Greaterthan(cond)); 165*1da177e4SLinus Torvalds } 166*1da177e4SLinus Torvalds else 167*1da177e4SLinus Torvalds { 168*1da177e4SLinus Torvalds /* Equal first parts. Now we must use unsigned compares to 169*1da177e4SLinus Torvalds * resolve the two possibilities. */ 170*1da177e4SLinus Torvalds if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) ) 171*1da177e4SLinus Torvalds { 172*1da177e4SLinus Torvalds Set_status_cbit(Lessthan(cond)); 173*1da177e4SLinus Torvalds } 174*1da177e4SLinus Torvalds else 175*1da177e4SLinus Torvalds { 176*1da177e4SLinus Torvalds Set_status_cbit(Greaterthan(cond)); 177*1da177e4SLinus Torvalds } 178*1da177e4SLinus Torvalds } 179*1da177e4SLinus Torvalds } 180*1da177e4SLinus Torvalds return(NOEXCEPTION); 181*1da177e4SLinus Torvalds } 182