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 */ 36 int 37 dbl_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 } 169