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

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/dfadd.c $Revision: 1.1 $
  26.  *
  27.  *  Purpose:
  28.  * Double_add: add two double precision values.
  29.  *
  30.  *  External Interfaces:
  31.  * dbl_fadd(leftptr, rightptr, 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_add: add two double precision values.
  44.  */
  45. dbl_fadd(
  46.     dbl_floating_point *leftptr,
  47.     dbl_floating_point *rightptr,
  48.     dbl_floating_point *dstptr,
  49.     unsigned int *status)
  50. {
  51.     register unsigned int signless_upper_left, signless_upper_right, save;
  52.     register unsigned int leftp1, leftp2, rightp1, rightp2, extent;
  53.     register unsigned int resultp1 = 0, resultp2 = 0;
  54.     
  55.     register int result_exponent, right_exponent, diff_exponent;
  56.     register int sign_save, jumpsize;
  57.     register boolean inexact = FALSE;
  58.     register boolean underflowtrap;
  59.         
  60.     /* Create local copies of the numbers */
  61.     Dbl_copyfromptr(leftptr,leftp1,leftp2);
  62.     Dbl_copyfromptr(rightptr,rightp1,rightp2);
  63.     /* A zero "save" helps discover equal operands (for later),  *
  64.      * and is used in swapping operands (if needed).             */
  65.     Dbl_xortointp1(leftp1,rightp1,/*to*/save);
  66.     /*
  67.      * check first operand for NaN's or infinity
  68.      */
  69.     if ((result_exponent = Dbl_exponent(leftp1)) == DBL_INFINITY_EXPONENT)
  70. {
  71. if (Dbl_iszero_mantissa(leftp1,leftp2)) 
  72.     {
  73.     if (Dbl_isnotnan(rightp1,rightp2)) 
  74. {
  75. if (Dbl_isinfinity(rightp1,rightp2) && save!=0) 
  76.     {
  77.     /* 
  78.      * invalid since operands are opposite signed infinity's
  79.      */
  80.     if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  81.                     Set_invalidflag();
  82.                     Dbl_makequietnan(resultp1,resultp2);
  83.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  84.     return(NOEXCEPTION);
  85.     }
  86. /*
  87.    * return infinity
  88.    */
  89. Dbl_copytoptr(leftp1,leftp2,dstptr);
  90. return(NOEXCEPTION);
  91. }
  92.     }
  93. else 
  94.     {
  95.             /*
  96.              * is NaN; signaling or quiet?
  97.              */
  98.             if (Dbl_isone_signaling(leftp1)) 
  99. {
  100.                 /* trap if INVALIDTRAP enabled */
  101. if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  102.          /* make NaN quiet */
  103.          Set_invalidflag();
  104.          Dbl_set_quiet(leftp1);
  105.          }
  106.     /* 
  107.      * is second operand a signaling NaN? 
  108.      */
  109.     else if (Dbl_is_signalingnan(rightp1)) 
  110. {
  111.          /* trap if INVALIDTRAP enabled */
  112.                 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  113. /* make NaN quiet */
  114. Set_invalidflag();
  115. Dbl_set_quiet(rightp1);
  116. Dbl_copytoptr(rightp1,rightp2,dstptr);
  117. return(NOEXCEPTION);
  118. }
  119.     /*
  120.        * return quiet NaN
  121.        */
  122.     Dbl_copytoptr(leftp1,leftp2,dstptr);
  123.       return(NOEXCEPTION);
  124.     }
  125. } /* End left NaN or Infinity processing */
  126.     /*
  127.      * check second operand for NaN's or infinity
  128.      */
  129.     if (Dbl_isinfinity_exponent(rightp1)) 
  130. {
  131. if (Dbl_iszero_mantissa(rightp1,rightp2)) 
  132.     {
  133.     /* return infinity */
  134.     Dbl_copytoptr(rightp1,rightp2,dstptr);
  135.     return(NOEXCEPTION);
  136.     }
  137.         /*
  138.          * is NaN; signaling or quiet?
  139.          */
  140.         if (Dbl_isone_signaling(rightp1)) 
  141.     {
  142.             /* trap if INVALIDTRAP enabled */
  143.     if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  144.     /* make NaN quiet */
  145.     Set_invalidflag();
  146.     Dbl_set_quiet(rightp1);
  147.     }
  148. /*
  149.  * return quiet NaN
  150.    */
  151. Dbl_copytoptr(rightp1,rightp2,dstptr);
  152. return(NOEXCEPTION);
  153.      } /* End right NaN or Infinity processing */
  154.     /* Invariant: Must be dealing with finite numbers */
  155.     /* Compare operands by removing the sign */
  156.     Dbl_copytoint_exponentmantissap1(leftp1,signless_upper_left);
  157.     Dbl_copytoint_exponentmantissap1(rightp1,signless_upper_right);
  158.     /* sign difference selects add or sub operation. */
  159.     if(Dbl_ismagnitudeless(leftp2,rightp2,signless_upper_left,signless_upper_right))
  160. {
  161. /* Set the left operand to the larger one by XOR swap *
  162.  *  First finish the first word using "save"          */
  163. Dbl_xorfromintp1(save,rightp1,/*to*/rightp1);
  164. Dbl_xorfromintp1(save,leftp1,/*to*/leftp1);
  165.       Dbl_swap_lower(leftp2,rightp2);
  166. result_exponent = Dbl_exponent(leftp1);
  167. }
  168.     /* Invariant:  left is not smaller than right. */ 
  169.     if((right_exponent = Dbl_exponent(rightp1)) == 0)
  170.         {
  171. /* Denormalized operands.  First look for zeroes */
  172. if(Dbl_iszero_mantissa(rightp1,rightp2)) 
  173.     {
  174.     /* right is zero */
  175.     if(Dbl_iszero_exponentmantissa(leftp1,leftp2))
  176. {
  177. /* Both operands are zeros */
  178. if(Is_rounding_mode(ROUNDMINUS))
  179.     {
  180.     Dbl_or_signs(leftp1,/*with*/rightp1);
  181.     }
  182. else
  183.     {
  184.     Dbl_and_signs(leftp1,/*with*/rightp1);
  185.     }
  186. }
  187.     else 
  188. {
  189. /* Left is not a zero and must be the result.  Trapped
  190.  * underflows are signaled if left is denormalized.  Result
  191.  * is always exact. */
  192. if( (result_exponent == 0) && Is_underflowtrap_enabled() )
  193.     {
  194.     /* need to normalize results mantissa */
  195.          sign_save = Dbl_signextendedsign(leftp1);
  196.     Dbl_leftshiftby1(leftp1,leftp2);
  197.     Dbl_normalize(leftp1,leftp2,result_exponent);
  198.     Dbl_set_sign(leftp1,/*using*/sign_save);
  199.                     Dbl_setwrapped_exponent(leftp1,result_exponent,unfl);
  200.     Dbl_copytoptr(leftp1,leftp2,dstptr);
  201.     /* inexact = FALSE */
  202.     return(UNDERFLOWEXCEPTION);
  203.     }
  204. }
  205.     Dbl_copytoptr(leftp1,leftp2,dstptr);
  206.     return(NOEXCEPTION);
  207.     }
  208. /* Neither are zeroes */
  209. Dbl_clear_sign(rightp1); /* Exponent is already cleared */
  210. if(result_exponent == 0 )
  211.     {
  212.     /* Both operands are denormalized.  The result must be exact
  213.      * and is simply calculated.  A sum could become normalized and a
  214.      * difference could cancel to a true zero. */
  215.     if( (/*signed*/int) save < 0 )
  216. {
  217. Dbl_subtract(leftp1,leftp2,/*minus*/rightp1,rightp2,
  218. /*into*/resultp1,resultp2);
  219. if(Dbl_iszero_mantissa(resultp1,resultp2))
  220.     {
  221.     if(Is_rounding_mode(ROUNDMINUS))
  222. {
  223. Dbl_setone_sign(resultp1);
  224. }
  225.     else
  226. {
  227. Dbl_setzero_sign(resultp1);
  228. }
  229.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  230.     return(NOEXCEPTION);
  231.     }
  232. }
  233.     else
  234. {
  235. Dbl_addition(leftp1,leftp2,rightp1,rightp2,
  236. /*into*/resultp1,resultp2);
  237. if(Dbl_isone_hidden(resultp1))
  238.     {
  239.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  240.     return(NOEXCEPTION);
  241.     }
  242. }
  243.     if(Is_underflowtrap_enabled())
  244. {
  245. /* need to normalize result */
  246.      sign_save = Dbl_signextendedsign(resultp1);
  247. Dbl_leftshiftby1(resultp1,resultp2);
  248. Dbl_normalize(resultp1,resultp2,result_exponent);
  249. Dbl_set_sign(resultp1,/*using*/sign_save);
  250.                 Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
  251.         Dbl_copytoptr(resultp1,resultp2,dstptr);
  252. /* inexact = FALSE */
  253.         return(UNDERFLOWEXCEPTION);
  254. }
  255.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  256.     return(NOEXCEPTION);
  257.     }
  258. right_exponent = 1; /* Set exponent to reflect different bias
  259.  * with denomalized numbers. */
  260. }
  261.     else
  262. {
  263. Dbl_clear_signexponent_set_hidden(rightp1);
  264. }
  265.     Dbl_clear_exponent_set_hidden(leftp1);
  266.     diff_exponent = result_exponent - right_exponent;
  267.     /* 
  268.      * Special case alignment of operands that would force alignment 
  269.      * beyond the extent of the extension.  A further optimization
  270.      * could special case this but only reduces the path length for this
  271.      * infrequent case.
  272.      */
  273.     if(diff_exponent > DBL_THRESHOLD)
  274. {
  275. diff_exponent = DBL_THRESHOLD;
  276. }
  277.     
  278.     /* Align right operand by shifting to right */
  279.     Dbl_right_align(/*operand*/rightp1,rightp2,/*shifted by*/diff_exponent,
  280.     /*and lower to*/extent);
  281.     /* Treat sum and difference of the operands separately. */
  282.     if( (/*signed*/int) save < 0 )
  283. {
  284. /*
  285.  * Difference of the two operands.  Their can be no overflow.  A
  286.  * borrow can occur out of the hidden bit and force a post
  287.  * normalization phase.
  288.  */
  289. Dbl_subtract_withextension(leftp1,leftp2,/*minus*/rightp1,rightp2,
  290. /*with*/extent,/*into*/resultp1,resultp2);
  291. if(Dbl_iszero_hidden(resultp1))
  292.     {
  293.     /* Handle normalization */
  294.     /* A straight foward algorithm would now shift the result
  295.      * and extension left until the hidden bit becomes one.  Not
  296.      * all of the extension bits need participate in the shift.
  297.      * Only the two most significant bits (round and guard) are
  298.      * needed.  If only a single shift is needed then the guard
  299.      * bit becomes a significant low order bit and the extension
  300.      * must participate in the rounding.  If more than a single 
  301.      * shift is needed, then all bits to the right of the guard 
  302.      * bit are zeros, and the guard bit may or may not be zero. */
  303.     sign_save = Dbl_signextendedsign(resultp1);
  304.             Dbl_leftshiftby1_withextent(resultp1,resultp2,extent,resultp1,resultp2);
  305.             /* Need to check for a zero result.  The sign and exponent
  306.      * fields have already been zeroed.  The more efficient test
  307.      * of the full object can be used.
  308.      */
  309.          if(Dbl_iszero(resultp1,resultp2))
  310. /* Must have been "x-x" or "x+(-x)". */
  311. {
  312. if(Is_rounding_mode(ROUNDMINUS)) Dbl_setone_sign(resultp1);
  313. Dbl_copytoptr(resultp1,resultp2,dstptr);
  314. return(NOEXCEPTION);
  315. }
  316.     result_exponent--;
  317.     /* Look to see if normalization is finished. */
  318.     if(Dbl_isone_hidden(resultp1))
  319. {
  320. if(result_exponent==0)
  321.     {
  322.     /* Denormalized, exponent should be zero.  Left operand *
  323.      * was normalized, so extent (guard, round) was zero    */
  324.     goto underflow;
  325.     }
  326. else
  327.     {
  328.     /* No further normalization is needed. */
  329.     Dbl_set_sign(resultp1,/*using*/sign_save);
  330.          Ext_leftshiftby1(extent);
  331.     goto round;
  332.     }
  333. }
  334.     /* Check for denormalized, exponent should be zero.  Left    *
  335.      * operand was normalized, so extent (guard, round) was zero */
  336.     if(!(underflowtrap = Is_underflowtrap_enabled()) &&
  337.        result_exponent==0) goto underflow;
  338.     /* Shift extension to complete one bit of normalization and
  339.      * update exponent. */
  340.     Ext_leftshiftby1(extent);
  341.     /* Discover first one bit to determine shift amount.  Use a
  342.      * modified binary search.  We have already shifted the result
  343.      * one position right and still not found a one so the remainder
  344.      * of the extension must be zero and simplifies rounding. */
  345.     /* Scan bytes */
  346.     while(Dbl_iszero_hiddenhigh7mantissa(resultp1))
  347. {
  348. Dbl_leftshiftby8(resultp1,resultp2);
  349. if((result_exponent -= 8) <= 0  && !underflowtrap)
  350.     goto underflow;
  351. }
  352.     /* Now narrow it down to the nibble */
  353.     if(Dbl_iszero_hiddenhigh3mantissa(resultp1))
  354. {
  355. /* The lower nibble contains the normalizing one */
  356. Dbl_leftshiftby4(resultp1,resultp2);
  357. if((result_exponent -= 4) <= 0 && !underflowtrap)
  358.     goto underflow;
  359. }
  360.     /* Select case were first bit is set (already normalized)
  361.      * otherwise select the proper shift. */
  362.     if((jumpsize = Dbl_hiddenhigh3mantissa(resultp1)) > 7)
  363. {
  364. /* Already normalized */
  365. if(result_exponent <= 0) goto underflow;
  366. Dbl_set_sign(resultp1,/*using*/sign_save);
  367. Dbl_set_exponent(resultp1,/*using*/result_exponent);
  368. Dbl_copytoptr(resultp1,resultp2,dstptr);
  369. return(NOEXCEPTION);
  370. }
  371.     Dbl_sethigh4bits(resultp1,/*using*/sign_save);
  372.     switch(jumpsize) 
  373. {
  374. case 1:
  375.     {
  376.     Dbl_leftshiftby3(resultp1,resultp2);
  377.     result_exponent -= 3;
  378.     break;
  379.     }
  380. case 2:
  381. case 3:
  382.     {
  383.     Dbl_leftshiftby2(resultp1,resultp2);
  384.     result_exponent -= 2;
  385.     break;
  386.     }
  387. case 4:
  388. case 5:
  389. case 6:
  390. case 7:
  391.     {
  392.     Dbl_leftshiftby1(resultp1,resultp2);
  393.     result_exponent -= 1;
  394.     break;
  395.     }
  396. }
  397.     if(result_exponent > 0) 
  398. {
  399. Dbl_set_exponent(resultp1,/*using*/result_exponent);
  400. Dbl_copytoptr(resultp1,resultp2,dstptr);
  401. return(NOEXCEPTION);  /* Sign bit is already set */
  402. }
  403.     /* Fixup potential underflows */
  404.   underflow:
  405.     if(Is_underflowtrap_enabled())
  406. {
  407. Dbl_set_sign(resultp1,sign_save);
  408.                 Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
  409. Dbl_copytoptr(resultp1,resultp2,dstptr);
  410. /* inexact = FALSE */
  411. return(UNDERFLOWEXCEPTION);
  412. }
  413.     /* 
  414.      * Since we cannot get an inexact denormalized result,
  415.      * we can now return.
  416.      */
  417.     Dbl_fix_overshift(resultp1,resultp2,(1-result_exponent),extent);
  418.     Dbl_clear_signexponent(resultp1);
  419.     Dbl_set_sign(resultp1,sign_save);
  420.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  421.     return(NOEXCEPTION);
  422.     } /* end if(hidden...)... */
  423. /* Fall through and round */
  424. } /* end if(save < 0)... */
  425.     else 
  426. {
  427. /* Add magnitudes */
  428. Dbl_addition(leftp1,leftp2,rightp1,rightp2,/*to*/resultp1,resultp2);
  429. if(Dbl_isone_hiddenoverflow(resultp1))
  430.     {
  431.     /* Prenormalization required. */
  432.     Dbl_rightshiftby1_withextent(resultp2,extent,extent);
  433.     Dbl_arithrightshiftby1(resultp1,resultp2);
  434.     result_exponent++;
  435.     } /* end if hiddenoverflow... */
  436. } /* end else ...add magnitudes... */
  437.     
  438.     /* Round the result.  If the extension is all zeros,then the result is
  439.      * exact.  Otherwise round in the correct direction.  No underflow is
  440.      * possible. If a postnormalization is necessary, then the mantissa is
  441.      * all zeros so no shift is needed. */
  442.   round:
  443.     if(Ext_isnotzero(extent))
  444. {
  445. inexact = TRUE;
  446. switch(Rounding_mode())
  447.     {
  448.     case ROUNDNEAREST: /* The default. */
  449.     if(Ext_isone_sign(extent))
  450. {
  451. /* at least 1/2 ulp */
  452. if(Ext_isnotzero_lower(extent)  ||
  453.   Dbl_isone_lowmantissap2(resultp2))
  454.     {
  455.     /* either exactly half way and odd or more than 1/2ulp */
  456.     Dbl_increment(resultp1,resultp2);
  457.     }
  458. }
  459.     break;
  460.     case ROUNDPLUS:
  461.     if(Dbl_iszero_sign(resultp1))
  462. {
  463. /* Round up positive results */
  464. Dbl_increment(resultp1,resultp2);
  465. }
  466.     break;
  467.     
  468.     case ROUNDMINUS:
  469.     if(Dbl_isone_sign(resultp1))
  470. {
  471. /* Round down negative results */
  472. Dbl_increment(resultp1,resultp2);
  473. }
  474.     
  475.     case ROUNDZERO:;
  476.     /* truncate is simple */
  477.     } /* end switch... */
  478. if(Dbl_isone_hiddenoverflow(resultp1)) result_exponent++;
  479. }
  480.     if(result_exponent == DBL_INFINITY_EXPONENT)
  481.         {
  482.         /* Overflow */
  483.         if(Is_overflowtrap_enabled())
  484.     {
  485.     Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl);
  486.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  487.     if (inexact)
  488. if (Is_inexacttrap_enabled())
  489. return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
  490. else Set_inexactflag();
  491.     return(OVERFLOWEXCEPTION);
  492.     }
  493.         else
  494.     {
  495.     inexact = TRUE;
  496.     Set_overflowflag();
  497.     Dbl_setoverflow(resultp1,resultp2);
  498.     }
  499. }
  500.     else Dbl_set_exponent(resultp1,result_exponent);
  501.     Dbl_copytoptr(resultp1,resultp2,dstptr);
  502.     if(inexact) 
  503. if(Is_inexacttrap_enabled())
  504.     return(INEXACTEXCEPTION);
  505. else Set_inexactflag();
  506.     return(NOEXCEPTION);
  507. }