sfcmp.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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/sfcmp.c $Revision: 1.1 $
  26. *
  27. * Purpose:
  28. * sgl_cmp: compare two values
  29. *
  30. * External Interfaces:
  31. * sgl_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 "sgl_float.h"
  42. /*
  43. * sgl_cmp: compare two values
  44. */
  45. int
  46. sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr,
  47. unsigned int cond, unsigned int *status)
  48. /* The predicate to be tested */
  49. {
  50. register unsigned int left, right;
  51. register int xorresult;
  52. /* Create local copies of the numbers */
  53. left = *leftptr;
  54. right = *rightptr;
  55. /*
  56. * Test for NaN
  57. */
  58. if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  59. || (Sgl_exponent(right) == SGL_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( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  65. && Sgl_isnotzero_mantissa(left)
  66. && (Exception(cond) || Sgl_isone_signaling(left)))
  67. ||
  68. ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  69. && Sgl_isnotzero_mantissa(right)
  70. && (Exception(cond) || Sgl_isone_signaling(right)) ) )
  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( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  83. && Sgl_isnotzero_mantissa(left))
  84. ||
  85. ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  86. && Sgl_isnotzero_mantissa(right)) )
  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. Sgl_xortointp1(left,right,xorresult);
  97. if( xorresult < 0 )
  98. {
  99. /* left negative => less, left positive => greater.
  100. * equal is possible if both operands are zeros. */
  101. if( Sgl_iszero_exponentmantissa(left)
  102. && Sgl_iszero_exponentmantissa(right) )
  103. {
  104. Set_status_cbit(Equal(cond));
  105. }
  106. else if( Sgl_isone_sign(left) )
  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( Sgl_all(left) == Sgl_all(right) )
  118. {
  119. Set_status_cbit(Equal(cond));
  120. }
  121. else if( Sgl_iszero_sign(left) )
  122. {
  123. /* Positive compare */
  124. if( Sgl_all(left) < Sgl_all(right) )
  125. {
  126. Set_status_cbit(Lessthan(cond));
  127. }
  128. else
  129. {
  130. Set_status_cbit(Greaterthan(cond));
  131. }
  132. }
  133. else
  134. {
  135. /* Negative compare. Signed or unsigned compares
  136. * both work the same. That distinction is only
  137. * important when the sign bits differ. */
  138. if( Sgl_all(left) > Sgl_all(right) )
  139. {
  140. Set_status_cbit(Lessthan(cond));
  141. }
  142. else
  143. {
  144. Set_status_cbit(Greaterthan(cond));
  145. }
  146. }
  147. return(NOEXCEPTION);
  148. }