aboutsummaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-02 18:28:14 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-02 18:28:14 +0000
commitcd5ff7bc323a8fa6eafc4513bc814e4e7fa24120 (patch)
tree4a69a3ee23bde8480b983e60720932a0219c7a95 /gcc/emit-rtl.c
parent3d8ca53dd9b4c42b07ef974f92c3c4553cce3a79 (diff)
downloadgcc-cd5ff7bc323a8fa6eafc4513bc814e4e7fa24120.zip
gcc-cd5ff7bc323a8fa6eafc4513bc814e4e7fa24120.tar.gz
gcc-cd5ff7bc323a8fa6eafc4513bc814e4e7fa24120.tar.bz2
Make CONST_VECTOR_ELT handle implicitly-encoded elements
This patch makes CONST_VECTOR_ELT handle implicitly-encoded elements, in a similar way to VECTOR_CST_ELT. 2018-01-02 Richard Sandiford <richard.sandiford@linaro.org> gcc/ * rtl.h (CONST_VECTOR_ELT): Redefine to const_vector_elt. (const_vector_encoded_nelts): New function. (CONST_VECTOR_NUNITS): Redefine to use GET_MODE_NUNITS. (const_vector_int_elt, const_vector_elt): Declare. * emit-rtl.c (const_vector_int_elt_1): New function. (const_vector_elt): Likewise. * simplify-rtx.c (simplify_immed_subreg): Avoid taking the address of CONST_VECTOR_ELT. From-SVN: r256104
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index c9599e1..e282b3d 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -5862,6 +5862,62 @@ init_emit (void)
#endif
}
+/* Return the value of element I of CONST_VECTOR X as a wide_int. */
+
+wide_int
+const_vector_int_elt (const_rtx x, unsigned int i)
+{
+ /* First handle elements that are directly encoded. */
+ machine_mode elt_mode = GET_MODE_INNER (GET_MODE (x));
+ if (i < (unsigned int) XVECLEN (x, 0))
+ return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, i), elt_mode);
+
+ /* Identify the pattern that contains element I and work out the index of
+ the last encoded element for that pattern. */
+ unsigned int encoded_nelts = const_vector_encoded_nelts (x);
+ unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
+ unsigned int count = i / npatterns;
+ unsigned int pattern = i % npatterns;
+ unsigned int final_i = encoded_nelts - npatterns + pattern;
+
+ /* If there are no steps, the final encoded value is the right one. */
+ if (!CONST_VECTOR_STEPPED_P (x))
+ return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, final_i), elt_mode);
+
+ /* Otherwise work out the value from the last two encoded elements. */
+ rtx v1 = CONST_VECTOR_ENCODED_ELT (x, final_i - npatterns);
+ rtx v2 = CONST_VECTOR_ENCODED_ELT (x, final_i);
+ wide_int diff = wi::sub (rtx_mode_t (v2, elt_mode),
+ rtx_mode_t (v1, elt_mode));
+ return wi::add (rtx_mode_t (v2, elt_mode), (count - 2) * diff);
+}
+
+/* Return the value of element I of CONST_VECTOR X. */
+
+rtx
+const_vector_elt (const_rtx x, unsigned int i)
+{
+ /* First handle elements that are directly encoded. */
+ if (i < (unsigned int) XVECLEN (x, 0))
+ return CONST_VECTOR_ENCODED_ELT (x, i);
+
+ /* If there are no steps, the final encoded value is the right one. */
+ if (!CONST_VECTOR_STEPPED_P (x))
+ {
+ /* Identify the pattern that contains element I and work out the index of
+ the last encoded element for that pattern. */
+ unsigned int encoded_nelts = const_vector_encoded_nelts (x);
+ unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
+ unsigned int pattern = i % npatterns;
+ unsigned int final_i = encoded_nelts - npatterns + pattern;
+ return CONST_VECTOR_ENCODED_ELT (x, final_i);
+ }
+
+ /* Otherwise work out the value from the last two encoded elements. */
+ return immed_wide_int_const (const_vector_int_elt (x, i),
+ GET_MODE_INNER (GET_MODE (x)));
+}
+
/* Return true if X is a valid element for a CONST_VECTOR of the given
mode. */