sp_fmin.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * IEEE754 floating point arithmetic
  4. * single precision: MIN{,A}.f
  5. * MIN : Scalar Floating-Point Minimum
  6. * MINA: Scalar Floating-Point argument with Minimum Absolute Value
  7. *
  8. * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft])
  9. * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
  10. *
  11. * MIPS floating point support
  12. * Copyright (C) 2015 Imagination Technologies, Ltd.
  13. * Author: Markos Chandras <[email protected]>
  14. */
  15. #include "ieee754sp.h"
  16. union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
  17. {
  18. COMPXSP;
  19. COMPYSP;
  20. EXPLODEXSP;
  21. EXPLODEYSP;
  22. FLUSHXSP;
  23. FLUSHYSP;
  24. ieee754_clearcx();
  25. switch (CLPAIR(xc, yc)) {
  26. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  27. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  28. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  29. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  30. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  31. return ieee754sp_nanxcpt(y);
  32. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  33. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  34. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  35. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  36. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  37. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  38. return ieee754sp_nanxcpt(x);
  39. /*
  40. * Quiet NaN handling
  41. */
  42. /*
  43. * The case of both inputs quiet NaNs
  44. */
  45. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  46. return x;
  47. /*
  48. * The cases of exactly one input quiet NaN (numbers
  49. * are here preferred as returned values to NaNs)
  50. */
  51. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  52. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  53. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  54. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  55. return x;
  56. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  57. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  58. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  59. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  60. return y;
  61. /*
  62. * Infinity and zero handling
  63. */
  64. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  65. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  66. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  67. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  68. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  69. return xs ? x : y;
  70. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  71. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  72. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  73. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  74. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  75. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  76. return ys ? y : x;
  77. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  78. return ieee754sp_zero(xs | ys);
  79. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  80. SPDNORMX;
  81. fallthrough;
  82. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  83. SPDNORMY;
  84. break;
  85. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  86. SPDNORMX;
  87. }
  88. /* Finally get to do some computation */
  89. assert(xm & SP_HIDDEN_BIT);
  90. assert(ym & SP_HIDDEN_BIT);
  91. /* Compare signs */
  92. if (xs > ys)
  93. return x;
  94. else if (xs < ys)
  95. return y;
  96. /* Signs of inputs are the same, let's compare exponents */
  97. if (xs == 0) {
  98. /* Inputs are both positive */
  99. if (xe > ye)
  100. return y;
  101. else if (xe < ye)
  102. return x;
  103. } else {
  104. /* Inputs are both negative */
  105. if (xe > ye)
  106. return x;
  107. else if (xe < ye)
  108. return y;
  109. }
  110. /* Signs and exponents of inputs are equal, let's compare mantissas */
  111. if (xs == 0) {
  112. /* Inputs are both positive, with equal signs and exponents */
  113. if (xm <= ym)
  114. return x;
  115. return y;
  116. }
  117. /* Inputs are both negative, with equal signs and exponents */
  118. if (xm <= ym)
  119. return y;
  120. return x;
  121. }
  122. union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
  123. {
  124. COMPXSP;
  125. COMPYSP;
  126. EXPLODEXSP;
  127. EXPLODEYSP;
  128. FLUSHXSP;
  129. FLUSHYSP;
  130. ieee754_clearcx();
  131. switch (CLPAIR(xc, yc)) {
  132. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  133. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  134. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  135. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  136. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  137. return ieee754sp_nanxcpt(y);
  138. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  139. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  140. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  141. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  142. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  143. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  144. return ieee754sp_nanxcpt(x);
  145. /*
  146. * Quiet NaN handling
  147. */
  148. /*
  149. * The case of both inputs quiet NaNs
  150. */
  151. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  152. return x;
  153. /*
  154. * The cases of exactly one input quiet NaN (numbers
  155. * are here preferred as returned values to NaNs)
  156. */
  157. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  158. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  159. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  160. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  161. return x;
  162. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  163. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  164. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  165. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  166. return y;
  167. /*
  168. * Infinity and zero handling
  169. */
  170. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  171. return ieee754sp_inf(xs | ys);
  172. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  173. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  174. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  175. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  176. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  177. return y;
  178. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  179. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  180. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  181. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  182. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  183. return x;
  184. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  185. return ieee754sp_zero(xs | ys);
  186. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  187. SPDNORMX;
  188. fallthrough;
  189. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  190. SPDNORMY;
  191. break;
  192. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  193. SPDNORMX;
  194. }
  195. /* Finally get to do some computation */
  196. assert(xm & SP_HIDDEN_BIT);
  197. assert(ym & SP_HIDDEN_BIT);
  198. /* Compare exponent */
  199. if (xe > ye)
  200. return y;
  201. else if (xe < ye)
  202. return x;
  203. /* Compare mantissa */
  204. if (xm < ym)
  205. return x;
  206. else if (xm > ym)
  207. return y;
  208. else if (xs == 1)
  209. return x;
  210. return y;
  211. }