sfcmp.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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/sfcmp.c $Revision: 1.1 $
  13. *
  14. * Purpose:
  15. * sgl_cmp: compare two values
  16. *
  17. * External Interfaces:
  18. * sgl_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. #include "float.h"
  28. #include "sgl_float.h"
  29. /*
  30. * sgl_cmp: compare two values
  31. */
  32. int
  33. sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr,
  34. unsigned int cond, unsigned int *status)
  35. /* The predicate to be tested */
  36. {
  37. register unsigned int left, right;
  38. register int xorresult;
  39. /* Create local copies of the numbers */
  40. left = *leftptr;
  41. right = *rightptr;
  42. /*
  43. * Test for NaN
  44. */
  45. if( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  46. || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) )
  47. {
  48. /* Check if a NaN is involved. Signal an invalid exception when
  49. * comparing a signaling NaN or when comparing quiet NaNs and the
  50. * low bit of the condition is set */
  51. if( ( (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  52. && Sgl_isnotzero_mantissa(left)
  53. && (Exception(cond) || Sgl_isone_signaling(left)))
  54. ||
  55. ( (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  56. && Sgl_isnotzero_mantissa(right)
  57. && (Exception(cond) || Sgl_isone_signaling(right)) ) )
  58. {
  59. if( Is_invalidtrap_enabled() ) {
  60. Set_status_cbit(Unordered(cond));
  61. return(INVALIDEXCEPTION);
  62. }
  63. else Set_invalidflag();
  64. Set_status_cbit(Unordered(cond));
  65. return(NOEXCEPTION);
  66. }
  67. /* All the exceptional conditions are handled, now special case
  68. NaN compares */
  69. else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
  70. && Sgl_isnotzero_mantissa(left))
  71. ||
  72. ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
  73. && Sgl_isnotzero_mantissa(right)) )
  74. {
  75. /* NaNs always compare unordered. */
  76. Set_status_cbit(Unordered(cond));
  77. return(NOEXCEPTION);
  78. }
  79. /* infinities will drop down to the normal compare mechanisms */
  80. }
  81. /* First compare for unequal signs => less or greater or
  82. * special equal case */
  83. Sgl_xortointp1(left,right,xorresult);
  84. if( xorresult < 0 )
  85. {
  86. /* left negative => less, left positive => greater.
  87. * equal is possible if both operands are zeros. */
  88. if( Sgl_iszero_exponentmantissa(left)
  89. && Sgl_iszero_exponentmantissa(right) )
  90. {
  91. Set_status_cbit(Equal(cond));
  92. }
  93. else if( Sgl_isone_sign(left) )
  94. {
  95. Set_status_cbit(Lessthan(cond));
  96. }
  97. else
  98. {
  99. Set_status_cbit(Greaterthan(cond));
  100. }
  101. }
  102. /* Signs are the same. Treat negative numbers separately
  103. * from the positives because of the reversed sense. */
  104. else if( Sgl_all(left) == Sgl_all(right) )
  105. {
  106. Set_status_cbit(Equal(cond));
  107. }
  108. else if( Sgl_iszero_sign(left) )
  109. {
  110. /* Positive compare */
  111. if( Sgl_all(left) < Sgl_all(right) )
  112. {
  113. Set_status_cbit(Lessthan(cond));
  114. }
  115. else
  116. {
  117. Set_status_cbit(Greaterthan(cond));
  118. }
  119. }
  120. else
  121. {
  122. /* Negative compare. Signed or unsigned compares
  123. * both work the same. That distinction is only
  124. * important when the sign bits differ. */
  125. if( Sgl_all(left) > Sgl_all(right) )
  126. {
  127. Set_status_cbit(Lessthan(cond));
  128. }
  129. else
  130. {
  131. Set_status_cbit(Greaterthan(cond));
  132. }
  133. }
  134. return(NOEXCEPTION);
  135. }