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