OSDN Git Service

gcc/ChangeLog:
[pf3gnuchains/gcc-fork.git] / gcc / fixed-value.c
index 705f4ca..9af431c 100644 (file)
@@ -1,5 +1,5 @@
 /* Fixed-point arithmetic support.
-   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -23,7 +23,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "toplev.h"
-#include "fixed-value.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.  */
@@ -553,7 +562,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
                         &r.low, &r.high, 0);
        }
 
-      /* Divide r by pos_b to quo_r.  The remanider is in mod.  */
+      /* Divide r by pos_b to quo_r.  The remainder is in mod.  */
       div_and_round_double (TRUNC_DIV_EXPR, 1, r.low, r.high, pos_b.low,
                            pos_b.high, &quo_r.low, &quo_r.high, &mod.low,
                            &mod.high);
@@ -613,7 +622,7 @@ do_fixed_divide (FIXED_VALUE_TYPE *f, const FIXED_VALUE_TYPE *a,
   return overflow_p;
 }
 
-/* Calculate F = A << B if LEFT_P.  Otherwies, F = A >> B.
+/* Calculate F = A << B if LEFT_P.  Otherwise, F = A >> B.
    If SAT_P, saturate the result to the max or the min.
    Return true, if !SAT_P and overflow.  */
 
@@ -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);