Mercurial > hg > CbC > CbC_gcc
diff gcc/dfp.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/dfp.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/dfp.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,6 +1,5 @@ /* Decimal floating point support. - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software - Foundation, Inc. + Copyright (C) 2005-2017 Free Software Foundation, Inc. This file is part of GCC. @@ -23,17 +22,14 @@ #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "tm_p.h" #include "dfp.h" /* The order of the following headers is important for making sure decNumber structure is large enough to hold decimal128 digits. */ #include "decimal128.h" -#include "decimal128Local.h" #include "decimal64.h" #include "decimal32.h" -#include "decNumber.h" #ifndef WORDS_BIGENDIAN #define WORDS_BIGENDIAN 0 @@ -110,7 +106,33 @@ decNumberFromString (dn, "nan", &set); break; case rvc_normal: - gcc_assert (r->decimal); + if (!r->decimal) + { + /* dconst{1,2,m1,half} are used in various places in + the middle-end and optimizers, allow them here + as an exception by converting them to decimal. */ + if (memcmp (r, &dconst1, sizeof (*r)) == 0) + { + decNumberFromString (dn, "1", &set); + break; + } + if (memcmp (r, &dconst2, sizeof (*r)) == 0) + { + decNumberFromString (dn, "2", &set); + break; + } + if (memcmp (r, &dconstm1, sizeof (*r)) == 0) + { + decNumberFromString (dn, "-1", &set); + break; + } + if (memcmp (r, &dconsthalf, sizeof (*r)) == 0) + { + decNumberFromString (dn, "0.5", &set); + break; + } + gcc_unreachable (); + } decimal128ToNumber ((const decimal128 *) r->sig, dn); break; default: @@ -317,13 +339,13 @@ static void decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from, - enum machine_mode mode) + const real_format *fmt) { char string[256]; const decimal128 *const d128 = (const decimal128 *) from->sig; decimal128ToString (d128, string); - real_from_string3 (to, string, mode); + real_from_string3 (to, string, fmt); } @@ -433,15 +455,13 @@ binary and decimal types. */ void -decimal_real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode, +decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt, const REAL_VALUE_TYPE *a) { - const struct real_format *fmt = REAL_MODE_FORMAT (mode); - if (a->decimal && fmt->b == 10) return; if (a->decimal) - decimal_to_binary (r, a, mode); + decimal_to_binary (r, a, fmt); else decimal_from_binary (r, a); } @@ -579,11 +599,11 @@ return real_to_integer (&to); } -/* Likewise, but to an integer pair, HI+LOW. */ +/* Likewise, but returns a wide_int with PRECISION. *FAIL is set if the + value does not fit. */ -void -decimal_real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh, - const REAL_VALUE_TYPE *r) +wide_int +decimal_real_to_integer (const REAL_VALUE_TYPE *r, bool *fail, int precision) { decContext set; decNumber dn, dn2, dn3; @@ -603,7 +623,7 @@ function. */ decNumberToString (&dn, string); real_from_string (&to, string); - real_to_integer2 (plow, phigh, &to); + return real_to_integer (&to, fail, precision); } /* Perform the decimal floating point operation described by CODE. @@ -694,19 +714,19 @@ If SIGN is nonzero, R is set to the most negative finite value. */ void -decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode) +decimal_real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode) { const char *max; switch (mode) { - case SDmode: + case E_SDmode: max = "9.999999E96"; break; - case DDmode: + case E_DDmode: max = "9.999999999999999E384"; break; - case TDmode: + case E_TDmode: max = "9.999999999999999999999999999999999E6144"; break; default: