Mercurial > hg > CbC > CbC_gcc
annotate gcc/fixed-value.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
rev | line source |
---|---|
0 | 1 /* Fixed-point arithmetic support. |
145 | 2 Copyright (C) 2006-2020 Free Software Foundation, Inc. |
0 | 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 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
23 #include "tm.h" | |
24 #include "tree.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
25 #include "diagnostic-core.h" |
0 | 26 |
27 /* Compare two fixed objects for bitwise identity. */ | |
28 | |
29 bool | |
30 fixed_identical (const FIXED_VALUE_TYPE *a, const FIXED_VALUE_TYPE *b) | |
31 { | |
32 return (a->mode == b->mode | |
33 && a->data.high == b->data.high | |
34 && a->data.low == b->data.low); | |
35 } | |
36 | |
37 /* Calculate a hash value. */ | |
38 | |
39 unsigned int | |
40 fixed_hash (const FIXED_VALUE_TYPE *f) | |
41 { | |
42 return (unsigned int) (f->data.low ^ f->data.high); | |
43 } | |
44 | |
45 /* Define the enum code for the range of the fixed-point value. */ | |
46 enum fixed_value_range_code { | |
47 FIXED_OK, /* The value is within the range. */ | |
48 FIXED_UNDERFLOW, /* The value is less than the minimum. */ | |
49 FIXED_GT_MAX_EPS, /* The value is greater than the maximum, but not equal | |
50 to the maximum plus the epsilon. */ | |
51 FIXED_MAX_EPS /* The value equals the maximum plus the epsilon. */ | |
52 }; | |
53 | |
54 /* Check REAL_VALUE against the range of the fixed-point mode. | |
55 Return FIXED_OK, if it is within the range. | |
56 FIXED_UNDERFLOW, if it is less than the minimum. | |
57 FIXED_GT_MAX_EPS, if it is greater than the maximum, but not equal to | |
58 the maximum plus the epsilon. | |
59 FIXED_MAX_EPS, if it is equal to the maximum plus the epsilon. */ | |
60 | |
61 static enum fixed_value_range_code | |
111 | 62 check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, machine_mode mode) |
0 | 63 { |
64 REAL_VALUE_TYPE max_value, min_value, epsilon_value; | |
65 | |
111 | 66 real_2expN (&max_value, GET_MODE_IBIT (mode), VOIDmode); |
67 real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), VOIDmode); | |
0 | 68 |
69 if (SIGNED_FIXED_POINT_MODE_P (mode)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
70 min_value = real_value_negate (&max_value); |
0 | 71 else |
72 real_from_string (&min_value, "0.0"); | |
73 | |
74 if (real_compare (LT_EXPR, real_value, &min_value)) | |
75 return FIXED_UNDERFLOW; | |
76 if (real_compare (EQ_EXPR, real_value, &max_value)) | |
77 return FIXED_MAX_EPS; | |
78 real_arithmetic (&max_value, MINUS_EXPR, &max_value, &epsilon_value); | |
79 if (real_compare (GT_EXPR, real_value, &max_value)) | |
80 return FIXED_GT_MAX_EPS; | |
81 return FIXED_OK; | |
82 } | |
83 | |
111 | 84 |
85 /* Construct a CONST_FIXED from a bit payload and machine mode MODE. | |
86 The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */ | |
87 | |
88 FIXED_VALUE_TYPE | |
89 fixed_from_double_int (double_int payload, scalar_mode mode) | |
90 { | |
91 FIXED_VALUE_TYPE value; | |
92 | |
93 gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT); | |
94 | |
95 if (SIGNED_SCALAR_FIXED_POINT_MODE_P (mode)) | |
96 value.data = payload.sext (1 + GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode)); | |
97 else if (UNSIGNED_SCALAR_FIXED_POINT_MODE_P (mode)) | |
98 value.data = payload.zext (GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode)); | |
99 else | |
100 gcc_unreachable (); | |
101 | |
102 value.mode = mode; | |
103 | |
104 return value; | |
105 } | |
106 | |
107 | |
0 | 108 /* Initialize from a decimal or hexadecimal string. */ |
109 | |
110 void | |
111 | 111 fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, scalar_mode mode) |
0 | 112 { |
113 REAL_VALUE_TYPE real_value, fixed_value, base_value; | |
114 unsigned int fbit; | |
115 enum fixed_value_range_code temp; | |
111 | 116 bool fail; |
0 | 117 |
118 f->mode = mode; | |
119 fbit = GET_MODE_FBIT (mode); | |
120 | |
121 real_from_string (&real_value, str); | |
122 temp = check_real_for_fixed_mode (&real_value, f->mode); | |
123 /* We don't want to warn the case when the _Fract value is 1.0. */ | |
124 if (temp == FIXED_UNDERFLOW | |
125 || temp == FIXED_GT_MAX_EPS | |
126 || (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode))) | |
127 warning (OPT_Woverflow, | |
128 "large fixed-point constant implicitly truncated to fixed-point type"); | |
111 | 129 real_2expN (&base_value, fbit, VOIDmode); |
0 | 130 real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value); |
111 | 131 wide_int w = real_to_integer (&fixed_value, &fail, |
132 GET_MODE_PRECISION (mode)); | |
133 f->data.low = w.ulow (); | |
134 f->data.high = w.elt (1); | |
0 | 135 |
136 if (temp == FIXED_MAX_EPS && ALL_FRACT_MODE_P (f->mode)) | |
137 { | |
138 /* From the spec, we need to evaluate 1 to the maximal value. */ | |
139 f->data.low = -1; | |
140 f->data.high = -1; | |
111 | 141 f->data = f->data.zext (GET_MODE_FBIT (f->mode) |
142 + GET_MODE_IBIT (f->mode)); | |
0 | 143 } |
144 else | |
111 | 145 f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) |
0 | 146 + GET_MODE_FBIT (f->mode) |
147 + GET_MODE_IBIT (f->mode), | |
148 UNSIGNED_FIXED_POINT_MODE_P (f->mode)); | |
149 } | |
150 | |
151 /* Render F as a decimal floating point constant. */ | |
152 | |
153 void | |
154 fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig, | |
155 size_t buf_size) | |
156 { | |
157 REAL_VALUE_TYPE real_value, base_value, fixed_value; | |
158 | |
111 | 159 signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode) ? UNSIGNED : SIGNED; |
160 real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), VOIDmode); | |
161 real_from_integer (&real_value, VOIDmode, | |
162 wide_int::from (f_orig->data, | |
163 GET_MODE_PRECISION (f_orig->mode), sgn), | |
164 sgn); | |
0 | 165 real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value); |
166 real_to_decimal (str, &fixed_value, buf_size, 0, 1); | |
167 } | |
168 | |
169 /* If SAT_P, saturate A to the maximum or the minimum, and save to *F based on | |
170 the machine mode MODE. | |
171 Do not modify *F otherwise. | |
172 This function assumes the width of double_int is greater than the width | |
173 of the fixed-point value (the sum of a possible sign bit, possible ibits, | |
174 and fbits). | |
175 Return true, if !SAT_P and overflow. */ | |
176 | |
177 static bool | |
111 | 178 fixed_saturate1 (machine_mode mode, double_int a, double_int *f, |
0 | 179 bool sat_p) |
180 { | |
181 bool overflow_p = false; | |
182 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode); | |
183 int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode); | |
184 | |
185 if (unsigned_p) /* Unsigned type. */ | |
186 { | |
187 double_int max; | |
188 max.low = -1; | |
189 max.high = -1; | |
111 | 190 max = max.zext (i_f_bits); |
191 if (a.ugt (max)) | |
0 | 192 { |
193 if (sat_p) | |
194 *f = max; | |
195 else | |
196 overflow_p = true; | |
197 } | |
198 } | |
199 else /* Signed type. */ | |
200 { | |
201 double_int max, min; | |
202 max.high = -1; | |
203 max.low = -1; | |
111 | 204 max = max.zext (i_f_bits); |
0 | 205 min.high = 0; |
206 min.low = 1; | |
111 | 207 min = min.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); |
208 min = min.sext (1 + i_f_bits); | |
209 if (a.sgt (max)) | |
0 | 210 { |
211 if (sat_p) | |
212 *f = max; | |
213 else | |
214 overflow_p = true; | |
215 } | |
111 | 216 else if (a.slt (min)) |
0 | 217 { |
218 if (sat_p) | |
219 *f = min; | |
220 else | |
221 overflow_p = true; | |
222 } | |
223 } | |
224 return overflow_p; | |
225 } | |
226 | |
227 /* If SAT_P, saturate {A_HIGH, A_LOW} to the maximum or the minimum, and | |
228 save to *F based on the machine mode MODE. | |
229 Do not modify *F otherwise. | |
230 This function assumes the width of two double_int is greater than the width | |
231 of the fixed-point value (the sum of a possible sign bit, possible ibits, | |
232 and fbits). | |
233 Return true, if !SAT_P and overflow. */ | |
234 | |
235 static bool | |
111 | 236 fixed_saturate2 (machine_mode mode, double_int a_high, double_int a_low, |
0 | 237 double_int *f, bool sat_p) |
238 { | |
239 bool overflow_p = false; | |
240 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode); | |
241 int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode); | |
242 | |
243 if (unsigned_p) /* Unsigned type. */ | |
244 { | |
245 double_int max_r, max_s; | |
246 max_r.high = 0; | |
247 max_r.low = 0; | |
248 max_s.high = -1; | |
249 max_s.low = -1; | |
111 | 250 max_s = max_s.zext (i_f_bits); |
251 if (a_high.ugt (max_r) | |
252 || (a_high == max_r && | |
253 a_low.ugt (max_s))) | |
0 | 254 { |
255 if (sat_p) | |
256 *f = max_s; | |
257 else | |
258 overflow_p = true; | |
259 } | |
260 } | |
261 else /* Signed type. */ | |
262 { | |
263 double_int max_r, max_s, min_r, min_s; | |
264 max_r.high = 0; | |
265 max_r.low = 0; | |
266 max_s.high = -1; | |
267 max_s.low = -1; | |
111 | 268 max_s = max_s.zext (i_f_bits); |
0 | 269 min_r.high = -1; |
270 min_r.low = -1; | |
271 min_s.high = 0; | |
272 min_s.low = 1; | |
111 | 273 min_s = min_s.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); |
274 min_s = min_s.sext (1 + i_f_bits); | |
275 if (a_high.sgt (max_r) | |
276 || (a_high == max_r && | |
277 a_low.ugt (max_s))) | |
0 | 278 { |
279 if (sat_p) | |
280 *f = max_s; | |
281 else | |
282 overflow_p = true; | |
283 } | |
111 | 284 else if (a_high.slt (min_r) |
285 || (a_high == min_r && | |
286 a_low.ult (min_s))) | |
0 | 287 { |
288 if (sat_p) | |
289 *f = min_s; | |
290 else | |
291 overflow_p = true; | |
292 } | |
293 } | |
294 return overflow_p; | |
295 } | |
296 | |
297 /* Return the sign bit based on I_F_BITS. */ | |
298 | |
299 static inline int | |
300 get_fixed_sign_bit (double_int a, int i_f_bits) | |
301 { | |
302 if (i_f_bits < HOST_BITS_PER_WIDE_INT) | |
303 return (a.low >> i_f_bits) & 1; | |
304 else | |
305 return (a.high >> (i_f_bits - HOST_BITS_PER_WIDE_INT)) & 1; | |
306 } | |
307 | |
308 /* Calculate F = A + (SUBTRACT_P ? -B : B). | |
309 If SAT_P, saturate the result to the max or the min. | |
310 Return true, if !SAT_P and overflow. */ | |
311 | |
312 static bool | |
313 do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, | |
314 const FIXED_VALUE_TYPE *b, bool subtract_p, bool sat_p) | |
315 { | |
316 bool overflow_p = false; | |
317 bool unsigned_p; | |
318 double_int temp; | |
319 int i_f_bits; | |
320 | |
321 /* This was a conditional expression but it triggered a bug in | |
322 Sun C 5.5. */ | |
323 if (subtract_p) | |
111 | 324 temp = -b->data; |
0 | 325 else |
326 temp = b->data; | |
327 | |
328 unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); | |
329 i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); | |
330 f->mode = a->mode; | |
111 | 331 f->data = a->data + temp; |
0 | 332 if (unsigned_p) /* Unsigned type. */ |
333 { | |
334 if (subtract_p) /* Unsigned subtraction. */ | |
335 { | |
111 | 336 if (a->data.ult (b->data)) |
0 | 337 { |
338 if (sat_p) | |
339 { | |
340 f->data.high = 0; | |
341 f->data.low = 0; | |
342 } | |
343 else | |
344 overflow_p = true; | |
345 } | |
346 } | |
347 else /* Unsigned addition. */ | |
348 { | |
111 | 349 f->data = f->data.zext (i_f_bits); |
350 if (f->data.ult (a->data) | |
351 || f->data.ult (b->data)) | |
0 | 352 { |
353 if (sat_p) | |
354 { | |
355 f->data.high = -1; | |
356 f->data.low = -1; | |
357 } | |
358 else | |
359 overflow_p = true; | |
360 } | |
361 } | |
362 } | |
363 else /* Signed type. */ | |
364 { | |
365 if ((!subtract_p | |
366 && (get_fixed_sign_bit (a->data, i_f_bits) | |
367 == get_fixed_sign_bit (b->data, i_f_bits)) | |
368 && (get_fixed_sign_bit (a->data, i_f_bits) | |
369 != get_fixed_sign_bit (f->data, i_f_bits))) | |
370 || (subtract_p | |
371 && (get_fixed_sign_bit (a->data, i_f_bits) | |
372 != get_fixed_sign_bit (b->data, i_f_bits)) | |
373 && (get_fixed_sign_bit (a->data, i_f_bits) | |
374 != get_fixed_sign_bit (f->data, i_f_bits)))) | |
375 { | |
376 if (sat_p) | |
377 { | |
378 f->data.low = 1; | |
379 f->data.high = 0; | |
111 | 380 f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); |
0 | 381 if (get_fixed_sign_bit (a->data, i_f_bits) == 0) |
382 { | |
111 | 383 --f->data; |
0 | 384 } |
385 } | |
386 else | |
387 overflow_p = true; | |
388 } | |
389 } | |
111 | 390 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); |
0 | 391 return overflow_p; |
392 } | |
393 | |
394 /* Calculate F = A * B. | |
395 If SAT_P, saturate the result to the max or the min. | |
396 Return true, if !SAT_P and overflow. */ | |
397 | |
398 static bool | |
399 do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, | |
400 const FIXED_VALUE_TYPE *b, bool sat_p) | |
401 { | |
402 bool overflow_p = false; | |
403 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); | |
404 int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); | |
405 f->mode = a->mode; | |
406 if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT) | |
407 { | |
111 | 408 f->data = a->data * b->data; |
409 f->data = f->data.lshift (-GET_MODE_FBIT (f->mode), | |
410 HOST_BITS_PER_DOUBLE_INT, !unsigned_p); | |
0 | 411 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); |
412 } | |
413 else | |
414 { | |
415 /* The result of multiplication expands to two double_int. */ | |
416 double_int a_high, a_low, b_high, b_low; | |
417 double_int high_high, high_low, low_high, low_low; | |
418 double_int r, s, temp1, temp2; | |
419 int carry = 0; | |
420 | |
421 /* Decompose a and b to four double_int. */ | |
422 a_high.low = a->data.high; | |
423 a_high.high = 0; | |
424 a_low.low = a->data.low; | |
425 a_low.high = 0; | |
426 b_high.low = b->data.high; | |
427 b_high.high = 0; | |
428 b_low.low = b->data.low; | |
429 b_low.high = 0; | |
430 | |
431 /* Perform four multiplications. */ | |
111 | 432 low_low = a_low * b_low; |
433 low_high = a_low * b_high; | |
434 high_low = a_high * b_low; | |
435 high_high = a_high * b_high; | |
0 | 436 |
437 /* Accumulate four results to {r, s}. */ | |
438 temp1.high = high_low.low; | |
439 temp1.low = 0; | |
111 | 440 s = low_low + temp1; |
441 if (s.ult (low_low) | |
442 || s.ult (temp1)) | |
0 | 443 carry ++; /* Carry */ |
444 temp1.high = s.high; | |
445 temp1.low = s.low; | |
446 temp2.high = low_high.low; | |
447 temp2.low = 0; | |
111 | 448 s = temp1 + temp2; |
449 if (s.ult (temp1) | |
450 || s.ult (temp2)) | |
0 | 451 carry ++; /* Carry */ |
452 | |
453 temp1.low = high_low.high; | |
454 temp1.high = 0; | |
111 | 455 r = high_high + temp1; |
0 | 456 temp1.low = low_high.high; |
457 temp1.high = 0; | |
111 | 458 r += temp1; |
0 | 459 temp1.low = carry; |
460 temp1.high = 0; | |
111 | 461 r += temp1; |
0 | 462 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
463 /* We need to subtract b from r, if a < 0. */ |
0 | 464 if (!unsigned_p && a->data.high < 0) |
111 | 465 r -= b->data; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
466 /* We need to subtract a from r, if b < 0. */ |
0 | 467 if (!unsigned_p && b->data.high < 0) |
111 | 468 r -= a->data; |
0 | 469 |
470 /* Shift right the result by FBIT. */ | |
111 | 471 if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT) |
0 | 472 { |
473 s.low = r.low; | |
474 s.high = r.high; | |
475 if (unsigned_p) | |
476 { | |
477 r.low = 0; | |
478 r.high = 0; | |
479 } | |
480 else | |
481 { | |
482 r.low = -1; | |
483 r.high = -1; | |
484 } | |
485 f->data.low = s.low; | |
486 f->data.high = s.high; | |
487 } | |
488 else | |
489 { | |
111 | 490 s = s.llshift ((-GET_MODE_FBIT (f->mode)), HOST_BITS_PER_DOUBLE_INT); |
491 f->data = r.llshift ((HOST_BITS_PER_DOUBLE_INT | |
0 | 492 - GET_MODE_FBIT (f->mode)), |
111 | 493 HOST_BITS_PER_DOUBLE_INT); |
0 | 494 f->data.low = f->data.low | s.low; |
495 f->data.high = f->data.high | s.high; | |
496 s.low = f->data.low; | |
497 s.high = f->data.high; | |
111 | 498 r = r.lshift (-GET_MODE_FBIT (f->mode), |
499 HOST_BITS_PER_DOUBLE_INT, !unsigned_p); | |
0 | 500 } |
501 | |
502 overflow_p = fixed_saturate2 (f->mode, r, s, &f->data, sat_p); | |
503 } | |
504 | |
111 | 505 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); |
0 | 506 return overflow_p; |
507 } | |
508 | |
509 /* Calculate F = A / B. | |
510 If SAT_P, saturate the result to the max or the min. | |
511 Return true, if !SAT_P and overflow. */ | |
512 | |
513 static bool | |
514 do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, | |
515 const FIXED_VALUE_TYPE *b, bool sat_p) | |
516 { | |
517 bool overflow_p = false; | |
518 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); | |
519 int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); | |
520 f->mode = a->mode; | |
521 if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT) | |
522 { | |
111 | 523 f->data = a->data.lshift (GET_MODE_FBIT (f->mode), |
524 HOST_BITS_PER_DOUBLE_INT, !unsigned_p); | |
525 f->data = f->data.div (b->data, unsigned_p, TRUNC_DIV_EXPR); | |
0 | 526 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); |
527 } | |
528 else | |
529 { | |
530 double_int pos_a, pos_b, r, s; | |
531 double_int quo_r, quo_s, mod, temp; | |
532 int num_of_neg = 0; | |
533 int i; | |
534 | |
535 /* If a < 0, negate a. */ | |
536 if (!unsigned_p && a->data.high < 0) | |
537 { | |
111 | 538 pos_a = -a->data; |
0 | 539 num_of_neg ++; |
540 } | |
541 else | |
542 pos_a = a->data; | |
543 | |
544 /* If b < 0, negate b. */ | |
545 if (!unsigned_p && b->data.high < 0) | |
546 { | |
111 | 547 pos_b = -b->data; |
0 | 548 num_of_neg ++; |
549 } | |
550 else | |
551 pos_b = b->data; | |
552 | |
553 /* Left shift pos_a to {r, s} by FBIT. */ | |
111 | 554 if (GET_MODE_FBIT (f->mode) == HOST_BITS_PER_DOUBLE_INT) |
0 | 555 { |
556 r = pos_a; | |
557 s.high = 0; | |
558 s.low = 0; | |
559 } | |
560 else | |
561 { | |
111 | 562 s = pos_a.llshift (GET_MODE_FBIT (f->mode), HOST_BITS_PER_DOUBLE_INT); |
563 r = pos_a.llshift (- (HOST_BITS_PER_DOUBLE_INT | |
0 | 564 - GET_MODE_FBIT (f->mode)), |
111 | 565 HOST_BITS_PER_DOUBLE_INT); |
0 | 566 } |
567 | |
568 /* Divide r by pos_b to quo_r. The remainder is in mod. */ | |
111 | 569 quo_r = r.divmod (pos_b, 1, TRUNC_DIV_EXPR, &mod); |
570 quo_s = double_int_zero; | |
0 | 571 |
111 | 572 for (i = 0; i < HOST_BITS_PER_DOUBLE_INT; i++) |
0 | 573 { |
574 /* Record the leftmost bit of mod. */ | |
575 int leftmost_mod = (mod.high < 0); | |
576 | |
577 /* Shift left mod by 1 bit. */ | |
111 | 578 mod = mod.lshift (1); |
0 | 579 |
580 /* Test the leftmost bit of s to add to mod. */ | |
581 if (s.high < 0) | |
582 mod.low += 1; | |
583 | |
584 /* Shift left quo_s by 1 bit. */ | |
111 | 585 quo_s = quo_s.lshift (1); |
0 | 586 |
587 /* Try to calculate (mod - pos_b). */ | |
111 | 588 temp = mod - pos_b; |
0 | 589 |
111 | 590 if (leftmost_mod == 1 || mod.ucmp (pos_b) != -1) |
0 | 591 { |
592 quo_s.low += 1; | |
593 mod = temp; | |
594 } | |
595 | |
596 /* Shift left s by 1 bit. */ | |
111 | 597 s = s.lshift (1); |
0 | 598 |
599 } | |
600 | |
601 if (num_of_neg == 1) | |
602 { | |
111 | 603 quo_s = -quo_s; |
0 | 604 if (quo_s.high == 0 && quo_s.low == 0) |
111 | 605 quo_r = -quo_r; |
0 | 606 else |
607 { | |
608 quo_r.low = ~quo_r.low; | |
609 quo_r.high = ~quo_r.high; | |
610 } | |
611 } | |
612 | |
613 f->data = quo_s; | |
614 overflow_p = fixed_saturate2 (f->mode, quo_r, quo_s, &f->data, sat_p); | |
615 } | |
616 | |
111 | 617 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); |
0 | 618 return overflow_p; |
619 } | |
620 | |
621 /* Calculate F = A << B if LEFT_P. Otherwise, F = A >> B. | |
622 If SAT_P, saturate the result to the max or the min. | |
623 Return true, if !SAT_P and overflow. */ | |
624 | |
625 static bool | |
626 do_fixed_shift (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, | |
627 const FIXED_VALUE_TYPE *b, bool left_p, bool sat_p) | |
628 { | |
629 bool overflow_p = false; | |
630 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); | |
631 int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); | |
632 f->mode = a->mode; | |
633 | |
634 if (b->data.low == 0) | |
635 { | |
636 f->data = a->data; | |
637 return overflow_p; | |
638 } | |
639 | |
640 if (GET_MODE_PRECISION (f->mode) <= HOST_BITS_PER_WIDE_INT || (!left_p)) | |
641 { | |
111 | 642 f->data = a->data.lshift (left_p ? b->data.low : -b->data.low, |
643 HOST_BITS_PER_DOUBLE_INT, !unsigned_p); | |
0 | 644 if (left_p) /* Only left shift saturates. */ |
645 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); | |
646 } | |
647 else /* We need two double_int to store the left-shift result. */ | |
648 { | |
649 double_int temp_high, temp_low; | |
111 | 650 if (b->data.low == HOST_BITS_PER_DOUBLE_INT) |
0 | 651 { |
652 temp_high = a->data; | |
653 temp_low.high = 0; | |
654 temp_low.low = 0; | |
655 } | |
656 else | |
657 { | |
111 | 658 temp_low = a->data.lshift (b->data.low, |
659 HOST_BITS_PER_DOUBLE_INT, !unsigned_p); | |
0 | 660 /* Logical shift right to temp_high. */ |
111 | 661 temp_high = a->data.llshift (b->data.low - HOST_BITS_PER_DOUBLE_INT, |
662 HOST_BITS_PER_DOUBLE_INT); | |
0 | 663 } |
664 if (!unsigned_p && a->data.high < 0) /* Signed-extend temp_high. */ | |
111 | 665 temp_high = temp_high.ext (b->data.low, unsigned_p); |
0 | 666 f->data = temp_low; |
667 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data, | |
668 sat_p); | |
669 } | |
111 | 670 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); |
0 | 671 return overflow_p; |
672 } | |
673 | |
674 /* Calculate F = -A. | |
675 If SAT_P, saturate the result to the max or the min. | |
676 Return true, if !SAT_P and overflow. */ | |
677 | |
678 static bool | |
679 do_fixed_neg (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, bool sat_p) | |
680 { | |
681 bool overflow_p = false; | |
682 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); | |
683 int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); | |
684 f->mode = a->mode; | |
111 | 685 f->data = -a->data; |
686 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); | |
0 | 687 |
688 if (unsigned_p) /* Unsigned type. */ | |
689 { | |
690 if (f->data.low != 0 || f->data.high != 0) | |
691 { | |
692 if (sat_p) | |
693 { | |
694 f->data.low = 0; | |
695 f->data.high = 0; | |
696 } | |
697 else | |
698 overflow_p = true; | |
699 } | |
700 } | |
701 else /* Signed type. */ | |
702 { | |
703 if (!(f->data.high == 0 && f->data.low == 0) | |
704 && f->data.high == a->data.high && f->data.low == a->data.low ) | |
705 { | |
706 if (sat_p) | |
707 { | |
708 /* Saturate to the maximum by subtracting f->data by one. */ | |
709 f->data.low = -1; | |
710 f->data.high = -1; | |
111 | 711 f->data = f->data.zext (i_f_bits); |
0 | 712 } |
713 else | |
714 overflow_p = true; | |
715 } | |
716 } | |
717 return overflow_p; | |
718 } | |
719 | |
720 /* Perform the binary or unary operation described by CODE. | |
721 Note that OP0 and OP1 must have the same mode for binary operators. | |
722 For a unary operation, leave OP1 NULL. | |
723 Return true, if !SAT_P and overflow. */ | |
724 | |
725 bool | |
726 fixed_arithmetic (FIXED_VALUE_TYPE *f, int icode, const FIXED_VALUE_TYPE *op0, | |
727 const FIXED_VALUE_TYPE *op1, bool sat_p) | |
728 { | |
729 switch (icode) | |
730 { | |
731 case NEGATE_EXPR: | |
732 return do_fixed_neg (f, op0, sat_p); | |
733 | |
734 case PLUS_EXPR: | |
735 gcc_assert (op0->mode == op1->mode); | |
736 return do_fixed_add (f, op0, op1, false, sat_p); | |
737 | |
738 case MINUS_EXPR: | |
739 gcc_assert (op0->mode == op1->mode); | |
740 return do_fixed_add (f, op0, op1, true, sat_p); | |
741 | |
742 case MULT_EXPR: | |
743 gcc_assert (op0->mode == op1->mode); | |
744 return do_fixed_multiply (f, op0, op1, sat_p); | |
745 | |
746 case TRUNC_DIV_EXPR: | |
747 gcc_assert (op0->mode == op1->mode); | |
748 return do_fixed_divide (f, op0, op1, sat_p); | |
749 | |
750 case LSHIFT_EXPR: | |
751 return do_fixed_shift (f, op0, op1, true, sat_p); | |
752 | |
753 case RSHIFT_EXPR: | |
754 return do_fixed_shift (f, op0, op1, false, sat_p); | |
755 | |
756 default: | |
757 gcc_unreachable (); | |
758 } | |
759 return false; | |
760 } | |
761 | |
762 /* Compare fixed-point values by tree_code. | |
763 Note that OP0 and OP1 must have the same mode. */ | |
764 | |
765 bool | |
766 fixed_compare (int icode, const FIXED_VALUE_TYPE *op0, | |
767 const FIXED_VALUE_TYPE *op1) | |
768 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
769 enum tree_code code = (enum tree_code) icode; |
0 | 770 gcc_assert (op0->mode == op1->mode); |
771 | |
772 switch (code) | |
773 { | |
774 case NE_EXPR: | |
111 | 775 return op0->data != op1->data; |
0 | 776 |
777 case EQ_EXPR: | |
111 | 778 return op0->data == op1->data; |
0 | 779 |
780 case LT_EXPR: | |
111 | 781 return op0->data.cmp (op1->data, |
0 | 782 UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == -1; |
783 | |
784 case LE_EXPR: | |
111 | 785 return op0->data.cmp (op1->data, |
0 | 786 UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != 1; |
787 | |
788 case GT_EXPR: | |
111 | 789 return op0->data.cmp (op1->data, |
0 | 790 UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) == 1; |
791 | |
792 case GE_EXPR: | |
111 | 793 return op0->data.cmp (op1->data, |
0 | 794 UNSIGNED_FIXED_POINT_MODE_P (op0->mode)) != -1; |
795 | |
796 default: | |
797 gcc_unreachable (); | |
798 } | |
799 } | |
800 | |
801 /* Extend or truncate to a new mode. | |
802 If SAT_P, saturate the result to the max or the min. | |
803 Return true, if !SAT_P and overflow. */ | |
804 | |
805 bool | |
111 | 806 fixed_convert (FIXED_VALUE_TYPE *f, scalar_mode mode, |
0 | 807 const FIXED_VALUE_TYPE *a, bool sat_p) |
808 { | |
809 bool overflow_p = false; | |
810 if (mode == a->mode) | |
811 { | |
812 *f = *a; | |
813 return overflow_p; | |
814 } | |
815 | |
816 if (GET_MODE_FBIT (mode) > GET_MODE_FBIT (a->mode)) | |
817 { | |
818 /* Left shift a to temp_high, temp_low based on a->mode. */ | |
819 double_int temp_high, temp_low; | |
820 int amount = GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode); | |
111 | 821 temp_low = a->data.lshift (amount, |
822 HOST_BITS_PER_DOUBLE_INT, | |
823 SIGNED_FIXED_POINT_MODE_P (a->mode)); | |
0 | 824 /* Logical shift right to temp_high. */ |
111 | 825 temp_high = a->data.llshift (amount - HOST_BITS_PER_DOUBLE_INT, |
826 HOST_BITS_PER_DOUBLE_INT); | |
0 | 827 if (SIGNED_FIXED_POINT_MODE_P (a->mode) |
828 && a->data.high < 0) /* Signed-extend temp_high. */ | |
111 | 829 temp_high = temp_high.sext (amount); |
0 | 830 f->mode = mode; |
831 f->data = temp_low; | |
832 if (SIGNED_FIXED_POINT_MODE_P (a->mode) == | |
833 SIGNED_FIXED_POINT_MODE_P (f->mode)) | |
834 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data, | |
835 sat_p); | |
836 else | |
837 { | |
838 /* Take care of the cases when converting between signed and | |
839 unsigned. */ | |
840 if (SIGNED_FIXED_POINT_MODE_P (a->mode)) | |
841 { | |
842 /* Signed -> Unsigned. */ | |
843 if (a->data.high < 0) | |
844 { | |
845 if (sat_p) | |
846 { | |
847 f->data.low = 0; /* Set to zero. */ | |
848 f->data.high = 0; /* Set to zero. */ | |
849 } | |
850 else | |
851 overflow_p = true; | |
852 } | |
853 else | |
854 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, | |
855 &f->data, sat_p); | |
856 } | |
857 else | |
858 { | |
859 /* Unsigned -> Signed. */ | |
860 if (temp_high.high < 0) | |
861 { | |
862 if (sat_p) | |
863 { | |
864 /* Set to maximum. */ | |
865 f->data.low = -1; /* Set to all ones. */ | |
866 f->data.high = -1; /* Set to all ones. */ | |
111 | 867 f->data = f->data.zext (GET_MODE_FBIT (f->mode) |
868 + GET_MODE_IBIT (f->mode)); | |
869 /* Clear the sign. */ | |
0 | 870 } |
871 else | |
872 overflow_p = true; | |
873 } | |
874 else | |
875 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, | |
876 &f->data, sat_p); | |
877 } | |
878 } | |
879 } | |
880 else | |
881 { | |
882 /* Right shift a to temp based on a->mode. */ | |
883 double_int temp; | |
111 | 884 temp = a->data.lshift (GET_MODE_FBIT (mode) - GET_MODE_FBIT (a->mode), |
885 HOST_BITS_PER_DOUBLE_INT, | |
886 SIGNED_FIXED_POINT_MODE_P (a->mode)); | |
0 | 887 f->mode = mode; |
888 f->data = temp; | |
889 if (SIGNED_FIXED_POINT_MODE_P (a->mode) == | |
890 SIGNED_FIXED_POINT_MODE_P (f->mode)) | |
891 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, sat_p); | |
892 else | |
893 { | |
894 /* Take care of the cases when converting between signed and | |
895 unsigned. */ | |
896 if (SIGNED_FIXED_POINT_MODE_P (a->mode)) | |
897 { | |
898 /* Signed -> Unsigned. */ | |
899 if (a->data.high < 0) | |
900 { | |
901 if (sat_p) | |
902 { | |
903 f->data.low = 0; /* Set to zero. */ | |
904 f->data.high = 0; /* Set to zero. */ | |
905 } | |
906 else | |
907 overflow_p = true; | |
908 } | |
909 else | |
910 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, | |
911 sat_p); | |
912 } | |
913 else | |
914 { | |
915 /* Unsigned -> Signed. */ | |
916 if (temp.high < 0) | |
917 { | |
918 if (sat_p) | |
919 { | |
920 /* Set to maximum. */ | |
921 f->data.low = -1; /* Set to all ones. */ | |
922 f->data.high = -1; /* Set to all ones. */ | |
111 | 923 f->data = f->data.zext (GET_MODE_FBIT (f->mode) |
924 + GET_MODE_IBIT (f->mode)); | |
925 /* Clear the sign. */ | |
0 | 926 } |
927 else | |
928 overflow_p = true; | |
929 } | |
930 else | |
931 overflow_p = fixed_saturate1 (f->mode, f->data, &f->data, | |
932 sat_p); | |
933 } | |
934 } | |
935 } | |
936 | |
111 | 937 f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) |
0 | 938 + GET_MODE_FBIT (f->mode) |
939 + GET_MODE_IBIT (f->mode), | |
940 UNSIGNED_FIXED_POINT_MODE_P (f->mode)); | |
941 return overflow_p; | |
942 } | |
943 | |
944 /* Convert to a new fixed-point mode from an integer. | |
945 If UNSIGNED_P, this integer is unsigned. | |
946 If SAT_P, saturate the result to the max or the min. | |
947 Return true, if !SAT_P and overflow. */ | |
948 | |
949 bool | |
111 | 950 fixed_convert_from_int (FIXED_VALUE_TYPE *f, scalar_mode mode, |
0 | 951 double_int a, bool unsigned_p, bool sat_p) |
952 { | |
953 bool overflow_p = false; | |
954 /* Left shift a to temp_high, temp_low. */ | |
955 double_int temp_high, temp_low; | |
956 int amount = GET_MODE_FBIT (mode); | |
111 | 957 if (amount == HOST_BITS_PER_DOUBLE_INT) |
0 | 958 { |
959 temp_high = a; | |
960 temp_low.low = 0; | |
961 temp_low.high = 0; | |
962 } | |
963 else | |
964 { | |
111 | 965 temp_low = a.llshift (amount, HOST_BITS_PER_DOUBLE_INT); |
0 | 966 |
967 /* Logical shift right to temp_high. */ | |
111 | 968 temp_high = a.llshift (amount - HOST_BITS_PER_DOUBLE_INT, |
969 HOST_BITS_PER_DOUBLE_INT); | |
0 | 970 } |
971 if (!unsigned_p && a.high < 0) /* Signed-extend temp_high. */ | |
111 | 972 temp_high = temp_high.sext (amount); |
0 | 973 |
974 f->mode = mode; | |
975 f->data = temp_low; | |
976 | |
977 if (unsigned_p == UNSIGNED_FIXED_POINT_MODE_P (f->mode)) | |
978 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, &f->data, | |
979 sat_p); | |
980 else | |
981 { | |
982 /* Take care of the cases when converting between signed and unsigned. */ | |
983 if (!unsigned_p) | |
984 { | |
985 /* Signed -> Unsigned. */ | |
986 if (a.high < 0) | |
987 { | |
988 if (sat_p) | |
989 { | |
990 f->data.low = 0; /* Set to zero. */ | |
991 f->data.high = 0; /* Set to zero. */ | |
992 } | |
993 else | |
994 overflow_p = true; | |
995 } | |
996 else | |
997 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, | |
998 &f->data, sat_p); | |
999 } | |
1000 else | |
1001 { | |
1002 /* Unsigned -> Signed. */ | |
1003 if (temp_high.high < 0) | |
1004 { | |
1005 if (sat_p) | |
1006 { | |
1007 /* Set to maximum. */ | |
1008 f->data.low = -1; /* Set to all ones. */ | |
1009 f->data.high = -1; /* Set to all ones. */ | |
111 | 1010 f->data = f->data.zext (GET_MODE_FBIT (f->mode) |
1011 + GET_MODE_IBIT (f->mode)); | |
1012 /* Clear the sign. */ | |
0 | 1013 } |
1014 else | |
1015 overflow_p = true; | |
1016 } | |
1017 else | |
1018 overflow_p = fixed_saturate2 (f->mode, temp_high, temp_low, | |
1019 &f->data, sat_p); | |
1020 } | |
1021 } | |
111 | 1022 f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode) |
0 | 1023 + GET_MODE_FBIT (f->mode) |
1024 + GET_MODE_IBIT (f->mode), | |
1025 UNSIGNED_FIXED_POINT_MODE_P (f->mode)); | |
1026 return overflow_p; | |
1027 } | |
1028 | |
1029 /* Convert to a new fixed-point mode from a real. | |
1030 If SAT_P, saturate the result to the max or the min. | |
1031 Return true, if !SAT_P and overflow. */ | |
1032 | |
1033 bool | |
111 | 1034 fixed_convert_from_real (FIXED_VALUE_TYPE *f, scalar_mode mode, |
0 | 1035 const REAL_VALUE_TYPE *a, bool sat_p) |
1036 { | |
1037 bool overflow_p = false; | |
1038 REAL_VALUE_TYPE real_value, fixed_value, base_value; | |
1039 bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode); | |
1040 int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode); | |
1041 unsigned int fbit = GET_MODE_FBIT (mode); | |
1042 enum fixed_value_range_code temp; | |
111 | 1043 bool fail; |
0 | 1044 |
1045 real_value = *a; | |
1046 f->mode = mode; | |
111 | 1047 real_2expN (&base_value, fbit, VOIDmode); |
0 | 1048 real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value); |
111 | 1049 |
1050 wide_int w = real_to_integer (&fixed_value, &fail, | |
1051 GET_MODE_PRECISION (mode)); | |
1052 f->data.low = w.ulow (); | |
1053 f->data.high = w.elt (1); | |
0 | 1054 temp = check_real_for_fixed_mode (&real_value, mode); |
1055 if (temp == FIXED_UNDERFLOW) /* Minimum. */ | |
1056 { | |
1057 if (sat_p) | |
1058 { | |
1059 if (unsigned_p) | |
1060 { | |
1061 f->data.low = 0; | |
1062 f->data.high = 0; | |
1063 } | |
1064 else | |
1065 { | |
1066 f->data.low = 1; | |
1067 f->data.high = 0; | |
111 | 1068 f->data = f->data.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT); |
1069 f->data = f->data.sext (1 + i_f_bits); | |
0 | 1070 } |
1071 } | |
1072 else | |
1073 overflow_p = true; | |
1074 } | |
1075 else if (temp == FIXED_GT_MAX_EPS || temp == FIXED_MAX_EPS) /* Maximum. */ | |
1076 { | |
1077 if (sat_p) | |
1078 { | |
1079 f->data.low = -1; | |
1080 f->data.high = -1; | |
111 | 1081 f->data = f->data.zext (i_f_bits); |
0 | 1082 } |
1083 else | |
1084 overflow_p = true; | |
1085 } | |
111 | 1086 f->data = f->data.ext ((!unsigned_p) + i_f_bits, unsigned_p); |
0 | 1087 return overflow_p; |
1088 } | |
1089 | |
1090 /* Convert to a new real mode from a fixed-point. */ | |
1091 | |
1092 void | |
111 | 1093 real_convert_from_fixed (REAL_VALUE_TYPE *r, scalar_mode mode, |
0 | 1094 const FIXED_VALUE_TYPE *f) |
1095 { | |
1096 REAL_VALUE_TYPE base_value, fixed_value, real_value; | |
1097 | |
111 | 1098 signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f->mode) ? UNSIGNED : SIGNED; |
1099 real_2expN (&base_value, GET_MODE_FBIT (f->mode), VOIDmode); | |
1100 real_from_integer (&fixed_value, VOIDmode, | |
1101 wide_int::from (f->data, GET_MODE_PRECISION (f->mode), | |
1102 sgn), sgn); | |
0 | 1103 real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value); |
1104 real_convert (r, mode, &real_value); | |
1105 } | |
1106 | |
1107 /* Determine whether a fixed-point value F is negative. */ | |
1108 | |
1109 bool | |
1110 fixed_isneg (const FIXED_VALUE_TYPE *f) | |
1111 { | |
1112 if (SIGNED_FIXED_POINT_MODE_P (f->mode)) | |
1113 { | |
1114 int i_f_bits = GET_MODE_IBIT (f->mode) + GET_MODE_FBIT (f->mode); | |
1115 int sign_bit = get_fixed_sign_bit (f->data, i_f_bits); | |
1116 if (sign_bit == 1) | |
1117 return true; | |
1118 } | |
1119 | |
1120 return false; | |
1121 } |