sp_fmin.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. /*
  43. * Quiet NaN handling
  44. */
  45. /*
  46. * The case of both inputs quiet NaNs
  47. */
  48. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  49. return x;
  50. /*
  51. * The cases of exactly one input quiet NaN (numbers
  52. * are here preferred as returned values to NaNs)
  53. */
  54. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  55. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  56. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  57. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  58. return x;
  59. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  60. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  61. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  62. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  63. return y;
  64. /*
  65. * Infinity and zero handling
  66. */
  67. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  68. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  69. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  70. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  71. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  72. return xs ? x : y;
  73. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  74. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  75. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  76. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  77. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  78. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  79. return ys ? y : x;
  80. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  81. return ieee754sp_zero(xs | ys);
  82. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  83. SPDNORMX;
  84. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  85. SPDNORMY;
  86. break;
  87. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  88. SPDNORMX;
  89. }
  90. /* Finally get to do some computation */
  91. assert(xm & SP_HIDDEN_BIT);
  92. assert(ym & SP_HIDDEN_BIT);
  93. /* Compare signs */
  94. if (xs > ys)
  95. return x;
  96. else if (xs < ys)
  97. return y;
  98. /* Signs of inputs are the same, let's compare exponents */
  99. if (xs == 0) {
  100. /* Inputs are both positive */
  101. if (xe > ye)
  102. return y;
  103. else if (xe < ye)
  104. return x;
  105. } else {
  106. /* Inputs are both negative */
  107. if (xe > ye)
  108. return x;
  109. else if (xe < ye)
  110. return y;
  111. }
  112. /* Signs and exponents of inputs are equal, let's compare mantissas */
  113. if (xs == 0) {
  114. /* Inputs are both positive, with equal signs and exponents */
  115. if (xm <= ym)
  116. return x;
  117. return y;
  118. }
  119. /* Inputs are both negative, with equal signs and exponents */
  120. if (xm <= ym)
  121. return y;
  122. return x;
  123. }
  124. union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
  125. {
  126. COMPXSP;
  127. COMPYSP;
  128. EXPLODEXSP;
  129. EXPLODEYSP;
  130. FLUSHXSP;
  131. FLUSHYSP;
  132. ieee754_clearcx();
  133. switch (CLPAIR(xc, yc)) {
  134. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  135. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  136. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  137. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  138. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  139. return ieee754sp_nanxcpt(y);
  140. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  141. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  142. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  143. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  144. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  145. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  146. return ieee754sp_nanxcpt(x);
  147. /*
  148. * Quiet NaN handling
  149. */
  150. /*
  151. * The case of both inputs quiet NaNs
  152. */
  153. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  154. return x;
  155. /*
  156. * The cases of exactly one input quiet NaN (numbers
  157. * are here preferred as returned values to NaNs)
  158. */
  159. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  160. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  161. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  162. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  163. return x;
  164. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  165. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  166. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  167. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  168. return y;
  169. /*
  170. * Infinity and zero handling
  171. */
  172. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  173. return ieee754sp_inf(xs | ys);
  174. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  175. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  176. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  177. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  178. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  179. return y;
  180. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  181. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  182. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  183. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  184. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  185. return x;
  186. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  187. return ieee754sp_zero(xs | ys);
  188. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  189. SPDNORMX;
  190. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  191. SPDNORMY;
  192. break;
  193. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  194. SPDNORMX;
  195. }
  196. /* Finally get to do some computation */
  197. assert(xm & SP_HIDDEN_BIT);
  198. assert(ym & SP_HIDDEN_BIT);
  199. /* Compare exponent */
  200. if (xe > ye)
  201. return y;
  202. else if (xe < ye)
  203. return x;
  204. /* Compare mantissa */
  205. if (xm < ym)
  206. return x;
  207. else if (xm > ym)
  208. return y;
  209. else if (xs == 1)
  210. return x;
  211. return y;
  212. }