Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* This is a software fixed-point library.
  2.    Copyright (C) 2007-2015 Free Software Foundation, Inc.
  3.  
  4. This file is part of GCC.
  5.  
  6. GCC is free software; you can redistribute it and/or modify it under
  7. the terms of the GNU General Public License as published by the Free
  8. Software Foundation; either version 3, or (at your option) any later
  9. version.
  10.  
  11. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  12. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14. for more details.
  15.  
  16. Under Section 7 of GPL version 3, you are granted additional
  17. permissions described in the GCC Runtime Library Exception, version
  18. 3.1, as published by the Free Software Foundation.
  19.  
  20. You should have received a copy of the GNU General Public License and
  21. a copy of the GCC Runtime Library Exception along with this program;
  22. see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. <http://www.gnu.org/licenses/>.  */
  24.  
  25. /* This implements fixed-point arithmetic.
  26.  
  27.    Contributed by Chao-ying Fu  <fu@mips.com>.  */
  28.  
  29. /* To use this file, we need to define one of the following:
  30.    QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
  31.    TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
  32.    TA_MODE, UTA_MODE.
  33.    Then, all operators for this machine mode will be created.
  34.  
  35.    Or, we need to define FROM_* TO_* for conversions from one mode to another
  36.    mode.  The mode could be one of the following:
  37.    Fract: QQ, UQQ, HQ, UHQ, SQ, USQ, DQ, UDQ, TQ, UTQ
  38.    Accum: HA, UHA, SA, USA, DA, UDA, TA, UTA
  39.    Signed integer: QI, HI, SI, DI, TI
  40.    Unsigned integer: UQI, UHI, USI, UDI, UTI
  41.    Floating-point: SF, DF
  42.    Ex: If we define FROM_QQ and TO_SI, the conversion from QQ to SI is
  43.    generated.  */
  44.  
  45. #include "tconfig.h"
  46. #include "tsystem.h"
  47. #include "coretypes.h"
  48. #include "tm.h"
  49. #include "libgcc_tm.h"
  50.  
  51. #ifndef MIN_UNITS_PER_WORD
  52. #define MIN_UNITS_PER_WORD UNITS_PER_WORD
  53. #endif
  54.  
  55. #include "fixed-bit.h"
  56.  
  57. #if defined(FIXED_ADD) && defined(L_add)
  58. FIXED_C_TYPE
  59. FIXED_ADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
  60. {
  61.   FIXED_C_TYPE c;
  62.   INT_C_TYPE x, y, z;
  63.   memcpy (&x, &a, FIXED_SIZE);
  64.   memcpy (&y, &b, FIXED_SIZE);
  65.   z = x + y;
  66. #if HAVE_PADDING_BITS
  67.   z = z << PADDING_BITS;
  68.   z = z >> PADDING_BITS;
  69. #endif
  70.   memcpy (&c, &z, FIXED_SIZE);
  71.   return c;
  72. }
  73. #endif /* FIXED_ADD */
  74.  
  75. #if defined(FIXED_SSADD) && defined(L_ssadd)
  76. FIXED_C_TYPE
  77. FIXED_SSADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
  78. {
  79.   FIXED_C_TYPE c;
  80.   INT_C_TYPE x, y, z;
  81.   memcpy (&x, &a, FIXED_SIZE);
  82.   memcpy (&y, &b, FIXED_SIZE);
  83.   z = x + (UINT_C_TYPE) y;
  84.   if ((((x ^ y) >> I_F_BITS) & 1) == 0)
  85.     {
  86.       if (((z ^ x) >> I_F_BITS) & 1)
  87.         {
  88.           z = ((UINT_C_TYPE) 1) << I_F_BITS;
  89.           if (x >= 0)
  90.             z -= (UINT_C_TYPE) 1;
  91.         }
  92.     }
  93. #if HAVE_PADDING_BITS
  94.   z = z << PADDING_BITS;
  95.   z = z >> PADDING_BITS;
  96. #endif
  97.   memcpy (&c, &z, FIXED_SIZE);
  98.   return c;
  99. }
  100. #endif /* FIXED_SSADD */
  101.  
  102. #if defined(FIXED_USADD) && defined(L_usadd)
  103. FIXED_C_TYPE
  104. FIXED_USADD (FIXED_C_TYPE a, FIXED_C_TYPE b)
  105. {
  106.   FIXED_C_TYPE c;
  107.   INT_C_TYPE x, y, z;
  108.   memcpy (&x, &a, FIXED_SIZE);
  109.   memcpy (&y, &b, FIXED_SIZE);
  110.   z = x + y;
  111. #if HAVE_PADDING_BITS
  112.   z = z << PADDING_BITS;
  113.   z = z >> PADDING_BITS;
  114. #endif
  115.   if (z < x || z < y) /* max */
  116.     {
  117.        z = -1;
  118. #if HAVE_PADDING_BITS
  119.        z = z << PADDING_BITS;
  120.        z = z >> PADDING_BITS;
  121. #endif
  122.     }
  123.   memcpy (&c, &z, FIXED_SIZE);
  124.   return c;
  125. }
  126. #endif /* FIXED_USADD */
  127.  
  128. #if defined(FIXED_SUB) && defined(L_sub)
  129. FIXED_C_TYPE
  130. FIXED_SUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
  131. {
  132.   FIXED_C_TYPE c;
  133.   INT_C_TYPE x, y, z;
  134.   memcpy (&x, &a, FIXED_SIZE);
  135.   memcpy (&y, &b, FIXED_SIZE);
  136.   z = x - y;
  137. #if HAVE_PADDING_BITS
  138.   z = z << PADDING_BITS;
  139.   z = z >> PADDING_BITS;
  140. #endif
  141.   memcpy (&c, &z, FIXED_SIZE);
  142.   return c;
  143. }
  144. #endif /* FIXED_SUB */
  145.  
  146. #if defined(FIXED_SSSUB) && defined(L_sssub)
  147. FIXED_C_TYPE
  148. FIXED_SSSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
  149. {
  150.   FIXED_C_TYPE c;
  151.   INT_C_TYPE x, y, z;
  152.   memcpy (&x, &a, FIXED_SIZE);
  153.   memcpy (&y, &b, FIXED_SIZE);
  154.   z = x - (UINT_C_TYPE) y;
  155.   if (((x ^ y) >> I_F_BITS) & 1)
  156.     {
  157.       if (((z ^ x) >> I_F_BITS) & 1)
  158.         {
  159.           z = ((UINT_C_TYPE) 1) << I_F_BITS;
  160.           if (x >= 0)
  161.             z -= (UINT_C_TYPE) 1;
  162.         }
  163.     }
  164. #if HAVE_PADDING_BITS
  165.   z = z << PADDING_BITS;
  166.   z = z >> PADDING_BITS;
  167. #endif
  168.   memcpy (&c, &z, FIXED_SIZE);
  169.   return c;
  170. }
  171. #endif /* FIXED_SSSUB */
  172.  
  173. #if defined(FIXED_USSUB) && defined(L_ussub)
  174. FIXED_C_TYPE
  175. FIXED_USSUB (FIXED_C_TYPE a, FIXED_C_TYPE b)
  176. {
  177.   FIXED_C_TYPE c;
  178.   INT_C_TYPE x, y, z;
  179.   memcpy (&x, &a, FIXED_SIZE);
  180.   memcpy (&y, &b, FIXED_SIZE);
  181.   z = x - y;
  182.   if (x < y)
  183.     z = 0;
  184. #if HAVE_PADDING_BITS
  185.   z = z << PADDING_BITS;
  186.   z = z >> PADDING_BITS;
  187. #endif
  188.   memcpy (&c, &z, FIXED_SIZE);
  189.   return c;
  190. }
  191. #endif /* FIXED_USSUB */
  192.  
  193. #if defined(FIXED_SATURATE1) && defined(L_saturate1)
  194. void
  195. FIXED_SATURATE1 (DINT_C_TYPE *a)
  196. {
  197.   DINT_C_TYPE max, min;
  198.   max = (DINT_C_TYPE)1 << I_F_BITS;
  199.   max = max - 1;
  200. #if MODE_UNSIGNED == 0
  201.   min = (DINT_C_TYPE)1 << (2 * FIXED_WIDTH - 1);
  202.   min = min >> (2 * FIXED_WIDTH - 1 - I_F_BITS);
  203. #else
  204.   min = 0;
  205. #endif
  206.   if (*a > max)
  207.     *a = max;
  208.   else if (*a < min)
  209.     *a = min;
  210. }
  211. #endif /* FIXED_SATURATE1 */
  212.  
  213. #if defined(FIXED_SATURATE2) && defined(L_saturate2)
  214. void
  215. FIXED_SATURATE2 (INT_C_TYPE *high, INT_C_TYPE *low)
  216. {
  217.   INT_C_TYPE r_max, s_max, r_min, s_min;
  218.   r_max = 0;
  219. #if (MODE_UNSIGNED == 0) || HAVE_PADDING_BITS
  220.   s_max = (INT_C_TYPE)1 << I_F_BITS;
  221.   s_max = s_max - 1;
  222. #else
  223.   s_max = -1;
  224. #endif
  225. #if MODE_UNSIGNED == 0
  226.   r_min = -1;
  227.   s_min = (INT_C_TYPE)1 << (FIXED_WIDTH - 1);
  228.   s_min = s_min >> (FIXED_WIDTH - 1 - I_F_BITS);
  229. #else
  230.   r_min = 0;
  231.   s_min = 0;
  232. #endif
  233.  
  234.   if (*high > r_max
  235.       || (*high == r_max && (UINT_C_TYPE)(*low) > (UINT_C_TYPE)s_max))
  236.     {
  237.       *high = r_max;
  238.       *low = s_max;
  239.     }
  240.   else if (*high < r_min ||
  241.            (*high == r_min && (UINT_C_TYPE)(*low) < (UINT_C_TYPE)s_min))
  242.     {
  243.       *high = r_min;
  244.       *low = s_min;
  245.     }
  246. }
  247. #endif /* FIXED_SATURATE2 */
  248.  
  249. #if defined(FIXED_MULHELPER) && defined(L_mulhelper)
  250. FIXED_C_TYPE
  251. FIXED_MULHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
  252. {
  253.   FIXED_C_TYPE c;
  254.   INT_C_TYPE x, y;
  255.  
  256. #if defined (DINT_C_TYPE)
  257.   INT_C_TYPE z;
  258.   DINT_C_TYPE dx, dy, dz;
  259.   memcpy (&x, &a, FIXED_SIZE);
  260.   memcpy (&y, &b, FIXED_SIZE);
  261.   dx = (DINT_C_TYPE) x;
  262.   dy = (DINT_C_TYPE) y;
  263.   dz = dx * dy;
  264.   /* Round the result by adding (1 << (FBITS -1)).  */
  265.   dz += ((DINT_C_TYPE) 1 << (FBITS - 1));
  266.   dz = dz >> FBITS;
  267.   if (satp)
  268.     FIXED_SATURATE1 (&dz);
  269.  
  270.   z = (INT_C_TYPE) dz;
  271. #if HAVE_PADDING_BITS
  272.   z = z << PADDING_BITS;
  273.   z = z >> PADDING_BITS;
  274. #endif
  275.   memcpy (&c, &z, FIXED_SIZE);
  276.   return c;
  277.  
  278. #else /* No DINT_C_TYPE */
  279.   /* The result of multiplication expands to two INT_C_TYPE.  */
  280.   INTunion aa, bb;
  281.   INTunion a_high, a_low, b_high, b_low;
  282.   INTunion high_high, high_low, low_high, low_low;
  283.   INTunion r, s, temp1, temp2;
  284.   INT_C_TYPE carry = 0;
  285.   INT_C_TYPE z;
  286.  
  287.   memcpy (&x, &a, FIXED_SIZE);
  288.   memcpy (&y, &b, FIXED_SIZE);
  289.  
  290.   /* Decompose a and b.  */
  291.   aa.ll = x;
  292.   bb.ll = y;
  293.  
  294.   a_high.s.low = aa.s.high;
  295.   a_high.s.high = 0;
  296.   a_low.s.low = aa.s.low;
  297.   a_low.s.high = 0;
  298.   b_high.s.low = bb.s.high;
  299.   b_high.s.high = 0;
  300.   b_low.s.low = bb.s.low;
  301.   b_low.s.high = 0;
  302.  
  303.   /* Perform four multiplications.  */
  304.   low_low.ll = a_low.ll * b_low.ll;
  305.   low_high.ll = a_low.ll * b_high.ll;
  306.   high_low.ll = a_high.ll * b_low.ll;
  307.   high_high.ll = a_high.ll * b_high.ll;
  308.  
  309.   /* Accumulate four results to {r, s}.  */
  310.   temp1.s.high = high_low.s.low;
  311.   temp1.s.low = 0;
  312.   s.ll = low_low.ll + temp1.ll;
  313.   if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) low_low.ll
  314.       || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll)
  315.     carry ++; /* Carry.  */
  316.   temp1.ll = s.ll;
  317.   temp2.s.high = low_high.s.low;
  318.   temp2.s.low = 0;
  319.   s.ll = temp1.ll + temp2.ll;
  320.   if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
  321.       || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp2.ll)
  322.     carry ++; /* Carry.  */
  323.  
  324.   temp1.s.low = high_low.s.high;
  325.   temp1.s.high = 0;
  326.   r.ll = high_high.ll + temp1.ll;
  327.   temp1.s.low = low_high.s.high;
  328.   temp1.s.high = 0;
  329.   r.ll = r.ll + temp1.ll + carry;
  330.  
  331. #if MODE_UNSIGNED == 0
  332.   /* For signed types, we need to add neg(y) to r, if x < 0.  */
  333.   if (x < 0)
  334.     r.ll = r.ll - y;
  335.   /* We need to add neg(x) to r, if y < 0.  */
  336.   if (y < 0)
  337.     r.ll = r.ll - x;
  338. #endif
  339.  
  340.   /* Round the result by adding (1 << (FBITS -1)).  */
  341.   temp1.ll = s.ll;
  342.   s.ll += ((INT_C_TYPE) 1 << (FBITS -1));
  343.   if ((UINT_C_TYPE) s.ll < (UINT_C_TYPE) temp1.ll
  344.       || (UINT_C_TYPE) s.ll < (UINT_C_TYPE) ((INT_C_TYPE) 1 << (FBITS -1)))
  345.     r.ll += 1;
  346.  
  347.   /* Shift right the result by FBITS.  */
  348. #if FBITS == FIXED_WIDTH
  349.   /* This happens only for unsigned types without any padding bits.
  350.      So, it is safe to set r.ll to 0 as it is logically shifted right.  */
  351.   s.ll = r.ll;
  352.   r.ll = 0;
  353. #else
  354.   s.ll = ((UINT_C_TYPE)s.ll) >> FBITS;
  355.   temp1.ll = r.ll << (FIXED_WIDTH - FBITS);
  356.   s.ll = s.ll | temp1.ll;
  357.   r.ll = r.ll >> FBITS;
  358. #endif
  359.  
  360.   if (satp)
  361.     FIXED_SATURATE2 (&r.ll, &s.ll);
  362.  
  363.   z = (INT_C_TYPE) s.ll;
  364. #if HAVE_PADDING_BITS
  365.   z = z << PADDING_BITS;
  366.   z = z >> PADDING_BITS;
  367. #endif
  368.   memcpy (&c, &z, FIXED_SIZE);
  369.   return c;
  370. #endif
  371. }
  372. #endif /* FIXED_MULHELPER */
  373.  
  374. #if defined(FIXED_MUL) && defined(L_mul)
  375. FIXED_C_TYPE
  376. FIXED_MUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
  377. {
  378.   return FIXED_MULHELPER (a, b, 0);
  379. }
  380. #endif /* FIXED_MUL */
  381.  
  382. #if defined(FIXED_SSMUL) && defined(L_ssmul)
  383. FIXED_C_TYPE
  384. FIXED_SSMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
  385. {
  386.   return FIXED_MULHELPER (a, b, 1);
  387. }
  388. #endif /* FIXED_SSMUL */
  389.  
  390. #if defined(FIXED_USMUL) && defined(L_usmul)
  391. FIXED_C_TYPE
  392. FIXED_USMUL (FIXED_C_TYPE a, FIXED_C_TYPE b)
  393. {
  394.   return FIXED_MULHELPER (a, b, 1);
  395. }
  396. #endif /* FIXED_USMUL */
  397.  
  398. #if defined(FIXED_DIVHELPER) && defined(L_divhelper)
  399. FIXED_C_TYPE
  400. FIXED_DIVHELPER (FIXED_C_TYPE a, FIXED_C_TYPE b, word_type satp)
  401. {
  402.   FIXED_C_TYPE c;
  403.   INT_C_TYPE x, y;
  404.   INT_C_TYPE z;
  405.  
  406. #if defined (DINT_C_TYPE)
  407.   DINT_C_TYPE dx, dy, dz;
  408.   memcpy (&x, &a, FIXED_SIZE);
  409.   memcpy (&y, &b, FIXED_SIZE);
  410.   dx = (DINT_C_TYPE) x;
  411.   dy = (DINT_C_TYPE) y;
  412.   dx = dx << FBITS;
  413.   dz = dx / dy;
  414.   if (satp)
  415.     FIXED_SATURATE1 (&dz);
  416.   z = (INT_C_TYPE) dz;
  417. #if HAVE_PADDING_BITS
  418.   z = z << PADDING_BITS;
  419.   z = z >> PADDING_BITS;
  420. #endif
  421.   memcpy (&c, &z, FIXED_SIZE);
  422.   return c;
  423.  
  424. #else /* No DINT_C_TYPE */
  425.   INT_C_TYPE pos_a, pos_b, r, s;
  426.   INT_C_TYPE quo_r, quo_s, mod, temp;
  427.   word_type i;
  428. #if MODE_UNSIGNED == 0
  429.   word_type num_of_neg = 0;
  430. #endif
  431.  
  432.   memcpy (&x, &a, FIXED_SIZE);
  433.   memcpy (&y, &b, FIXED_SIZE);
  434.   pos_a = x;
  435.   pos_b = y;
  436.  
  437. #if MODE_UNSIGNED == 0
  438.   /* If a < 0, negate a.  */
  439.   if (pos_a < 0)
  440.     {
  441.       pos_a = -pos_a;
  442.       num_of_neg ++;
  443.     }
  444.   /* If b < 0, negate b.  */
  445.   if (pos_b < 0)
  446.     {
  447.       pos_b = -pos_b;
  448.       num_of_neg ++;
  449.     }
  450. #endif
  451.  
  452.   /* Left shift pos_a to {r, s} by FBITS.  */
  453. #if FBITS == FIXED_WIDTH
  454.   /* This happens only for unsigned types without any padding bits.  */
  455.   r = pos_a;
  456.   s = 0;
  457. #else
  458.   s = pos_a << FBITS;
  459.   r = pos_a >> (FIXED_WIDTH - FBITS);
  460. #endif
  461.  
  462.   /* Unsigned divide r by pos_b to quo_r.  The remainder is in mod.  */
  463.   quo_r = (UINT_C_TYPE)r / (UINT_C_TYPE)pos_b;
  464.   mod = (UINT_C_TYPE)r % (UINT_C_TYPE)pos_b;
  465.   quo_s = 0;
  466.  
  467.   for (i = 0; i < FIXED_WIDTH; i++)
  468.     {
  469.       /* Record the leftmost bit of mod.  */
  470.       word_type leftmost_mode = (mod >> (FIXED_WIDTH - 1)) & 1;
  471.       /* Shift left mod by 1 bit.  */
  472.       mod = mod << 1;
  473.       /* Test the leftmost bit of s to add to mod.  */
  474.       if ((s >> (FIXED_WIDTH - 1)) & 1)
  475.         mod ++;
  476.       /* Shift left quo_s by 1 bit.  */
  477.       quo_s = quo_s << 1;
  478.       /* Try to calculate (mod - pos_b).  */
  479.       temp = mod - pos_b;
  480.       if (leftmost_mode || (UINT_C_TYPE)mod >= (UINT_C_TYPE)pos_b)
  481.         {
  482.           quo_s ++;
  483.           mod = temp;
  484.         }
  485.       /* Shift left s by 1 bit.  */
  486.       s = s << 1;
  487.     }
  488.  
  489. #if MODE_UNSIGNED == 0
  490.     if (num_of_neg == 1)
  491.       {
  492.         quo_s = -quo_s;
  493.         if (quo_s == 0)
  494.           quo_r = -quo_r;
  495.         else
  496.           quo_r = ~quo_r;
  497.       }
  498. #endif
  499.   if (satp)
  500.     FIXED_SATURATE2 (&quo_r, &quo_s);
  501.   z = quo_s;
  502. #if HAVE_PADDING_BITS
  503.   z = z << PADDING_BITS;
  504.   z = z >> PADDING_BITS;
  505. #endif
  506.   memcpy (&c, &z, FIXED_SIZE);
  507.   return c;
  508. #endif
  509. }
  510. #endif /* FIXED_DIVHELPER */
  511.  
  512. #if defined(FIXED_DIV) && defined(L_div)
  513. FIXED_C_TYPE
  514. FIXED_DIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
  515. {
  516.   return FIXED_DIVHELPER (a, b, 0);
  517. }
  518. #endif /* FIXED_DIV */
  519.  
  520.  
  521. #if defined(FIXED_UDIV) && defined(L_udiv)
  522. FIXED_C_TYPE
  523. FIXED_UDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
  524. {
  525.   return FIXED_DIVHELPER (a, b, 0);
  526. }
  527. #endif /* FIXED_UDIV */
  528.  
  529. #if defined(FIXED_SSDIV) && defined(L_ssdiv)
  530. FIXED_C_TYPE
  531. FIXED_SSDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
  532. {
  533.   return FIXED_DIVHELPER (a, b, 1);
  534. }
  535. #endif /* FIXED_SSDIV */
  536.  
  537. #if defined(FIXED_USDIV) && defined(L_usdiv)
  538. FIXED_C_TYPE
  539. FIXED_USDIV (FIXED_C_TYPE a, FIXED_C_TYPE b)
  540. {
  541.   return FIXED_DIVHELPER (a, b, 1);
  542. }
  543. #endif /* FIXED_USDIV */
  544.  
  545. #if defined(FIXED_NEG) && defined(L_neg)
  546. FIXED_C_TYPE
  547. FIXED_NEG (FIXED_C_TYPE a)
  548. {
  549.   FIXED_C_TYPE c;
  550.   INT_C_TYPE x, z;
  551.   memcpy (&x, &a, FIXED_SIZE);
  552.   z = -x;
  553. #if HAVE_PADDING_BITS
  554.   z = z << PADDING_BITS;
  555.   z = z >> PADDING_BITS;
  556. #endif
  557.   memcpy (&c, &z, FIXED_SIZE);
  558.   return c;
  559. }
  560. #endif /* FIXED_NEG */
  561.  
  562. #if defined(FIXED_SSNEG) && defined(L_ssneg)
  563. FIXED_C_TYPE
  564. FIXED_SSNEG (FIXED_C_TYPE a)
  565. {
  566.   FIXED_C_TYPE c;
  567.   INT_C_TYPE x, y, z;
  568.   memcpy (&y, &a, FIXED_SIZE);
  569.   x = 0;
  570.   z = x - (UINT_C_TYPE) y;
  571.   if (((x ^ y) >> I_F_BITS) & 1)
  572.     {
  573.       if (((z ^ x) >> I_F_BITS) & 1)
  574.         z = (((UINT_C_TYPE) 1) << I_F_BITS) - 1;
  575.     }
  576. #if HAVE_PADDING_BITS
  577.   z = z << PADDING_BITS;
  578.   z = z >> PADDING_BITS;
  579. #endif
  580.   memcpy (&c, &z, FIXED_SIZE);
  581.   return c;
  582. }
  583. #endif /* FIXED_SSNEG */
  584.  
  585. #if defined(FIXED_USNEG) && defined(L_usneg)
  586. FIXED_C_TYPE
  587. FIXED_USNEG (FIXED_C_TYPE a __attribute__ ((__unused__)))
  588. {
  589.   FIXED_C_TYPE c;
  590.   INT_C_TYPE z;
  591.   z = 0;
  592.   memcpy (&c, &z, FIXED_SIZE);
  593.   return c;
  594. }
  595. #endif /* FIXED_USNEG */
  596.  
  597. #if defined(FIXED_ASHLHELPER) && defined(L_ashlhelper)
  598. FIXED_C_TYPE
  599. FIXED_ASHLHELPER (FIXED_C_TYPE a, word_type b, word_type satp)
  600. {
  601.   FIXED_C_TYPE c;
  602.   INT_C_TYPE x, z;
  603.  
  604. #if defined (DINT_C_TYPE)
  605.   DINT_C_TYPE dx, dz;
  606.   memcpy (&x, &a, FIXED_SIZE);
  607.   dx = (DINT_C_TYPE) x;
  608.   if (b >= FIXED_WIDTH)
  609.     dz = dx << FIXED_WIDTH;
  610.   else
  611.     dz = dx << b;
  612.   if (satp)
  613.     FIXED_SATURATE1 (&dz);
  614.   z = (INT_C_TYPE) dz;
  615. #if HAVE_PADDING_BITS
  616.   z = z << PADDING_BITS;
  617.   z = z >> PADDING_BITS;
  618. #endif
  619.   memcpy (&c, &z, FIXED_SIZE);
  620.   return c;
  621.  
  622. #else /* No DINT_C_TYPE */
  623.   INT_C_TYPE r, s;
  624.   memcpy (&x, &a, FIXED_SIZE);
  625.   /* We need to shift left x by b bits to {r, s}.  */
  626.   if (b >= FIXED_WIDTH)
  627.     {
  628.       r = b;
  629.       s = 0;
  630.     }
  631.   else
  632.     {
  633.       s = x << b;
  634.       r = x >> (FIXED_WIDTH - b);
  635.     }
  636.   if (satp)
  637.     FIXED_SATURATE2 (&r, &s);
  638.   z = s;
  639. #if HAVE_PADDING_BITS
  640.   z = z << PADDING_BITS;
  641.   z = z >> PADDING_BITS;
  642. #endif
  643.   memcpy (&c, &z, FIXED_SIZE);
  644.   return c;
  645. #endif
  646. }
  647. #endif /* FIXED_ASHLHELPER */
  648.  
  649. #if defined(FIXED_ASHL) && defined(L_ashl)
  650. FIXED_C_TYPE
  651. FIXED_ASHL (FIXED_C_TYPE a, word_type b)
  652. {
  653.   return FIXED_ASHLHELPER (a, b, 0);
  654. }
  655. #endif /* FIXED_ASHL */
  656.  
  657. #if defined(FIXED_ASHR) && defined(L_ashr)
  658. FIXED_C_TYPE
  659. FIXED_ASHR (FIXED_C_TYPE a, word_type b)
  660. {
  661.   FIXED_C_TYPE c;
  662.   INT_C_TYPE x, z;
  663.   memcpy (&x, &a, FIXED_SIZE);
  664.   z = x >> b;
  665. #if HAVE_PADDING_BITS
  666.   z = z << PADDING_BITS;
  667.   z = z >> PADDING_BITS;
  668. #endif
  669.   memcpy (&c, &z, FIXED_SIZE);
  670.   return c;
  671. }
  672. #endif /* FIXED_ASHR */
  673.  
  674. #if defined(FIXED_LSHR) && defined(L_lshr)
  675. FIXED_C_TYPE
  676. FIXED_LSHR (FIXED_C_TYPE a, word_type b)
  677. {
  678.   FIXED_C_TYPE c;
  679.   INT_C_TYPE x, z;
  680.   memcpy (&x, &a, FIXED_SIZE);
  681.   z = x >> b;
  682. #if HAVE_PADDING_BITS
  683.   z = z << PADDING_BITS;
  684.   z = z >> PADDING_BITS;
  685. #endif
  686.   memcpy (&c, &z, FIXED_SIZE);
  687.   return c;
  688. }
  689. #endif /* FIXED_LSHR */
  690.  
  691. #if defined(FIXED_SSASHL) && defined(L_ssashl)
  692. FIXED_C_TYPE
  693. FIXED_SSASHL (FIXED_C_TYPE a, word_type b)
  694. {
  695.   return FIXED_ASHLHELPER (a, b, 1);
  696. }
  697. #endif /* FIXED_SSASHL */
  698.  
  699. #if defined(FIXED_USASHL) && defined(L_usashl)
  700. FIXED_C_TYPE
  701. FIXED_USASHL (FIXED_C_TYPE a, word_type b)
  702. {
  703.   return FIXED_ASHLHELPER (a, b, 1);
  704. }
  705. #endif /* FIXED_USASHL */
  706.  
  707. #if defined(FIXED_CMP) && defined(L_cmp)
  708. word_type
  709. FIXED_CMP (FIXED_C_TYPE a, FIXED_C_TYPE b)
  710. {
  711.   INT_C_TYPE x, y;
  712.   memcpy (&x, &a, FIXED_SIZE);
  713.   memcpy (&y, &b, FIXED_SIZE);
  714.  
  715.   if (x < y)
  716.     return 0;
  717.   else if (x > y)
  718.     return 2;
  719.  
  720.   return 1;
  721. }
  722. #endif /* FIXED_CMP */
  723.  
  724. /* Fixed -> Fixed.  */
  725. #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 4
  726. TO_FIXED_C_TYPE
  727. FRACT (FROM_FIXED_C_TYPE a)
  728. {
  729.   TO_FIXED_C_TYPE c;
  730.   FROM_INT_C_TYPE x;
  731.   TO_INT_C_TYPE z;
  732.   int shift_amount;
  733.   memcpy (&x, &a, FROM_FIXED_SIZE);
  734. #if TO_FBITS > FROM_FBITS  /* Need left shift.  */
  735.   shift_amount = TO_FBITS - FROM_FBITS;
  736.   z = (TO_INT_C_TYPE) x;
  737.   z = z << shift_amount;
  738. #else /* TO_FBITS <= FROM_FBITS.  Need right Shift.  */
  739.   shift_amount = FROM_FBITS - TO_FBITS;
  740.   x = x >> shift_amount;
  741.   z = (TO_INT_C_TYPE) x;
  742. #endif /* TO_FBITS > FROM_FBITS  */
  743.  
  744. #if TO_HAVE_PADDING_BITS
  745.   z = z << TO_PADDING_BITS;
  746.   z = z >> TO_PADDING_BITS;
  747. #endif
  748.   memcpy (&c, &z, TO_FIXED_SIZE);
  749.   return c;
  750. }
  751. #endif /* FRACT && FROM_TYPE == 4 && TO_TYPE == 4  */
  752.  
  753. /* Fixed -> Fixed with saturation.  */
  754. #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 4 && TO_TYPE == 4
  755. TO_FIXED_C_TYPE
  756. SATFRACT (FROM_FIXED_C_TYPE a)
  757. {
  758.   TO_FIXED_C_TYPE c;
  759.   TO_INT_C_TYPE z;
  760.   FROM_INT_C_TYPE x;
  761. #if FROM_MODE_UNSIGNED == 0
  762.   BIG_SINT_C_TYPE high, low;
  763.   BIG_SINT_C_TYPE max_high, max_low;
  764. #if TO_MODE_UNSIGNED == 0
  765.   BIG_SINT_C_TYPE min_high, min_low;
  766. #endif
  767. #else
  768.   BIG_UINT_C_TYPE high, low;
  769.   BIG_UINT_C_TYPE max_high, max_low;
  770. #endif
  771. #if TO_FBITS > FROM_FBITS
  772.   BIG_UINT_C_TYPE utemp;
  773. #endif
  774. #if TO_MODE_UNSIGNED == 0
  775.   BIG_SINT_C_TYPE stemp;
  776. #endif
  777. #if TO_FBITS != FROM_FBITS
  778.   int shift_amount;
  779. #endif
  780.   memcpy (&x, &a, FROM_FIXED_SIZE);
  781.  
  782.   /* Step 1. We need to store x to {high, low}.  */
  783. #if FROM_MODE_UNSIGNED == 0
  784.   low = (BIG_SINT_C_TYPE) x;
  785.   if (x < 0)
  786.     high = -1;
  787.   else
  788.     high = 0;
  789. #else
  790.   low = (BIG_UINT_C_TYPE) x;
  791.   high = 0;
  792. #endif
  793.  
  794.   /* Step 2. We need to shift {high, low}.  */
  795. #if TO_FBITS > FROM_FBITS /* Left shift.  */
  796.   shift_amount = TO_FBITS - FROM_FBITS;
  797.   utemp = (BIG_UINT_C_TYPE) low;
  798.   utemp = utemp >> (BIG_WIDTH - shift_amount);
  799.   high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
  800.   low = low << shift_amount;
  801. #elif TO_FBITS < FROM_FBITS /* Right shift.  */
  802.   shift_amount = FROM_FBITS - TO_FBITS;
  803.   low = low >> shift_amount;
  804. #endif
  805.  
  806.   /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
  807.   max_high = 0;
  808. #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
  809.   max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
  810.   max_low = max_low - 1;
  811. #else
  812.   max_low = -1;
  813. #endif
  814.  
  815. #if TO_MODE_UNSIGNED == 0
  816.   stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
  817.   stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
  818. #if FROM_MODE_UNSIGNED == 0
  819.   min_high = -1;
  820.   min_low = stemp;
  821. #endif
  822. #endif
  823.  
  824. #if FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 0
  825.   /* Signed -> Signed.  */
  826.   if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
  827.       || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
  828.           && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  829.     low = max_low; /* Maximum.  */
  830.   else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
  831.            || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
  832.                && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
  833.     low = min_low; /* Minimum.  */
  834. #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 1
  835.   /* Unigned -> Unsigned.  */
  836.   if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
  837.       || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
  838.           && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  839.     low = max_low; /* Maximum.  */
  840. #elif FROM_MODE_UNSIGNED == 0 && TO_MODE_UNSIGNED == 1
  841.   /* Signed -> Unsigned.  */
  842.   if (x < 0)
  843.     low = 0; /* Minimum.  */
  844.   else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
  845.            || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
  846.                && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  847.     low = max_low; /* Maximum.  */
  848. #elif FROM_MODE_UNSIGNED == 1 && TO_MODE_UNSIGNED == 0
  849.   /* Unsigned -> Signed.  */
  850.   if ((BIG_SINT_C_TYPE) high < 0)
  851.     low = max_low; /* Maximum.  */
  852.   else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
  853.            || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
  854.                && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  855.     low = max_low; /* Maximum.  */
  856. #endif
  857.  
  858.   /* Step 4. Store the result.  */
  859.   z = (TO_INT_C_TYPE) low;
  860. #if TO_HAVE_PADDING_BITS
  861.   z = z << TO_PADDING_BITS;
  862.   z = z >> TO_PADDING_BITS;
  863. #endif
  864.   memcpy (&c, &z, TO_FIXED_SIZE);
  865.   return c;
  866. }
  867. #endif /* defined(SATFRACT) && FROM_TYPE == 4 && TO_TYPE == 4  */
  868.  
  869. /* Fixed -> Int.  */
  870. #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 1
  871. TO_INT_C_TYPE
  872. FRACT (FROM_FIXED_C_TYPE a)
  873. {
  874.   FROM_INT_C_TYPE x;
  875.   TO_INT_C_TYPE z;
  876.   FROM_INT_C_TYPE i = 0;
  877.   memcpy (&x, &a, FROM_FIXED_SIZE);
  878.  
  879. #if FROM_MODE_UNSIGNED == 0
  880.   if (x < 0)
  881.     {
  882. #if FROM_FIXED_WIDTH == FROM_FBITS
  883.       if (x != 0)
  884.         i = 1;
  885. #else
  886.       if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
  887.         i = 1;
  888. #endif
  889.     }
  890. #endif
  891.  
  892. #if FROM_FIXED_WIDTH == FROM_FBITS
  893.   x = 0;
  894. #else
  895.   x = x >> FROM_FBITS;
  896. #endif
  897.   x = x + i;
  898.   z = (TO_INT_C_TYPE) x;
  899.   return z;
  900. }
  901. #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 1  */
  902.  
  903. /* Fixed -> Unsigned int.  */
  904. #if defined(FRACTUNS) && defined(L_fractuns) && FROM_TYPE == 4 && TO_TYPE == 2
  905. TO_INT_C_TYPE
  906. FRACTUNS (FROM_FIXED_C_TYPE a)
  907. {
  908.   FROM_INT_C_TYPE x;
  909.   TO_INT_C_TYPE z;
  910.   FROM_INT_C_TYPE i = 0;
  911.   memcpy (&x, &a, FROM_FIXED_SIZE);
  912.  
  913. #if FROM_MODE_UNSIGNED == 0
  914.   if (x < 0)
  915.     {
  916. #if FROM_FIXED_WIDTH == FROM_FBITS
  917.       if (x != 0)
  918.         i = 1;
  919. #else
  920.       if (((FROM_INT_C_TYPE)(x << (FROM_FIXED_WIDTH - FROM_FBITS))) != 0)
  921.         i = 1;
  922. #endif
  923.     }
  924. #endif
  925.  
  926. #if FROM_FIXED_WIDTH == FROM_FBITS
  927.   x = 0;
  928. #else
  929.   x = x >> FROM_FBITS;
  930. #endif
  931.   x = x + i;
  932.   z = (TO_INT_C_TYPE) x;
  933.   return z;
  934. }
  935. #endif /* defined(FRACTUNS) && FROM_TYPE == 4 && TO_TYPE == 2  */
  936.  
  937. /* Int -> Fixed.  */
  938. #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 1 && TO_TYPE == 4
  939. TO_FIXED_C_TYPE
  940. FRACT (FROM_INT_C_TYPE a)
  941. {
  942.   TO_FIXED_C_TYPE c;
  943.   TO_INT_C_TYPE z;
  944.   z = (TO_INT_C_TYPE) a;
  945. #if TO_FIXED_WIDTH == TO_FBITS
  946.   z = 0;
  947. #else
  948.   z = z << TO_FBITS;
  949. #endif
  950. #if TO_HAVE_PADDING_BITS
  951.   z = z << TO_PADDING_BITS;
  952.   z = z >> TO_PADDING_BITS;
  953. #endif
  954.   memcpy (&c, &z, TO_FIXED_SIZE);
  955.   return c;
  956. }
  957. #endif /* defined(FRACT) && FROM_TYPE == 1 && TO_TYPE == 4  */
  958.  
  959. /* Signed int -> Fixed with saturation.  */
  960. #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 1 && TO_TYPE == 4
  961. TO_FIXED_C_TYPE
  962. SATFRACT (FROM_INT_C_TYPE a)
  963. {
  964.   TO_FIXED_C_TYPE c;
  965.   TO_INT_C_TYPE z;
  966.   FROM_INT_C_TYPE x = a;
  967.   BIG_SINT_C_TYPE high, low;
  968.   BIG_SINT_C_TYPE max_high, max_low;
  969. #if TO_MODE_UNSIGNED == 0
  970.   BIG_SINT_C_TYPE min_high, min_low;
  971.   BIG_SINT_C_TYPE stemp;
  972. #endif
  973. #if BIG_WIDTH != TO_FBITS
  974.   BIG_UINT_C_TYPE utemp;
  975.   int shift_amount;
  976. #endif
  977.  
  978.   /* Step 1. We need to store x to {high, low}.  */
  979.   low = (BIG_SINT_C_TYPE) x;
  980.   if (x < 0)
  981.     high = -1;
  982.   else
  983.     high = 0;
  984.  
  985.   /* Step 2. We need to left shift {high, low}.  */
  986. #if BIG_WIDTH == TO_FBITS
  987.   high = low;
  988.   low = 0;
  989. #else
  990.   shift_amount = TO_FBITS;
  991.   utemp = (BIG_UINT_C_TYPE) low;
  992.   utemp = utemp >> (BIG_WIDTH - shift_amount);
  993.   high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
  994.   low = low << shift_amount;
  995. #endif
  996.  
  997.   /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
  998.   max_high = 0;
  999. #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
  1000.   max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
  1001.   max_low = max_low - 1;
  1002. #else
  1003.   max_low = -1;
  1004. #endif
  1005.  
  1006. #if TO_MODE_UNSIGNED == 0
  1007.   min_high = -1;
  1008.   stemp = (BIG_SINT_C_TYPE)1 << (BIG_WIDTH - 1);
  1009.   stemp = stemp >> (BIG_WIDTH - 1 - TO_I_F_BITS);
  1010.   min_low = stemp;
  1011.  
  1012.   /* Signed -> Signed.  */
  1013.   if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
  1014.       || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
  1015.           && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  1016.     low = max_low; /* Maximum.  */
  1017.   else if ((BIG_SINT_C_TYPE) high < (BIG_SINT_C_TYPE) min_high
  1018.            || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) min_high
  1019.                && (BIG_UINT_C_TYPE) low < (BIG_UINT_C_TYPE) min_low))
  1020.     low = min_low; /* Minimum.  */
  1021. #else
  1022.   /* Signed -> Unsigned.  */
  1023.   if (x < 0)
  1024.     low = 0; /* Minimum.  */
  1025.   else if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
  1026.            || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
  1027.                && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  1028.     low = max_low; /* Maximum.  */
  1029. #endif
  1030.  
  1031.   /* Step 4. Store the result.  */
  1032.   z = (TO_INT_C_TYPE) low;
  1033. #if TO_HAVE_PADDING_BITS
  1034.   z = z << TO_PADDING_BITS;
  1035.   z = z >> TO_PADDING_BITS;
  1036. #endif
  1037.   memcpy (&c, &z, TO_FIXED_SIZE);
  1038.   return c;
  1039. }
  1040. #endif /* defined(SATFRACT) && FROM_TYPE == 1 && TO_TYPE == 4  */
  1041.  
  1042. /* Unsigned int -> Fixed.  */
  1043. #if defined(FRACTUNS) && defined(L_fractuns) &&FROM_TYPE == 2 && TO_TYPE == 4
  1044. TO_FIXED_C_TYPE
  1045. FRACTUNS (FROM_INT_C_TYPE a)
  1046. {
  1047.   TO_FIXED_C_TYPE c;
  1048.   TO_INT_C_TYPE z;
  1049.   z = (TO_INT_C_TYPE) a;
  1050. #if TO_FIXED_WIDTH == TO_FBITS
  1051.   z = 0;
  1052. #else
  1053.   z = z << TO_FBITS;
  1054. #endif
  1055. #if TO_HAVE_PADDING_BITS
  1056.   z = z << TO_PADDING_BITS;
  1057.   z = z >> TO_PADDING_BITS;
  1058. #endif
  1059.   memcpy (&c, &z, TO_FIXED_SIZE);
  1060.   return c;
  1061. }
  1062. #endif /* defined(FRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4  */
  1063.  
  1064. /* Unsigned int -> Fixed with saturation.  */
  1065. #if defined(SATFRACTUNS) && defined(L_satfractuns) && FROM_TYPE == 2 && TO_TYPE == 4
  1066. TO_FIXED_C_TYPE
  1067. SATFRACTUNS (FROM_INT_C_TYPE a)
  1068. {
  1069.   TO_FIXED_C_TYPE c;
  1070.   TO_INT_C_TYPE z;
  1071.   FROM_INT_C_TYPE x = a;
  1072.   BIG_UINT_C_TYPE high, low;
  1073.   BIG_UINT_C_TYPE max_high, max_low;
  1074. #if BIG_WIDTH != TO_FBITS
  1075.   BIG_UINT_C_TYPE utemp;
  1076.   int shift_amount;
  1077. #endif
  1078.  
  1079.   /* Step 1. We need to store x to {high, low}.  */
  1080.   low = (BIG_UINT_C_TYPE) x;
  1081.   high = 0;
  1082.  
  1083.   /* Step 2. We need to left shift {high, low}.  */
  1084. #if BIG_WIDTH == TO_FBITS
  1085.   high = low;
  1086.   low = 0;
  1087. #else
  1088.   shift_amount = TO_FBITS;
  1089.   utemp = (BIG_UINT_C_TYPE) low;
  1090.   utemp = utemp >> (BIG_WIDTH - shift_amount);
  1091.   high = ((BIG_UINT_C_TYPE)(high << shift_amount)) | utemp;
  1092.   low = low << shift_amount;
  1093. #endif
  1094.  
  1095.   /* Step 3. Compare {high, low} with max and  min of TO_FIXED_C_TYPE.  */
  1096.   max_high = 0;
  1097. #if BIG_WIDTH > TO_FIXED_WIDTH || TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
  1098.   max_low = (BIG_UINT_C_TYPE)1 << TO_I_F_BITS;
  1099.   max_low = max_low - 1;
  1100. #else
  1101.   max_low = -1;
  1102. #endif
  1103.  
  1104. #if TO_MODE_UNSIGNED == 1
  1105.   /* Unigned -> Unsigned.  */
  1106.   if ((BIG_UINT_C_TYPE) high > (BIG_UINT_C_TYPE) max_high
  1107.       || ((BIG_UINT_C_TYPE) high == (BIG_UINT_C_TYPE) max_high
  1108.           && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  1109.     low = max_low; /* Maximum.  */
  1110. #else
  1111.   /* Unsigned -> Signed.  */
  1112.   if ((BIG_SINT_C_TYPE) high < 0)
  1113.     low = max_low; /* Maximum.  */
  1114.   else if ((BIG_SINT_C_TYPE) high > (BIG_SINT_C_TYPE) max_high
  1115.            || ((BIG_SINT_C_TYPE) high == (BIG_SINT_C_TYPE) max_high
  1116.                && (BIG_UINT_C_TYPE) low > (BIG_UINT_C_TYPE) max_low))
  1117.     low = max_low; /* Maximum.  */
  1118. #endif
  1119.  
  1120.   /* Step 4. Store the result.  */
  1121.   z = (TO_INT_C_TYPE) low;
  1122. #if TO_HAVE_PADDING_BITS
  1123.   z = z << TO_PADDING_BITS;
  1124.   z = z >> TO_PADDING_BITS;
  1125. #endif
  1126.   memcpy (&c, &z, TO_FIXED_SIZE);
  1127.   return c;
  1128. }
  1129. #endif /* defined(SATFRACTUNS) && FROM_TYPE == 2 && TO_TYPE == 4  */
  1130.  
  1131. /* Fixed -> Float.  */
  1132. #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 4 && TO_TYPE == 3
  1133. TO_FLOAT_C_TYPE
  1134. FRACT (FROM_FIXED_C_TYPE a)
  1135. {
  1136.   FROM_INT_C_TYPE x;
  1137.   TO_FLOAT_C_TYPE z;
  1138.   memcpy (&x, &a, FROM_FIXED_SIZE);
  1139.   z = (TO_FLOAT_C_TYPE) x;
  1140.   z = z / BASE;
  1141.   return z;
  1142. }
  1143. #endif /* defined(FRACT) && FROM_TYPE == 4 && TO_TYPE == 3  */
  1144.  
  1145. /* Float -> Fixed.  */
  1146. #if defined(FRACT) && defined(L_fract) && FROM_TYPE == 3 && TO_TYPE == 4
  1147. TO_FIXED_C_TYPE
  1148. FRACT (FROM_FLOAT_C_TYPE a)
  1149. {
  1150.   FROM_FLOAT_C_TYPE temp;
  1151.   TO_INT_C_TYPE z;
  1152.   TO_FIXED_C_TYPE c;
  1153.  
  1154.   temp = a * BASE;
  1155.   z = (TO_INT_C_TYPE) temp;
  1156. #if TO_HAVE_PADDING_BITS
  1157.   z = z << TO_PADDING_BITS;
  1158.   z = z >> TO_PADDING_BITS;
  1159. #endif
  1160.   memcpy (&c, &z, TO_FIXED_SIZE);
  1161.   return c;
  1162. }
  1163. #endif /* defined(FRACT) && FROM_TYPE == 3 && TO_TYPE == 4  */
  1164.  
  1165. /* Float -> Fixed with saturation.  */
  1166. #if defined(SATFRACT) && defined(L_satfract) && FROM_TYPE == 3 && TO_TYPE == 4
  1167. TO_FIXED_C_TYPE
  1168. SATFRACT (FROM_FLOAT_C_TYPE a)
  1169. {
  1170.   FROM_FLOAT_C_TYPE temp;
  1171.   TO_INT_C_TYPE z;
  1172.   TO_FIXED_C_TYPE c;
  1173.  
  1174.   if (a >= FIXED_MAX)
  1175.     {
  1176. #if TO_MODE_UNSIGNED == 0 || TO_HAVE_PADDING_BITS
  1177.       z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
  1178.       z = z - 1;
  1179. #else
  1180.       z = -1;
  1181. #endif
  1182.     }
  1183.   else if (a <= FIXED_MIN)
  1184.     {
  1185. #if TO_MODE_UNSIGNED == 0
  1186.       z = (TO_INT_C_TYPE)1 << TO_I_F_BITS;
  1187. #else
  1188.       z = 0;
  1189. #endif
  1190.     }
  1191.   else
  1192.     {
  1193.       temp = a * BASE;
  1194.       z = (TO_INT_C_TYPE) temp;
  1195.     }
  1196.  
  1197. #if TO_HAVE_PADDING_BITS
  1198.   z = z << TO_PADDING_BITS;
  1199.   z = z >> TO_PADDING_BITS;
  1200. #endif
  1201.   memcpy (&c, &z, TO_FIXED_SIZE);
  1202.   return c;
  1203. }
  1204. #endif /* defined(SATFRACT) && FROM_TYPE == 3 && TO_TYPE == 4  */
  1205.  
  1206.