| /* A class for building vector rtx constants. | |
| Copyright (C) 2017-2026 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/>. */ | |
| #ifndef GCC_RTX_VECTOR_BUILDER_H | |
| #define GCC_RTX_VECTOR_BUILDER_H | |
| #include "vector-builder.h" | |
| /* This class is used to build VECTOR_CSTs from a sequence of elements. | |
| See vector_builder for more details. */ | |
| class rtx_vector_builder : public vector_builder<rtx, machine_mode, | |
| rtx_vector_builder> | |
| { | |
| typedef vector_builder<rtx, machine_mode, rtx_vector_builder> parent; | |
| friend class vector_builder<rtx, machine_mode, rtx_vector_builder>; | |
| public: | |
| rtx_vector_builder () : m_mode (VOIDmode) {} | |
| rtx_vector_builder (machine_mode, unsigned int, unsigned int); | |
| rtx build (rtvec); | |
| rtx build (); | |
| machine_mode mode () const { return m_mode; } | |
| void new_vector (machine_mode, unsigned int, unsigned int); | |
| private: | |
| bool equal_p (rtx, rtx) const; | |
| bool allow_steps_p () const; | |
| bool integral_p (rtx) const; | |
| poly_wide_int step (rtx, rtx) const; | |
| rtx apply_step (rtx, unsigned int, const poly_wide_int &) const; | |
| bool can_elide_p (rtx) const { return true; } | |
| void note_representative (rtx *, rtx) {} | |
| static poly_uint64 shape_nelts (machine_mode mode) | |
| { return GET_MODE_NUNITS (mode); } | |
| static poly_uint64 nelts_of (const_rtx x) | |
| { return CONST_VECTOR_NUNITS (x); } | |
| static unsigned int npatterns_of (const_rtx x) | |
| { return CONST_VECTOR_NPATTERNS (x); } | |
| static unsigned int nelts_per_pattern_of (const_rtx x) | |
| { return CONST_VECTOR_NELTS_PER_PATTERN (x); } | |
| rtx find_cached_value (); | |
| machine_mode m_mode; | |
| }; | |
| /* Create a new builder for a vector of mode MODE. Initially encode the | |
| value as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements | |
| each. */ | |
| inline | |
| rtx_vector_builder::rtx_vector_builder (machine_mode mode, | |
| unsigned int npatterns, | |
| unsigned int nelts_per_pattern) | |
| { | |
| new_vector (mode, npatterns, nelts_per_pattern); | |
| } | |
| /* Start building a new vector of mode MODE. Initially encode the value | |
| as NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each. */ | |
| inline void | |
| rtx_vector_builder::new_vector (machine_mode mode, unsigned int npatterns, | |
| unsigned int nelts_per_pattern) | |
| { | |
| m_mode = mode; | |
| parent::new_vector (GET_MODE_NUNITS (mode), npatterns, nelts_per_pattern); | |
| } | |
| /* Return true if elements ELT1 and ELT2 are equal. */ | |
| inline bool | |
| rtx_vector_builder::equal_p (rtx elt1, rtx elt2) const | |
| { | |
| return rtx_equal_p (elt1, elt2); | |
| } | |
| /* Return true if a stepped representation is OK. We don't allow | |
| linear series for anything other than integers, to avoid problems | |
| with rounding. */ | |
| inline bool | |
| rtx_vector_builder::allow_steps_p () const | |
| { | |
| return is_a <scalar_int_mode> (GET_MODE_INNER (m_mode)); | |
| } | |
| /* Return true if element ELT can be interpreted as an integer. */ | |
| inline bool | |
| rtx_vector_builder::integral_p (rtx elt) const | |
| { | |
| return CONST_SCALAR_INT_P (elt); | |
| } | |
| /* Return the value of element ELT2 minus the value of element ELT1. | |
| Both elements are known to be CONST_SCALAR_INT_Ps. */ | |
| inline poly_wide_int | |
| rtx_vector_builder::step (rtx elt1, rtx elt2) const | |
| { | |
| return (wi::to_poly_wide (elt2, GET_MODE_INNER (m_mode)) | |
| - wi::to_poly_wide (elt1, GET_MODE_INNER (m_mode))); | |
| } | |
| #endif |