xref: /netbsd-src/external/gpl3/gcc/dist/gcc/d/d-ctfloat.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* d-ctfloat.cc -- D frontend interface to the gcc back-end.
2    Copyright (C) 2020-2022 Free Software Foundation, Inc.
3 
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8 
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3.  If not see
16 <http://www.gnu.org/licenses/>.  */
17 
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21 
22 #include "dmd/root/ctfloat.h"
23 #include "dmd/target.h"
24 
25 #include "tree.h"
26 
27 
28 /* Implements the CTFloat interface defined by the frontend.
29    Compile-time floating-pointer helper functions.  */
30 
31 /* Return the absolute value of R.  */
32 
33 real_t
fabs(real_t r)34 CTFloat::fabs (real_t r)
35 {
36   real_t x;
37   real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL);
38   return x.normalize ();
39 }
40 
41 /* Return the value of R * 2 ^^ EXP.  */
42 
43 real_t
ldexp(real_t r,int exp)44 CTFloat::ldexp (real_t r, int exp)
45 {
46   real_t x;
47   real_ldexp (&x.rv (), &r.rv (), exp);
48   return x.normalize ();
49 }
50 
51 /* Return true if longdouble value X is identical to Y.  */
52 
53 bool
isIdentical(real_t x,real_t y)54 CTFloat::isIdentical (real_t x, real_t y)
55 {
56   real_value rx = x.rv ();
57   real_value ry = y.rv ();
58   return real_identical (&rx, &ry);
59 }
60 
61 /* Return true if real_t value R is NaN.  */
62 
63 bool
isNaN(real_t r)64 CTFloat::isNaN (real_t r)
65 {
66   return REAL_VALUE_ISNAN (r.rv ());
67 }
68 
69 /* Same as isNaN, but also check if is signalling.  */
70 
71 bool
isSNaN(real_t r)72 CTFloat::isSNaN (real_t r)
73 {
74   return REAL_VALUE_ISSIGNALING_NAN (r.rv ());
75 }
76 
77 /* Return true if real_t value is +Inf.  */
78 
79 bool
isInfinity(real_t r)80 CTFloat::isInfinity (real_t r)
81 {
82   return REAL_VALUE_ISINF (r.rv ());
83 }
84 
85 /* Return a real_t value from string BUFFER rounded to long double mode.  */
86 
87 real_t
parse(const char * buffer,bool * overflow)88 CTFloat::parse (const char *buffer, bool *overflow)
89 {
90   real_t r;
91   real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
92 
93   /* Front-end checks overflow to see if the value is representable.  */
94   if (overflow && r == target.RealProperties.infinity)
95     *overflow = true;
96 
97   return r;
98 }
99 
100 /* Format the real_t value R to string BUFFER as a decimal or hexadecimal,
101    converting the result to uppercase if FMT requests it.  */
102 
103 int
sprint(char * buffer,char fmt,real_t r)104 CTFloat::sprint (char *buffer, char fmt, real_t r)
105 {
106   if (fmt == 'a' || fmt == 'A')
107     {
108       /* Converting to a hexadecimal string.  */
109       real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);
110       int buflen;
111 
112       switch (fmt)
113 	{
114 	case 'A':
115 	  buflen = strlen (buffer);
116 	  for (int i = 0; i < buflen; i++)
117 	    buffer[i] = TOUPPER (buffer[i]);
118 
119 	  return buflen;
120 
121 	case 'a':
122 	  return strlen (buffer);
123 
124 	default:
125 	  gcc_unreachable ();
126 	}
127     }
128   else
129     {
130       /* Note: restricting the precision of significant digits to 18.  */
131       real_to_decimal (buffer, &r.rv (), 32, 18, 1);
132       return strlen (buffer);
133     }
134 }
135 
136 /* Return a hash value for real_t value R.  */
137 
138 size_t
hash(real_t r)139 CTFloat::hash (real_t r)
140 {
141   return real_hash (&r.rv ());
142 }
143