/* Pretty print support for value ranges.
   Copyright (C) 2019-2022 Free Software Foundation, Inc.
   Contributed by Aldy Hernandez <aldyh@redhat.com>.

This file is part of GCC.

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
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
#include "gimple-range.h"
#include "value-range-pretty-print.h"

void
vrange_printer::visit (const unsupported_range &r) const
{
  pp_string (pp, "[unsupported_range] ");
  if (r.undefined_p ())
    {
      pp_string (pp, "UNDEFINED");
      return;
    }
  if (r.varying_p ())
    {
      pp_string (pp, "VARYING");
      return;
    }
  gcc_unreachable ();
}

void
vrange_printer::visit (const irange &r) const
{
  pp_string (pp, "[irange] ");
  if (r.undefined_p ())
    {
      pp_string (pp, "UNDEFINED");
      return;
    }
  dump_generic_node (pp, r.type (), 0, TDF_NONE, false);
  pp_character (pp, ' ');
  if (r.varying_p ())
    {
      pp_string (pp, "VARYING");
      return;
    }
  // Handle legacy symbolics.
  if (!r.constant_p ())
    {
      if (r.kind () == VR_ANTI_RANGE)
	pp_character (pp, '~');
      pp_character (pp, '[');
      dump_generic_node (pp, r.min (), 0, TDF_NONE, false);
      pp_string (pp, ", ");
      dump_generic_node (pp, r.max (), 0, TDF_NONE, false);
      pp_character (pp, ']');
      print_irange_bitmasks (r);
      return;
    }
  for (unsigned i = 0; i < r.num_pairs (); ++i)
    {
      pp_character (pp, '[');
      print_irange_bound (r.lower_bound (i), r.type ());
      pp_string (pp, ", ");
      print_irange_bound (r.upper_bound (i), r.type ());
      pp_character (pp, ']');
    }
 print_irange_bitmasks (r);
}

void
vrange_printer::print_irange_bound (const wide_int &bound, tree type) const
{
  wide_int type_min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
  wide_int type_max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));

  if (INTEGRAL_TYPE_P (type)
      && !TYPE_UNSIGNED (type)
      && bound == type_min
      && TYPE_PRECISION (type) != 1)
    pp_string (pp, "-INF");
  else if (bound == type_max && TYPE_PRECISION (type) != 1)
    pp_string (pp, "+INF");
  else
    pp_wide_int (pp, bound, TYPE_SIGN (type));
}

void
vrange_printer::print_irange_bitmasks (const irange &r) const
{
  wide_int nz = r.get_nonzero_bits ();
  if (nz == -1)
    return;

  pp_string (pp, " NONZERO ");
  char buf[WIDE_INT_PRINT_BUFFER_SIZE];
  print_hex (nz, buf);
  pp_string (pp, buf);
}

void
vrange_printer::print_real_value (tree type, const REAL_VALUE_TYPE &r) const
{
  char s[100];
  real_to_decimal_for_mode (s, &r, sizeof (s), 0, 1, TYPE_MODE (type));
  pp_string (pp, s);
  if (!DECIMAL_FLOAT_TYPE_P (type))
    {
      real_to_hexadecimal (s, &r, sizeof (s), 0, 1);
      pp_printf (pp, " (%s)", s);
    }
}

// Print an frange.

void
vrange_printer::visit (const frange &r) const
{
  pp_string (pp, "[frange] ");
  if (r.undefined_p ())
    {
      pp_string (pp, "UNDEFINED");
      return;
    }
  tree type = r.type ();
  dump_generic_node (pp, type, 0, TDF_NONE, false);
  pp_string (pp, " ");
  if (r.varying_p ())
    {
      pp_string (pp, "VARYING");
      print_frange_nan (r);
      return;
    }
  pp_character (pp, '[');
  bool has_endpoints = !r.known_isnan ();
  if (has_endpoints)
    {
      print_real_value (type, r.lower_bound ());
      pp_string (pp, ", ");
      print_real_value (type, r.upper_bound ());
    }
  pp_character (pp, ']');
  print_frange_nan (r);
}

// Print the NAN info for an frange.

void
vrange_printer::print_frange_nan (const frange &r) const
{
  if (r.maybe_isnan ())
    {
      if (r.m_pos_nan && r.m_neg_nan)
	{
	  pp_string (pp, " +-NAN");
	  return;
	}
      bool nan_sign = r.m_neg_nan;
      if (nan_sign)
	pp_string (pp, " -NAN");
      else
	pp_string (pp, " +NAN");
    }
}
