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 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 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 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 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 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 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 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 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 139 CTFloat::hash (real_t r) 140 { 141 return real_hash (&r.rv ()); 142 } 143