X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ffixed-value.c;h=022f60ed8365171bf7bc53ad81d46cf2a6b7752e;hb=d4fbd9e6808cc60cb3df708a49d4060985e477ec;hp=aca386a6d9c00c8cb35fd91d7f7efa177ac44272;hpb=becfaa6206281ee8bb5d22ca461fa08568e7dc8c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/fixed-value.c b/gcc/fixed-value.c index aca386a6d9c..022f60ed836 100644 --- a/gcc/fixed-value.c +++ b/gcc/fixed-value.c @@ -1,5 +1,5 @@ /* Fixed-point arithmetic support. - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -22,8 +22,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "toplev.h" -#include "fixed-value.h" +#include "diagnostic-core.h" /* Compare two fixed objects for bitwise identity. */ @@ -64,11 +63,11 @@ check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, enum machine_mode mode) { REAL_VALUE_TYPE max_value, min_value, epsilon_value; - real_2expN (&max_value, GET_MODE_IBIT (mode)); - real_2expN (&epsilon_value, -GET_MODE_FBIT (mode)); + real_2expN (&max_value, GET_MODE_IBIT (mode), mode); + real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), mode); if (SIGNED_FIXED_POINT_MODE_P (mode)) - min_value = REAL_VALUE_NEGATE (max_value); + min_value = real_value_negate (&max_value); else real_from_string (&min_value, "0.0"); @@ -102,7 +101,7 @@ fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, enum machine_mode mode) || (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode))) warning (OPT_Woverflow, "large fixed-point constant implicitly truncated to fixed-point type"); - real_2expN (&base_value, fbit); + real_2expN (&base_value, fbit, mode); real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value); real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high, &fixed_value); @@ -132,7 +131,7 @@ fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig, { REAL_VALUE_TYPE real_value, base_value, fixed_value; - real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode)); + real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), f_orig->mode); real_from_integer (&real_value, VOIDmode, f_orig->data.low, f_orig->data.high, UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode)); real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value); @@ -291,9 +290,19 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, const FIXED_VALUE_TYPE *b, bool subtract_p, bool sat_p) { bool overflow_p = false; - double_int temp = subtract_p ? double_int_neg (b->data) : b->data; - bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); - int i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); + bool unsigned_p; + double_int temp; + int i_f_bits; + + /* This was a conditional expression but it triggered a bug in + Sun C 5.5. */ + if (subtract_p) + temp = double_int_neg (b->data); + else + temp = b->data; + + unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (a->mode); + i_f_bits = GET_MODE_IBIT (a->mode) + GET_MODE_FBIT (a->mode); f->mode = a->mode; f->data = double_int_add (a->data, temp); if (unsigned_p) /* Unsigned type. */ @@ -352,7 +361,7 @@ do_fixed_add (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, double_int one; one.low = 1; one.high = 0; - f->data = double_int_add (f->data, double_int_neg (one)); + f->data = double_int_sub (f->data, one); } } else @@ -434,12 +443,12 @@ do_fixed_multiply (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, temp1.high = 0; r = double_int_add (r, temp1); - /* We need to add neg(b) to r, if a < 0. */ + /* We need to subtract b from r, if a < 0. */ if (!unsigned_p && a->data.high < 0) - r = double_int_add (r, double_int_neg (b->data)); - /* We need to add neg(a) to r, if b < 0. */ + r = double_int_sub (r, b->data); + /* We need to subtract a from r, if b < 0. */ if (!unsigned_p && b->data.high < 0) - r = double_int_add (r, double_int_neg (a->data)); + r = double_int_sub (r, a->data); /* Shift right the result by FBIT. */ if (GET_MODE_FBIT (f->mode) == 2 * HOST_BITS_PER_WIDE_INT) @@ -579,7 +588,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a, &quo_s.low, &quo_s.high, 0); /* Try to calculate (mod - pos_b). */ - temp = double_int_add (mod, double_int_neg (pos_b)); + temp = double_int_sub (mod, pos_b); if (leftmost_mod == 1 || double_int_cmp (mod, pos_b, 1) != -1) { @@ -774,7 +783,7 @@ bool fixed_compare (int icode, const FIXED_VALUE_TYPE *op0, const FIXED_VALUE_TYPE *op1) { - enum tree_code code = icode; + enum tree_code code = (enum tree_code) icode; gcc_assert (op0->mode == op1->mode); switch (code) @@ -1067,7 +1076,7 @@ fixed_convert_from_real (FIXED_VALUE_TYPE *f, enum machine_mode mode, real_value = *a; f->mode = mode; - real_2expN (&base_value, fbit); + real_2expN (&base_value, fbit, mode); real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value); real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high, &fixed_value); temp = check_real_for_fixed_mode (&real_value, mode); @@ -1116,7 +1125,7 @@ real_convert_from_fixed (REAL_VALUE_TYPE *r, enum machine_mode mode, { REAL_VALUE_TYPE base_value, fixed_value, real_value; - real_2expN (&base_value, GET_MODE_FBIT (f->mode)); + real_2expN (&base_value, GET_MODE_FBIT (f->mode), f->mode); real_from_integer (&fixed_value, VOIDmode, f->data.low, f->data.high, UNSIGNED_FIXED_POINT_MODE_P (f->mode)); real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value);