dp_fmin.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * IEEE754 floating point arithmetic
  3. * double precision: MIN{,A}.f
  4. * MIN : Scalar Floating-Point Minimum
  5. * MINA: Scalar Floating-Point argument with Minimum Absolute Value
  6. *
  7. * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
  8. * MINA.D: 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 "ieee754dp.h"
  19. union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
  20. {
  21. COMPXDP;
  22. COMPYDP;
  23. EXPLODEXDP;
  24. EXPLODEYDP;
  25. FLUSHXDP;
  26. FLUSHYDP;
  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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(xs | ys);
  82. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  83. DPDNORMX;
  84. /* fall through */
  85. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  86. DPDNORMY;
  87. break;
  88. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  89. DPDNORMX;
  90. }
  91. /* Finally get to do some computation */
  92. assert(xm & DP_HIDDEN_BIT);
  93. assert(ym & DP_HIDDEN_BIT);
  94. /* Compare signs */
  95. if (xs > ys)
  96. return x;
  97. else if (xs < ys)
  98. return y;
  99. /* Signs of inputs are the same, let's compare exponents */
  100. if (xs == 0) {
  101. /* Inputs are both positive */
  102. if (xe > ye)
  103. return y;
  104. else if (xe < ye)
  105. return x;
  106. } else {
  107. /* Inputs are both negative */
  108. if (xe > ye)
  109. return x;
  110. else if (xe < ye)
  111. return y;
  112. }
  113. /* Signs and exponents of inputs are equal, let's compare mantissas */
  114. if (xs == 0) {
  115. /* Inputs are both positive, with equal signs and exponents */
  116. if (xm <= ym)
  117. return x;
  118. return y;
  119. }
  120. /* Inputs are both negative, with equal signs and exponents */
  121. if (xm <= ym)
  122. return y;
  123. return x;
  124. }
  125. union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
  126. {
  127. COMPXDP;
  128. COMPYDP;
  129. EXPLODEXDP;
  130. EXPLODEYDP;
  131. FLUSHXDP;
  132. FLUSHYDP;
  133. ieee754_clearcx();
  134. switch (CLPAIR(xc, yc)) {
  135. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  136. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  137. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  138. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  139. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  140. return ieee754dp_nanxcpt(y);
  141. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  142. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  143. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  144. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  145. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  146. case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  147. return ieee754dp_nanxcpt(x);
  148. /*
  149. * Quiet NaN handling
  150. */
  151. /*
  152. * The case of both inputs quiet NaNs
  153. */
  154. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  155. return x;
  156. /*
  157. * The cases of exactly one input quiet NaN (numbers
  158. * are here preferred as returned values to NaNs)
  159. */
  160. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  161. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  162. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  163. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  164. return x;
  165. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  166. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  167. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  168. case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  169. return y;
  170. /*
  171. * Infinity and zero handling
  172. */
  173. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  174. return ieee754dp_inf(xs | ys);
  175. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  176. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  177. case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  178. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  179. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  180. return y;
  181. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  182. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  183. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  184. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  185. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  186. return x;
  187. case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  188. return ieee754dp_zero(xs | ys);
  189. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  190. DPDNORMX;
  191. /* fall through */
  192. case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  193. DPDNORMY;
  194. break;
  195. case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  196. DPDNORMX;
  197. }
  198. /* Finally get to do some computation */
  199. assert(xm & DP_HIDDEN_BIT);
  200. assert(ym & DP_HIDDEN_BIT);
  201. /* Compare exponent */
  202. if (xe > ye)
  203. return y;
  204. else if (xe < ye)
  205. return x;
  206. /* Compare mantissa */
  207. if (xm < ym)
  208. return x;
  209. else if (xm > ym)
  210. return y;
  211. else if (xs == 1)
  212. return x;
  213. return y;
  214. }