xref: /dragonfly/contrib/gcc-8.0/gcc/realmpfr.c (revision 38fd1498)
1*38fd1498Szrj /* Conversion routines from GCC internal float representation to MPFR.
2*38fd1498Szrj    Copyright (C) 2010-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj    This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj    GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj    the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj    Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj    version.
10*38fd1498Szrj 
11*38fd1498Szrj    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj    WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj    for more details.
15*38fd1498Szrj 
16*38fd1498Szrj    You should have received a copy of the GNU General Public License
17*38fd1498Szrj    along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj    <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj #include "config.h"
21*38fd1498Szrj #include "system.h"
22*38fd1498Szrj #include "coretypes.h"
23*38fd1498Szrj #include "tree.h"
24*38fd1498Szrj #include "realmpfr.h"
25*38fd1498Szrj #include "stor-layout.h"
26*38fd1498Szrj 
27*38fd1498Szrj /* Convert from REAL_VALUE_TYPE to MPFR.  The caller is responsible
28*38fd1498Szrj    for initializing and clearing the MPFR parameter.  */
29*38fd1498Szrj 
30*38fd1498Szrj void
mpfr_from_real(mpfr_ptr m,const REAL_VALUE_TYPE * r,mp_rnd_t rndmode)31*38fd1498Szrj mpfr_from_real (mpfr_ptr m, const REAL_VALUE_TYPE *r, mp_rnd_t rndmode)
32*38fd1498Szrj {
33*38fd1498Szrj   /* We use a string as an intermediate type.  */
34*38fd1498Szrj   char buf[128];
35*38fd1498Szrj   int ret;
36*38fd1498Szrj 
37*38fd1498Szrj   /* Take care of Infinity and NaN.  */
38*38fd1498Szrj   if (r->cl == rvc_inf)
39*38fd1498Szrj     {
40*38fd1498Szrj       mpfr_set_inf (m, r->sign == 1 ? -1 : 1);
41*38fd1498Szrj       return;
42*38fd1498Szrj     }
43*38fd1498Szrj 
44*38fd1498Szrj   if (r->cl == rvc_nan)
45*38fd1498Szrj     {
46*38fd1498Szrj       mpfr_set_nan (m);
47*38fd1498Szrj       return;
48*38fd1498Szrj     }
49*38fd1498Szrj 
50*38fd1498Szrj   real_to_hexadecimal (buf, r, sizeof (buf), 0, 1);
51*38fd1498Szrj   /* mpfr_set_str() parses hexadecimal floats from strings in the same
52*38fd1498Szrj      format that GCC will output them.  Nothing extra is needed.  */
53*38fd1498Szrj   ret = mpfr_set_str (m, buf, 16, rndmode);
54*38fd1498Szrj   gcc_assert (ret == 0);
55*38fd1498Szrj }
56*38fd1498Szrj 
57*38fd1498Szrj /* Convert from MPFR to REAL_VALUE_TYPE, for a given format FORMAT and
58*38fd1498Szrj    rounding mode RNDMODE.  FORMAT is only relevant if M is a NaN.  */
59*38fd1498Szrj 
60*38fd1498Szrj void
real_from_mpfr(REAL_VALUE_TYPE * r,mpfr_srcptr m,const real_format * format,mp_rnd_t rndmode)61*38fd1498Szrj real_from_mpfr (REAL_VALUE_TYPE *r, mpfr_srcptr m, const real_format *format,
62*38fd1498Szrj 		mp_rnd_t rndmode)
63*38fd1498Szrj {
64*38fd1498Szrj   /* We use a string as an intermediate type.  */
65*38fd1498Szrj   char buf[128], *rstr;
66*38fd1498Szrj   mp_exp_t exp;
67*38fd1498Szrj 
68*38fd1498Szrj   /* Take care of Infinity and NaN.  */
69*38fd1498Szrj   if (mpfr_inf_p (m))
70*38fd1498Szrj     {
71*38fd1498Szrj       real_inf (r);
72*38fd1498Szrj       if (mpfr_sgn (m) < 0)
73*38fd1498Szrj 	*r = real_value_negate (r);
74*38fd1498Szrj       return;
75*38fd1498Szrj     }
76*38fd1498Szrj 
77*38fd1498Szrj   if (mpfr_nan_p (m))
78*38fd1498Szrj     {
79*38fd1498Szrj       real_nan (r, "", 1, format);
80*38fd1498Szrj       return;
81*38fd1498Szrj     }
82*38fd1498Szrj 
83*38fd1498Szrj   rstr = mpfr_get_str (NULL, &exp, 16, 0, m, rndmode);
84*38fd1498Szrj 
85*38fd1498Szrj   /* The additional 12 chars add space for the sprintf below.  This
86*38fd1498Szrj      leaves 6 digits for the exponent which is supposedly enough.  */
87*38fd1498Szrj   gcc_assert (rstr != NULL && strlen (rstr) < sizeof (buf) - 12);
88*38fd1498Szrj 
89*38fd1498Szrj   /* REAL_VALUE_ATOF expects the exponent for mantissa * 2**exp,
90*38fd1498Szrj      mpfr_get_str returns the exponent for mantissa * 16**exp, adjust
91*38fd1498Szrj      for that.  */
92*38fd1498Szrj   exp *= 4;
93*38fd1498Szrj 
94*38fd1498Szrj   if (rstr[0] == '-')
95*38fd1498Szrj     sprintf (buf, "-0x.%sp%d", &rstr[1], (int) exp);
96*38fd1498Szrj   else
97*38fd1498Szrj     sprintf (buf, "0x.%sp%d", rstr, (int) exp);
98*38fd1498Szrj 
99*38fd1498Szrj   mpfr_free_str (rstr);
100*38fd1498Szrj 
101*38fd1498Szrj   real_from_string (r, buf);
102*38fd1498Szrj }
103*38fd1498Szrj 
104*38fd1498Szrj /* Convert from MPFR to REAL_VALUE_TYPE, for a given type TYPE and rounding
105*38fd1498Szrj    mode RNDMODE.  TYPE is only relevant if M is a NaN.  */
106*38fd1498Szrj 
107*38fd1498Szrj void
real_from_mpfr(REAL_VALUE_TYPE * r,mpfr_srcptr m,tree type,mp_rnd_t rndmode)108*38fd1498Szrj real_from_mpfr (REAL_VALUE_TYPE *r, mpfr_srcptr m, tree type, mp_rnd_t rndmode)
109*38fd1498Szrj {
110*38fd1498Szrj   real_from_mpfr (r, m, type ? REAL_MODE_FORMAT (TYPE_MODE (type)) : NULL,
111*38fd1498Szrj 		  rndmode);
112*38fd1498Szrj }
113*38fd1498Szrj 
114