OSDN Git Service

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