dfcmp.c 5.2 KB

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