1 /* $OpenBSD: sfcmp.c,v 1.6 2002/09/20 19:26:59 mickey Exp $ */ 2 /* 3 (c) Copyright 1986 HEWLETT-PACKARD COMPANY 4 To anyone who acknowledges that this file is provided "AS IS" 5 without any express or implied warranty: 6 permission to use, copy, modify, and distribute this file 7 for any purpose is hereby granted without fee, provided that 8 the above copyright notice and this notice appears in all 9 copies, and that the name of Hewlett-Packard Company not be 10 used in advertising or publicity pertaining to distribution 11 of the software without specific, written prior permission. 12 Hewlett-Packard Company makes no representations about the 13 suitability of this software for any purpose. 14 */ 15 /* @(#)sfcmp.c: Revision: 1.7.88.2 Date: 93/12/08 13:28:43 */ 16 17 #include "float.h" 18 #include "sgl_float.h" 19 20 /* 21 * sgl_cmp: compare two values 22 */ 23 int 24 sgl_fcmp(leftptr, rightptr, cond, status) 25 sgl_floating_point *leftptr, *rightptr; 26 unsigned int cond; /* The predicate to be tested */ 27 unsigned int *status; 28 { 29 register unsigned int left, right; 30 register int xorresult; 31 32 /* Create local copies of the numbers */ 33 left = *leftptr; 34 right = *rightptr; 35 /* 36 * Test for NaN 37 */ 38 if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 39 || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) ) 40 { 41 /* Check if a NaN is involved. Signal an invalid exception when 42 * comparing a signaling NaN or when comparing quiet NaNs and the 43 * low bit of the condition is set */ 44 if( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 45 && Sgl_isnotzero_mantissa(left) 46 && (Exception(cond) || Sgl_isone_signaling(left))) 47 || 48 ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) 49 && Sgl_isnotzero_mantissa(right) 50 && (Exception(cond) || Sgl_isone_signaling(right)) ) ) 51 { 52 if( Is_invalidtrap_enabled() ) { 53 Set_status_cbit(Unordered(cond)); 54 return(INVALIDEXCEPTION); 55 } 56 else Set_invalidflag(); 57 Set_status_cbit(Unordered(cond)); 58 return(NOEXCEPTION); 59 } 60 /* All the exceptional conditions are handled, now special case 61 NaN compares */ 62 else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT) 63 && Sgl_isnotzero_mantissa(left)) 64 || 65 ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT) 66 && Sgl_isnotzero_mantissa(right)) ) 67 { 68 /* NaNs always compare unordered. */ 69 Set_status_cbit(Unordered(cond)); 70 return(NOEXCEPTION); 71 } 72 /* infinities will drop down to the normal compare mechanisms */ 73 } 74 /* First compare for unequal signs => less or greater or 75 * special equal case */ 76 Sgl_xortointp1(left,right,xorresult); 77 if( xorresult < 0 ) 78 { 79 /* left negative => less, left positive => greater. 80 * equal is possible if both operands are zeros. */ 81 if( Sgl_iszero_exponentmantissa(left) 82 && Sgl_iszero_exponentmantissa(right) ) 83 { 84 Set_status_cbit(Equal(cond)); 85 } 86 else if( Sgl_isone_sign(left) ) 87 { 88 Set_status_cbit(Lessthan(cond)); 89 } 90 else 91 { 92 Set_status_cbit(Greaterthan(cond)); 93 } 94 } 95 /* Signs are the same. Treat negative numbers separately 96 * from the positives because of the reversed sense. */ 97 else if( Sgl_all(left) == Sgl_all(right) ) 98 { 99 Set_status_cbit(Equal(cond)); 100 } 101 else if( Sgl_iszero_sign(left) ) 102 { 103 /* Positive compare */ 104 if( Sgl_all(left) < Sgl_all(right) ) 105 { 106 Set_status_cbit(Lessthan(cond)); 107 } 108 else 109 { 110 Set_status_cbit(Greaterthan(cond)); 111 } 112 } 113 else 114 { 115 /* Negative compare. Signed or unsigned compares 116 * both work the same. That distinction is only 117 * important when the sign bits differ. */ 118 if( Sgl_all(left) > Sgl_all(right) ) 119 { 120 Set_status_cbit(Lessthan(cond)); 121 } 122 else 123 { 124 Set_status_cbit(Greaterthan(cond)); 125 } 126 } 127 return(NOEXCEPTION); 128 } 129