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