Daily bump.
[official-gcc.git] / gcc / d / d-longdouble.cc
blobe4c8c5e6eb061b07d8335f3dff1138736cbce7aa
1 /* d-longdouble.cc -- Software floating-point emulation for the frontend.
2 Copyright (C) 2006-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/mtype.h"
24 #include "tree.h"
25 #include "fold-const.h"
26 #include "diagnostic.h"
27 #include "stor-layout.h"
29 #include "d-tree.h"
30 #include "longdouble.h"
33 /* Truncate longdouble to the highest precision supported by target. */
35 longdouble
36 longdouble::normalize (void)
38 const machine_mode mode = TYPE_MODE (long_double_type_node);
39 real_convert (&this->rv (), mode, &this->rv ());
40 return *this;
43 /* Assign a real_value to a longdouble type. */
45 void
46 longdouble::set (real_value &d)
48 real_convert (&this->rv (), TYPE_MODE (long_double_type_node), &d);
51 /* Conversion routines between longdouble and integer types. */
53 void
54 longdouble::set (int32_t d)
56 real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, SIGNED);
59 void
60 longdouble::set (int64_t d)
62 real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,
63 SIGNED);
66 int64_t
67 longdouble::to_int (void) const
69 bool overflow;
70 wide_int wi = real_to_integer (&this->rv (), &overflow, 64);
71 return wi.to_shwi ();
74 /* Unsigned variants of the same conversion routines. */
76 void
77 longdouble::set (uint32_t d)
79 real_from_integer (&this->rv (), TYPE_MODE (double_type_node), d, UNSIGNED);
82 void
83 longdouble::set (uint64_t d)
85 real_from_integer (&this->rv (), TYPE_MODE (long_double_type_node), d,
86 UNSIGNED);
89 uint64_t
90 longdouble::to_uint (void) const
92 bool overflow;
93 wide_int wi = real_to_integer (&this->rv (), &overflow, 64);
94 return wi.to_uhwi ();
97 /* For conversion between boolean, only need to check if is zero. */
99 void
100 longdouble::set (bool d)
102 this->rv () = (d == false) ? dconst0 : dconst1;
105 bool
106 longdouble::to_bool (void) const
108 return this->rv ().cl != rvc_zero;
111 /* Overload numeric operators for longdouble types. */
113 longdouble
114 longdouble::add (const longdouble &r) const
116 longdouble x;
117 real_arithmetic (&x.rv (), PLUS_EXPR, &this->rv (), &r.rv ());
118 return x.normalize ();
121 longdouble
122 longdouble::sub (const longdouble &r) const
124 longdouble x;
125 real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &r.rv ());
126 return x.normalize ();
129 longdouble
130 longdouble::mul (const longdouble &r) const
132 longdouble x;
133 real_arithmetic (&x.rv (), MULT_EXPR, &this->rv (), &r.rv ());
134 return x.normalize ();
137 longdouble
138 longdouble::div (const longdouble &r) const
140 longdouble x;
141 real_arithmetic (&x.rv (), RDIV_EXPR, &this->rv (), &r.rv ());
142 return x.normalize ();
145 longdouble
146 longdouble::mod (const longdouble &r) const
148 longdouble x;
149 real_value q;
151 if (r.rv ().cl == rvc_zero || REAL_VALUE_ISINF (this->rv ()))
153 real_nan (&x.rv (), "", 1, TYPE_MODE (long_double_type_node));
154 return x;
157 if (this->rv ().cl == rvc_zero)
158 return *this;
160 if (REAL_VALUE_ISINF (r.rv ()))
161 return *this;
163 /* Need to check for NaN? */
164 real_arithmetic (&q, RDIV_EXPR, &this->rv (), &r.rv ());
165 real_arithmetic (&q, FIX_TRUNC_EXPR, &q, NULL);
166 real_arithmetic (&q, MULT_EXPR, &q, &r.rv ());
167 real_arithmetic (&x.rv (), MINUS_EXPR, &this->rv (), &q);
169 return x.normalize ();
172 longdouble
173 longdouble::neg (void) const
175 longdouble x;
176 real_arithmetic (&x.rv (), NEGATE_EXPR, &this->rv (), NULL);
177 return x.normalize ();
180 /* Overload equality operators for longdouble types. */
183 longdouble::cmp (const longdouble &r) const
185 if (real_compare (LT_EXPR, &this->rv (), &r.rv ()))
186 return -1;
188 if (real_compare (GT_EXPR, &this->rv (), &r.rv ()))
189 return 1;
191 return 0;
195 longdouble::equals (const longdouble &r) const
197 return real_compare (EQ_EXPR, &this->rv (), &r.rv ());