/* A class for building vector rtx constants.
   Copyright (C) 2017-2018 Free Software Foundation, Inc.

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 "tm.h"
#include "rtl.h"
#include "rtx-vector-builder.h"

/* Return a CONST_VECTOR for the current constant.  V is an existing
   rtvec that contains all the elements.  */

rtx
rtx_vector_builder::build (rtvec v)
{
  finalize ();

  rtx x = find_cached_value ();
  if (x)
    return x;

  x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
  CONST_VECTOR_NPATTERNS (x) = npatterns ();
  CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
  return x;
}

/* Return a vector element with the value BASE + FACTOR * STEP.  */

rtx
rtx_vector_builder::apply_step (rtx base, unsigned int factor,
				const wide_int &step) const
{
  scalar_int_mode int_mode = as_a <scalar_int_mode> (GET_MODE_INNER (m_mode));
  return immed_wide_int_const (wi::add (rtx_mode_t (base, int_mode),
					factor * step),
			       int_mode);
}

/* Return a CONST_VECTOR for the current constant.  */

rtx
rtx_vector_builder::build ()
{
  finalize ();

  rtx x = find_cached_value ();
  if (x)
    return x;

  unsigned int nelts;
  if (!GET_MODE_NUNITS (m_mode).is_constant (&nelts))
    nelts = encoded_nelts ();
  rtvec v = rtvec_alloc (nelts);
  for (unsigned int i = 0; i < nelts; ++i)
    RTVEC_ELT (v, i) = elt (i);
  x = gen_rtx_raw_CONST_VECTOR (m_mode, v);
  CONST_VECTOR_NPATTERNS (x) = npatterns ();
  CONST_VECTOR_NELTS_PER_PATTERN (x) = nelts_per_pattern ();
  return x;
}

/* Check whether there is a global cached value for the vector.
   Return it if so, otherwise return null.  */

rtx
rtx_vector_builder::find_cached_value ()
{
  if (encoded_nelts () != 1)
    return NULL_RTX;

  rtx elt = (*this)[0];

  if (GET_MODE_CLASS (m_mode) == MODE_VECTOR_BOOL)
    {
      if (elt == const1_rtx || elt == constm1_rtx)
	return CONST1_RTX (m_mode);
      else if (elt == const0_rtx)
	return CONST0_RTX (m_mode);
      else
	gcc_unreachable ();
    }

  /* We can be called before the global vector constants are set up,
     but in that case we'll just return null.  */
  scalar_mode inner_mode = GET_MODE_INNER (m_mode);
  if (elt == CONST0_RTX (inner_mode))
    return CONST0_RTX (m_mode);
  else if (elt == CONST1_RTX (inner_mode))
    return CONST1_RTX (m_mode);
  else if (elt == CONSTM1_RTX (inner_mode))
    return CONSTM1_RTX (m_mode);

  return NULL_RTX;
}
