home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / floatlib.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  11KB  |  582 lines

  1. /*
  2. ** libgcc support for software floating point.
  3. ** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
  4. ** Permission is granted to do *anything* you want with this file,
  5. ** commercial or otherwise, provided this message remains intact.  So there!
  6. ** I would appreciate receiving any updates/patches/changes that anyone
  7. ** makes, and am willing to be the repository for said changes (am I
  8. ** making a big mistake?).
  9.  
  10. Warning! Only single-precision is actually implemented.  This file
  11. won't really be much use until double-precision is supported.
  12.  
  13. However, once that is done, this file might eventually become a
  14. replacement for libgcc1.c.  It might also make possible
  15. cross-compilation for an IEEE target machine from a non-IEEE
  16. host such as a VAX.
  17.  
  18. If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
  19.  
  20.  
  21. **
  22. ** Pat Wood
  23. ** Pipeline Associates, Inc.
  24. ** pipeline!phw@motown.com or
  25. ** sun!pipeline!phw or
  26. ** uunet!motown!pipeline!phw
  27. **
  28. ** 05/01/91 -- V1.0 -- first release to gcc mailing lists
  29. ** 05/04/91 -- V1.1 -- added float and double prototypes and return values
  30. **                  -- fixed problems with adding and subtracting zero
  31. **                  -- fixed rounding in truncdfsf2
  32. **                  -- fixed SWAP define and tested on 386
  33. */
  34.  
  35. /*
  36. ** The following are routines that replace the libgcc soft floating point
  37. ** routines that are called automatically when -msoft-float is selected.
  38. ** The support single and double precision IEEE format, with provisions
  39. ** for byte-swapped machines (tested on 386).  Some of the double-precision
  40. ** routines work at full precision, but most of the hard ones simply punt
  41. ** and call the single precision routines, producing a loss of accuracy.
  42. ** long long support is not assumed or included.
  43. ** Overall accuracy is close to IEEE (actually 68882) for single-precision
  44. ** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
  45. ** being rounded the wrong way during a multiply.  I'm not fussy enough to
  46. ** bother with it, but if anyone is, knock yourself out.
  47. **
  48. ** Efficiency has only been addressed where it was obvious that something
  49. ** would make a big difference.  Anyone who wants to do this right for
  50. ** best speed should go in and rewrite in assembler.
  51. **
  52. ** I have tested this only on a 68030 workstation and 386/ix integrated
  53. ** in with -msoft-float.
  54. */
  55.  
  56. /* the following deal with IEEE single-precision numbers */
  57. #define EXCESS        126
  58. #define SIGNBIT        0x80000000
  59. #define HIDDEN        (1 << 23)
  60. #define SIGN(fp)    ((fp) & SIGNBIT)
  61. #define EXP(fp)        (((fp) >> 23) & 0xFF)
  62. #define MANT(fp)    (((fp) & 0x7FFFFF) | HIDDEN)
  63. #define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
  64.  
  65. /* the following deal with IEEE double-precision numbers */
  66. #define EXCESSD        1022
  67. #define HIDDEND        (1 << 20)
  68. #define EXPD(fp)    (((fp.l.upper) >> 20) & 0x7FF)
  69. #define SIGND(fp)    ((fp.l.upper) & SIGNBIT)
  70. #define MANTD(fp)    (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
  71.                 (fp.l.lower >> 22))
  72.  
  73. /* define SWAP for 386/960 reverse-byte-order brain-damaged CPUs */
  74. union double_long
  75.   {
  76.     double d;
  77. #ifdef SWAP
  78.     struct {
  79.       unsigned long lower;
  80.       long upper;
  81.     } l;
  82. #else
  83.     struct {
  84.       long upper;
  85.       unsigned long lower;
  86.     } l;
  87. #endif
  88.   };
  89.  
  90. union float_long
  91.   {
  92.     float f;
  93.     long l;
  94.   };
  95.  
  96. /* add two floats */
  97. float
  98. __addsf3 (float a1, float a2)
  99. {
  100.   register long mant1, mant2;
  101.   register union float_long fl1, fl2;
  102.   register int exp1, exp2;
  103.   int sign = 0;
  104.  
  105.   fl1.f = a1;
  106.   fl2.f = a2;
  107.  
  108.   /* check for zero args */
  109.   if (!fl1.l)
  110.     return (fl2.f);
  111.   if (!fl2.l)
  112.     return (fl1.f);
  113.  
  114.   exp1 = EXP (fl1.l);
  115.   exp2 = EXP (fl2.l);
  116.  
  117.   if (exp1 > exp2 + 25)
  118.     return (fl1.l);
  119.   if (exp2 > exp1 + 25)
  120.     return (fl2.l);
  121.  
  122.   /* do everything in excess precision so's we can round later */
  123.   mant1 = MANT (fl1.l) << 6;
  124.   mant2 = MANT (fl2.l) << 6;
  125.  
  126.   if (SIGN (fl1.l))
  127.     mant1 = -mant1;
  128.   if (SIGN (fl2.l))
  129.     mant2 = -mant2;
  130.  
  131.   if (exp1 > exp2)
  132.     {
  133.       mant2 >>= exp1 - exp2;
  134.     }
  135.   else
  136.     {
  137.       mant1 >>= exp2 - exp1;
  138.       exp1 = exp2;
  139.     }
  140.   mant1 += mant2;
  141.  
  142.   if (mant1 < 0)
  143.     {
  144.       mant1 = -mant1;
  145.       sign = SIGNBIT;
  146.     }
  147.   else if (!mant1)
  148.     return (0);
  149.  
  150.   /* normalize up */
  151.   while (!(mant1 & 0xE0000000))
  152.     {
  153.       mant1 <<= 1;
  154.       exp1--;
  155.     }
  156.  
  157.   /* normalize down? */
  158.   if (mant1 & (1 << 30))
  159.     {
  160.       mant1 >>= 1;
  161.       exp1++;
  162.     }
  163.  
  164.   /* round to even */
  165.   mant1 += (mant1 & 0x40) ? 0x20 : 0x1F;
  166.  
  167.   /* normalize down? */
  168.   if (mant1 & (1 << 30))
  169.     {
  170.       mant1 >>= 1;
  171.       exp1++;
  172.     }
  173.  
  174.   /* lose extra precision */
  175.   mant1 >>= 6;
  176.  
  177.   /* turn off hidden bit */
  178.   mant1 &= ~HIDDEN;
  179.  
  180.   /* pack up and go home */
  181.   fl1.l = PACK (sign, exp1, mant1);
  182.   return (fl1.f);
  183. }
  184.  
  185. /* subtract two floats */
  186. float
  187. __subsf3 (float a1, float a2)
  188. {
  189.   register union float_long fl1, fl2;
  190.  
  191.   fl1.f = a1;
  192.   fl2.f = a2;
  193.  
  194.   /* check for zero args */
  195.   if (!fl2.l)
  196.     return (fl1.f);
  197.   if (!fl1.l)
  198.     return (-fl2.f);
  199.  
  200.   /* twiddle sign bit and add */
  201.   fl2.l ^= SIGNBIT;
  202.   return __addsf3 (a1, fl2.f);
  203. }
  204.  
  205. /* compare two floats */
  206. long
  207. __cmpsf2 (float a1, float a2)
  208. {
  209.   register union float_long fl1, fl2;
  210.  
  211.   fl1.f = a1;
  212.   fl2.f = a2;
  213.  
  214.   if (SIGN (fl1.l) && SIGN (fl2.l))
  215.     {
  216.       fl1.l ^= SIGNBIT;
  217.       fl2.l ^= SIGNBIT;
  218.     }
  219.   if (fl1.l < fl2.l)
  220.     return (-1);
  221.   if (fl1.l > fl2.l)
  222.     return (1);
  223.   return (0);
  224. }
  225.  
  226. /* multiply two floats */
  227. float
  228. __mulsf3 (float a1, float a2)
  229. {
  230.   register union float_long fl1, fl2;
  231.   register unsigned long result;
  232.   register int exp;
  233.   int sign;
  234.  
  235.   fl1.f = a1;
  236.   fl2.f = a2;
  237.  
  238.   if (!fl1.l || !fl2.l)
  239.     return (0);
  240.  
  241.   /* compute sign and exponent */
  242.   sign = SIGN (fl1.l) ^ SIGN (fl2.l);
  243.   exp = EXP (fl1.l) - EXCESS;
  244.   exp += EXP (fl2.l);
  245.  
  246.   fl1.l = MANT (fl1.l);
  247.   fl2.l = MANT (fl2.l);
  248.  
  249.   /* the multiply is done as one 16x16 multiply and two 16x8 multiples */
  250.   result = (fl1.l >> 8) * (fl2.l >> 8);
  251.   result += ((fl1.l & 0xFF) * (fl2.l >> 8)) >> 8;
  252.   result += ((fl2.l & 0xFF) * (fl1.l >> 8)) >> 8;
  253.  
  254.   if (result & 0x80000000)
  255.     {
  256.       /* round */
  257.       result += 0x80;
  258.       result >>= 8;
  259.     }
  260.   else
  261.     {
  262.       /* round */
  263.       result += 0x40;
  264.       result >>= 7;
  265.       exp--;
  266.     }
  267.  
  268.   result &= ~HIDDEN;
  269.  
  270.   /* pack up and go home */
  271.   fl1.l = PACK (sign, exp, result);
  272.   return (fl1.f);
  273. }
  274.  
  275. /* divide two floats */
  276. float
  277. __divsf3 (float a1, float a2)
  278. {
  279.   register union float_long fl1, fl2;
  280.   register int result;
  281.   register int mask;
  282.   register int exp, sign;
  283.  
  284.   fl1.f = a1;
  285.   fl2.f = a2;
  286.  
  287.   /* subtract exponents */
  288.   exp = EXP (fl1.l) - EXP (fl2.l) + EXCESS;
  289.  
  290.   /* compute sign */
  291.   sign = SIGN (fl1.l) ^ SIGN (fl2.l);
  292.  
  293.   /* divide by zero??? */
  294.   if (!fl2.l)
  295.     /* return NaN or -NaN */
  296.     return (sign ? 0xFFFFFFFF : 0x7FFFFFFF);
  297.  
  298.   /* numerator zero??? */
  299.   if (!fl1.l)
  300.     return (0);
  301.  
  302.   /* now get mantissas */
  303.   fl1.l = MANT (fl1.l);
  304.   fl2.l = MANT (fl2.l);
  305.  
  306.   /* this assures we have 25 bits of precision in the end */
  307.   if (fl1.l < fl2.l)
  308.     {
  309.       fl1.l <<= 1;
  310.       exp--;
  311.     }
  312.  
  313.   /* now we perform repeated subtraction of fl2.l from fl1.l */
  314.   mask = 0x1000000;
  315.   result = 0;
  316.   while (mask)
  317.     {
  318.       if (fl1.l >= fl2.l)
  319.     {
  320.       result |= mask;
  321.       fl1.l -= fl2.l;
  322.     }
  323.       fl1.l <<= 1;
  324.       mask >>= 1;
  325.     }
  326.  
  327.   /* round */
  328.   result += 1;
  329.  
  330.   /* normalize down */
  331.   exp++;
  332.   result >>= 1;
  333.  
  334.   result &= ~HIDDEN;
  335.  
  336.   /* pack up and go home */
  337.   fl1.l = PACK (sign, exp, result);
  338.   return (fl1.f);
  339. }
  340.  
  341. /* convert int to double */
  342. double
  343. __floatsidf (register long a1)
  344. {
  345.   register int sign = 0, exp = 31 + EXCESSD;
  346.   union double_long dl;
  347.  
  348.   if (!a1)
  349.     {
  350.       dl.l.upper = dl.l.lower = 0;
  351.       return (dl.d);
  352.     }
  353.  
  354.   if (a1 < 0)
  355.     {
  356.       sign = SIGNBIT;
  357.       a1 = -a1;
  358.     }
  359.  
  360.   while (a1 < 0x1000000)
  361.     {
  362.       a1 <<= 4;
  363.       exp -= 4;
  364.     }
  365.  
  366.   while (a1 < 0x40000000)
  367.     {
  368.       a1 <<= 1;
  369.       exp--;
  370.     }
  371.  
  372.   /* pack up and go home */
  373.   dl.l.upper = sign;
  374.   dl.l.upper |= exp << 20;
  375.   dl.l.upper |= (a1 >> 10) & ~HIDDEND;
  376.   dl.l.lower = a1 << 22;
  377.  
  378.   return (dl.d);
  379. }
  380.  
  381. /* negate a float */
  382. float
  383. __negsf2 (float a1)
  384. {
  385.   register union float_long fl1;
  386.  
  387.   fl1.f = a1;
  388.   if (!fl1.l)
  389.     return (0);
  390.  
  391.   fl1.l ^= SIGNBIT;
  392.   return (fl1.f);
  393. }
  394.  
  395. /* negate a double */
  396. double
  397. __negdf2 (double