sp_fmin.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * IEEE754 floating point arithmetic
  3. * single precision: MIN{,A}.f
  4. * MIN : Scalar Floating-Point Minimum
  5. * MINA: Scalar Floating-Point argument with Minimum Absolute Value
  6. *
  7. * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft])
  8. * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
  9. *
  10. * MIPS floating point support
  11. * Copyright (C) 2015 Imagination Technologies, Ltd.
  12. * Author: Markos Chandras <markos.chandras@imgtec.com>
  13. *
  14. * This program is free software; you can distribute it and/or modify it
  15. * under the terms of the GNU General Public License as published by the
  16. * Free Software Foundation; version 2 of the License.
  17. */
  18. #include "ieee754sp.h"
  19. union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
  20. {
  21. COMPXSP;
  22. COMPYSP;
  23. EXPLODEXSP;
  24. EXPLODEYSP;
  25. FLUSHXSP;
  26. FLUSHYSP;
  27. ieee754_clearcx();
  28. switch (CLPAIR(xc, yc)) {
  29. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  30. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  31. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  32. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  33. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  34. return ieee754sp_nanxcpt(y);
  35. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  36. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  37. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  38. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  39. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  40. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  41. return ieee754sp_nanxcpt(x);
  42. /* numbers are preferred to NaNs */
  43. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  44. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  45. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  46. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  47. return x;
  48. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  49. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  50. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  51. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  52. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  53. return y;
  54. /*
  55. * Infinity and zero handling
  56. */
  57. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  58. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  59. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  60. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  61. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  62. return xs ? x : y;
  63. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  64. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  65. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  66. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  67. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  68. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  69. return ys ? y : x;
  70. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  71. if (xs == ys)
  72. return x;
  73. return ieee754sp_zero(1);
  74. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  75. SPDNORMX;
  76. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  77. SPDNORMY;
  78. break;
  79. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  80. SPDNORMX;
  81. }
  82. /* Finally get to do some computation */
  83. assert(xm & SP_HIDDEN_BIT);
  84. assert(ym & SP_HIDDEN_BIT);
  85. /* Compare signs */
  86. if (xs > ys)
  87. return x;
  88. else if (xs < ys)
  89. return y;
  90. /* Compare exponent */
  91. if (xe > ye)
  92. return y;
  93. else if (xe < ye)
  94. return x;
  95. /* Compare mantissa */
  96. if (xm <= ym)
  97. return x;
  98. return y;
  99. }
  100. union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
  101. {
  102. COMPXSP;
  103. COMPYSP;
  104. EXPLODEXSP;
  105. EXPLODEYSP;
  106. FLUSHXSP;
  107. FLUSHYSP;
  108. ieee754_clearcx();
  109. switch (CLPAIR(xc, yc)) {
  110. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  111. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  112. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  113. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  114. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  115. return ieee754sp_nanxcpt(y);
  116. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  117. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  118. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  119. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  120. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  121. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  122. return ieee754sp_nanxcpt(x);
  123. /* numbers are preferred to NaNs */
  124. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  125. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  126. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  127. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  128. return x;
  129. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  130. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  131. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  132. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  133. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  134. return y;
  135. /*
  136. * Infinity and zero handling
  137. */
  138. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  139. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  140. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  141. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  142. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  143. return x;
  144. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  145. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  146. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  147. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  148. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  149. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  150. return y;
  151. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  152. if (xs == ys)
  153. return x;
  154. return ieee754sp_zero(1);
  155. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  156. SPDNORMX;
  157. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  158. SPDNORMY;
  159. break;
  160. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  161. SPDNORMX;
  162. }
  163. /* Finally get to do some computation */
  164. assert(xm & SP_HIDDEN_BIT);
  165. assert(ym & SP_HIDDEN_BIT);
  166. /* Compare exponent */
  167. if (xe > ye)
  168. return y;
  169. else if (xe < ye)
  170. return x;
  171. /* Compare mantissa */
  172. if (xm <= ym)
  173. return x;
  174. return y;
  175. }