1 /* d-ctfloat.cc -- D frontend interface to the gcc back-end.
2 Copyright (C) 2020-2021 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_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry))
59 || real_identical (&rx, &ry);
60 }
61
62 /* Return true if real_t value R is NaN. */
63
64 bool
isNaN(real_t r)65 CTFloat::isNaN (real_t r)
66 {
67 return REAL_VALUE_ISNAN (r.rv ());
68 }
69
70 /* Same as isNaN, but also check if is signalling. */
71
72 bool
isSNaN(real_t r)73 CTFloat::isSNaN (real_t r)
74 {
75 return REAL_VALUE_ISSIGNALING_NAN (r.rv ());
76 }
77
78 /* Return true if real_t value is +Inf. */
79
80 bool
isInfinity(real_t r)81 CTFloat::isInfinity (real_t r)
82 {
83 return REAL_VALUE_ISINF (r.rv ());
84 }
85
86 /* Return a real_t value from string BUFFER rounded to long double mode. */
87
88 real_t
parse(const char * buffer,bool * overflow)89 CTFloat::parse (const char *buffer, bool *overflow)
90 {
91 real_t r;
92 real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node));
93
94 /* Front-end checks overflow to see if the value is representable. */
95 if (overflow && r == target.RealProperties.infinity)
96 *overflow = true;
97
98 return r;
99 }
100
101 /* Format the real_t value R to string BUFFER as a decimal or hexadecimal,
102 converting the result to uppercase if FMT requests it. */
103
104 int
sprint(char * buffer,char fmt,real_t r)105 CTFloat::sprint (char *buffer, char fmt, real_t r)
106 {
107 if (fmt == 'a' || fmt == 'A')
108 {
109 /* Converting to a hexadecimal string. */
110 real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1);
111 int buflen;
112
113 switch (fmt)
114 {
115 case 'A':
116 buflen = strlen (buffer);
117 for (int i = 0; i < buflen; i++)
118 buffer[i] = TOUPPER (buffer[i]);
119
120 return buflen;
121
122 case 'a':
123 return strlen (buffer);
124
125 default:
126 gcc_unreachable ();
127 }
128 }
129 else
130 {
131 /* Note: restricting the precision of significant digits to 18. */
132 real_to_decimal (buffer, &r.rv (), 32, 18, 1);
133 return strlen (buffer);
134 }
135 }
136
137 /* Return a hash value for real_t value R. */
138
139 size_t
hash(real_t r)140 CTFloat::hash (real_t r)
141 {
142 return real_hash (&r.rv ());
143 }
144