dfdiv.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. /*
  2. * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  3. *
  4. * Floating-point emulation code
  5. * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2, or (at your option)
  10. * any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. /*
  22. * BEGIN_DESC
  23. *
  24. * File:
  25. * @(#) pa/spmath/dfdiv.c $Revision: 1.1 $
  26. *
  27. * Purpose:
  28. * Double Precision Floating-point Divide
  29. *
  30. * External Interfaces:
  31. * dbl_fdiv(srcptr1,srcptr2,dstptr,status)
  32. *
  33. * Internal Interfaces:
  34. *
  35. * Theory:
  36. * <<please update with a overview of the operation of this file>>
  37. *
  38. * END_DESC
  39. */
  40. #include "float.h"
  41. #include "dbl_float.h"
  42. /*
  43. * Double Precision Floating-point Divide
  44. */
  45. int
  46. dbl_fdiv (dbl_floating_point * srcptr1, dbl_floating_point * srcptr2,
  47. dbl_floating_point * dstptr, unsigned int *status)
  48. {
  49. register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
  50. register unsigned int opnd3p1, opnd3p2, resultp1, resultp2;
  51. register int dest_exponent, count;
  52. register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
  53. boolean is_tiny;
  54. Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
  55. Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
  56. /*
  57. * set sign bit of result
  58. */
  59. if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
  60. Dbl_setnegativezerop1(resultp1);
  61. else Dbl_setzerop1(resultp1);
  62. /*
  63. * check first operand for NaN's or infinity
  64. */
  65. if (Dbl_isinfinity_exponent(opnd1p1)) {
  66. if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
  67. if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
  68. if (Dbl_isinfinity(opnd2p1,opnd2p2)) {
  69. /*
  70. * invalid since both operands
  71. * are infinity
  72. */
  73. if (Is_invalidtrap_enabled())
  74. return(INVALIDEXCEPTION);
  75. Set_invalidflag();
  76. Dbl_makequietnan(resultp1,resultp2);
  77. Dbl_copytoptr(resultp1,resultp2,dstptr);
  78. return(NOEXCEPTION);
  79. }
  80. /*
  81. * return infinity
  82. */
  83. Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
  84. Dbl_copytoptr(resultp1,resultp2,dstptr);
  85. return(NOEXCEPTION);
  86. }
  87. }
  88. else {
  89. /*
  90. * is NaN; signaling or quiet?
  91. */
  92. if (Dbl_isone_signaling(opnd1p1)) {
  93. /* trap if INVALIDTRAP enabled */
  94. if (Is_invalidtrap_enabled())
  95. return(INVALIDEXCEPTION);
  96. /* make NaN quiet */
  97. Set_invalidflag();
  98. Dbl_set_quiet(opnd1p1);
  99. }
  100. /*
  101. * is second operand a signaling NaN?
  102. */
  103. else if (Dbl_is_signalingnan(opnd2p1)) {
  104. /* trap if INVALIDTRAP enabled */
  105. if (Is_invalidtrap_enabled())
  106. return(INVALIDEXCEPTION);
  107. /* make NaN quiet */
  108. Set_invalidflag();
  109. Dbl_set_quiet(opnd2p1);
  110. Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
  111. return(NOEXCEPTION);
  112. }
  113. /*
  114. * return quiet NaN
  115. */
  116. Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
  117. return(NOEXCEPTION);
  118. }
  119. }
  120. /*
  121. * check second operand for NaN's or infinity
  122. */
  123. if (Dbl_isinfinity_exponent(opnd2p1)) {
  124. if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
  125. /*
  126. * return zero
  127. */
  128. Dbl_setzero_exponentmantissa(resultp1,resultp2);
  129. Dbl_copytoptr(resultp1,resultp2,dstptr);
  130. return(NOEXCEPTION);
  131. }
  132. /*
  133. * is NaN; signaling or quiet?
  134. */
  135. if (Dbl_isone_signaling(opnd2p1)) {
  136. /* trap if INVALIDTRAP enabled */
  137. if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  138. /* make NaN quiet */
  139. Set_invalidflag();
  140. Dbl_set_quiet(opnd2p1);
  141. }
  142. /*
  143. * return quiet NaN
  144. */
  145. Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
  146. return(NOEXCEPTION);
  147. }
  148. /*
  149. * check for division by zero
  150. */
  151. if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
  152. if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
  153. /* invalid since both operands are zero */
  154. if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  155. Set_invalidflag();
  156. Dbl_makequietnan(resultp1,resultp2);
  157. Dbl_copytoptr(resultp1,resultp2,dstptr);
  158. return(NOEXCEPTION);
  159. }
  160. if (Is_divisionbyzerotrap_enabled())
  161. return(DIVISIONBYZEROEXCEPTION);
  162. Set_divisionbyzeroflag();
  163. Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
  164. Dbl_copytoptr(resultp1,resultp2,dstptr);
  165. return(NOEXCEPTION);
  166. }
  167. /*
  168. * Generate exponent
  169. */
  170. dest_exponent = Dbl_exponent(opnd1p1) - Dbl_exponent(opnd2p1) + DBL_BIAS;
  171. /*
  172. * Generate mantissa
  173. */
  174. if (Dbl_isnotzero_exponent(opnd1p1)) {
  175. /* set hidden bit */
  176. Dbl_clear_signexponent_set_hidden(opnd1p1);
  177. }
  178. else {
  179. /* check for zero */
  180. if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
  181. Dbl_setzero_exponentmantissa(resultp1,resultp2);
  182. Dbl_copytoptr(resultp1,resultp2,dstptr);
  183. return(NOEXCEPTION);
  184. }
  185. /* is denormalized, want to normalize */
  186. Dbl_clear_signexponent(opnd1p1);
  187. Dbl_leftshiftby1(opnd1p1,opnd1p2);
  188. Dbl_normalize(opnd1p1,opnd1p2,dest_exponent);
  189. }
  190. /* opnd2 needs to have hidden bit set with msb in hidden bit */
  191. if (Dbl_isnotzero_exponent(opnd2p1)) {
  192. Dbl_clear_signexponent_set_hidden(opnd2p1);
  193. }
  194. else {
  195. /* is denormalized; want to normalize */
  196. Dbl_clear_signexponent(opnd2p1);
  197. Dbl_leftshiftby1(opnd2p1,opnd2p2);
  198. while (Dbl_iszero_hiddenhigh7mantissa(opnd2p1)) {
  199. dest_exponent+=8;
  200. Dbl_leftshiftby8(opnd2p1,opnd2p2);
  201. }
  202. if (Dbl_iszero_hiddenhigh3mantissa(opnd2p1)) {
  203. dest_exponent+=4;
  204. Dbl_leftshiftby4(opnd2p1,opnd2p2);
  205. }
  206. while (Dbl_iszero_hidden(opnd2p1)) {
  207. dest_exponent++;
  208. Dbl_leftshiftby1(opnd2p1,opnd2p2);
  209. }
  210. }
  211. /* Divide the source mantissas */
  212. /*
  213. * A non-restoring divide algorithm is used.
  214. */
  215. Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
  216. Dbl_setzero(opnd3p1,opnd3p2);
  217. for (count=1; count <= DBL_P && (opnd1p1 || opnd1p2); count++) {
  218. Dbl_leftshiftby1(opnd1p1,opnd1p2);
  219. Dbl_leftshiftby1(opnd3p1,opnd3p2);
  220. if (Dbl_iszero_sign(opnd1p1)) {
  221. Dbl_setone_lowmantissap2(opnd3p2);
  222. Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
  223. }
  224. else {
  225. Twoword_add(opnd1p1, opnd1p2, opnd2p1, opnd2p2);
  226. }
  227. }
  228. if (count <= DBL_P) {
  229. Dbl_leftshiftby1(opnd3p1,opnd3p2);
  230. Dbl_setone_lowmantissap2(opnd3p2);
  231. Dbl_leftshift(opnd3p1,opnd3p2,(DBL_P-count));
  232. if (Dbl_iszero_hidden(opnd3p1)) {
  233. Dbl_leftshiftby1(opnd3p1,opnd3p2);
  234. dest_exponent--;
  235. }
  236. }
  237. else {
  238. if (Dbl_iszero_hidden(opnd3p1)) {
  239. /* need to get one more bit of result */
  240. Dbl_leftshiftby1(opnd1p1,opnd1p2);
  241. Dbl_leftshiftby1(opnd3p1,opnd3p2);
  242. if (Dbl_iszero_sign(opnd1p1)) {
  243. Dbl_setone_lowmantissap2(opnd3p2);
  244. Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
  245. }
  246. else {
  247. Twoword_add(opnd1p1,opnd1p2,opnd2p1,opnd2p2);
  248. }
  249. dest_exponent--;
  250. }
  251. if (Dbl_iszero_sign(opnd1p1)) guardbit = TRUE;
  252. stickybit = Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2);
  253. }
  254. inexact = guardbit | stickybit;
  255. /*
  256. * round result
  257. */
  258. if (inexact && (dest_exponent > 0 || Is_underflowtrap_enabled())) {
  259. Dbl_clear_signexponent(opnd3p1);
  260. switch (Rounding_mode()) {
  261. case ROUNDPLUS:
  262. if (Dbl_iszero_sign(resultp1))
  263. Dbl_increment(opnd3p1,opnd3p2);
  264. break;
  265. case ROUNDMINUS:
  266. if (Dbl_isone_sign(resultp1))
  267. Dbl_increment(opnd3p1,opnd3p2);
  268. break;
  269. case ROUNDNEAREST:
  270. if (guardbit && (stickybit ||
  271. Dbl_isone_lowmantissap2(opnd3p2))) {
  272. Dbl_increment(opnd3p1,opnd3p2);
  273. }
  274. }
  275. if (Dbl_isone_hidden(opnd3p1)) dest_exponent++;
  276. }
  277. Dbl_set_mantissa(resultp1,resultp2,opnd3p1,opnd3p2);
  278. /*
  279. * Test for overflow
  280. */
  281. if (dest_exponent >= DBL_INFINITY_EXPONENT) {
  282. /* trap if OVERFLOWTRAP enabled */
  283. if (Is_overflowtrap_enabled()) {
  284. /*
  285. * Adjust bias of result
  286. */
  287. Dbl_setwrapped_exponent(resultp1,dest_exponent,ovfl);
  288. Dbl_copytoptr(resultp1,resultp2,dstptr);
  289. if (inexact)
  290. if (Is_inexacttrap_enabled())
  291. return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
  292. else Set_inexactflag();
  293. return(OVERFLOWEXCEPTION);
  294. }
  295. Set_overflowflag();
  296. /* set result to infinity or largest number */
  297. Dbl_setoverflow(resultp1,resultp2);
  298. inexact = TRUE;
  299. }
  300. /*
  301. * Test for underflow
  302. */
  303. else if (dest_exponent <= 0) {
  304. /* trap if UNDERFLOWTRAP enabled */
  305. if (Is_underflowtrap_enabled()) {
  306. /*
  307. * Adjust bias of result
  308. */
  309. Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
  310. Dbl_copytoptr(resultp1,resultp2,dstptr);
  311. if (inexact)
  312. if (Is_inexacttrap_enabled())
  313. return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
  314. else Set_inexactflag();
  315. return(UNDERFLOWEXCEPTION);
  316. }
  317. /* Determine if should set underflow flag */
  318. is_tiny = TRUE;
  319. if (dest_exponent == 0 && inexact) {
  320. switch (Rounding_mode()) {
  321. case ROUNDPLUS:
  322. if (Dbl_iszero_sign(resultp1)) {
  323. Dbl_increment(opnd3p1,opnd3p2);
  324. if (Dbl_isone_hiddenoverflow(opnd3p1))
  325. is_tiny = FALSE;
  326. Dbl_decrement(opnd3p1,opnd3p2);
  327. }
  328. break;
  329. case ROUNDMINUS:
  330. if (Dbl_isone_sign(resultp1)) {
  331. Dbl_increment(opnd3p1,opnd3p2);
  332. if (Dbl_isone_hiddenoverflow(opnd3p1))
  333. is_tiny = FALSE;
  334. Dbl_decrement(opnd3p1,opnd3p2);
  335. }
  336. break;
  337. case ROUNDNEAREST:
  338. if (guardbit && (stickybit ||
  339. Dbl_isone_lowmantissap2(opnd3p2))) {
  340. Dbl_increment(opnd3p1,opnd3p2);
  341. if (Dbl_isone_hiddenoverflow(opnd3p1))
  342. is_tiny = FALSE;
  343. Dbl_decrement(opnd3p1,opnd3p2);
  344. }
  345. break;
  346. }
  347. }
  348. /*
  349. * denormalize result or set to signed zero
  350. */
  351. stickybit = inexact;
  352. Dbl_denormalize(opnd3p1,opnd3p2,dest_exponent,guardbit,
  353. stickybit,inexact);
  354. /* return rounded number */
  355. if (inexact) {
  356. switch (Rounding_mode()) {
  357. case ROUNDPLUS:
  358. if (Dbl_iszero_sign(resultp1)) {
  359. Dbl_increment(opnd3p1,opnd3p2);
  360. }
  361. break;
  362. case ROUNDMINUS:
  363. if (Dbl_isone_sign(resultp1)) {
  364. Dbl_increment(opnd3p1,opnd3p2);
  365. }
  366. break;
  367. case ROUNDNEAREST:
  368. if (guardbit && (stickybit ||
  369. Dbl_isone_lowmantissap2(opnd3p2))) {
  370. Dbl_increment(opnd3p1,opnd3p2);
  371. }
  372. break;
  373. }
  374. if (is_tiny) Set_underflowflag();
  375. }
  376. Dbl_set_exponentmantissa(resultp1,resultp2,opnd3p1,opnd3p2);
  377. }
  378. else Dbl_set_exponent(resultp1,dest_exponent);
  379. Dbl_copytoptr(resultp1,resultp2,dstptr);
  380. /* check for inexact */
  381. if (inexact) {
  382. if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
  383. else Set_inexactflag();
  384. }
  385. return(NOEXCEPTION);
  386. }