Home | History | Annotate | Line # | Download | only in d
      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