/* d-ctfloat.cc -- D frontend interface to the gcc back-end. Copyright (C) 2020 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "dmd/root/ctfloat.h" #include "dmd/target.h" #include "tree.h" /* Implements the CTFloat interface defined by the frontend. Compile-time floating-pointer helper functions. */ /* Return the absolute value of R. */ real_t CTFloat::fabs (real_t r) { real_t x; real_arithmetic (&x.rv (), ABS_EXPR, &r.rv (), NULL); return x.normalize (); } /* Return the value of R * 2 ^^ EXP. */ real_t CTFloat::ldexp (real_t r, int exp) { real_t x; real_ldexp (&x.rv (), &r.rv (), exp); return x.normalize (); } /* Return true if longdouble value X is identical to Y. */ bool CTFloat::isIdentical (real_t x, real_t y) { real_value rx = x.rv (); real_value ry = y.rv (); return (REAL_VALUE_ISNAN (rx) && REAL_VALUE_ISNAN (ry)) || real_identical (&rx, &ry); } /* Return true if real_t value R is NaN. */ bool CTFloat::isNaN (real_t r) { return REAL_VALUE_ISNAN (r.rv ()); } /* Same as isNaN, but also check if is signalling. */ bool CTFloat::isSNaN (real_t r) { return REAL_VALUE_ISSIGNALING_NAN (r.rv ()); } /* Return true if real_t value is +Inf. */ bool CTFloat::isInfinity (real_t r) { return REAL_VALUE_ISINF (r.rv ()); } /* Return a real_t value from string BUFFER rounded to long double mode. */ real_t CTFloat::parse (const char *buffer, bool *overflow) { real_t r; real_from_string3 (&r.rv (), buffer, TYPE_MODE (long_double_type_node)); /* Front-end checks overflow to see if the value is representable. */ if (overflow && r == target.RealProperties.infinity) *overflow = true; return r; } /* Format the real_t value R to string BUFFER as a decimal or hexadecimal, converting the result to uppercase if FMT requests it. */ int CTFloat::sprint (char *buffer, char fmt, real_t r) { if (fmt == 'a' || fmt == 'A') { /* Converting to a hexadecimal string. */ real_to_hexadecimal (buffer, &r.rv (), 32, 0, 1); int buflen; switch (fmt) { case 'A': buflen = strlen (buffer); for (int i = 0; i < buflen; i++) buffer[i] = TOUPPER (buffer[i]); return buflen; case 'a': return strlen (buffer); default: gcc_unreachable (); } } else { /* Note: restricting the precision of significant digits to 18. */ real_to_decimal (buffer, &r.rv (), 32, 18, 1); return strlen (buffer); } } /* Return a hash value for real_t value R. */ size_t CTFloat::hash (real_t r) { return real_hash (&r.rv ()); }