dfdiv.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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., 675 Mass Ave, Cambridge, MA 02139, 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. }