Home | History | Annotate | Line # | Download | only in libgcc
fixed-bit.c revision 1.1.1.1
      1 /* This is a software fixed-point library.
      2    Copyright (C) 2007-2013 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 (at) 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