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