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