Richard Sandiford wrote:
Tejas Belagod <tbela...@arm.com> writes:
+  /* This is big-endian-safe because the elements are kept in target
+     memory order.  So, for eg. PARALLEL element value of 2 is the same in
+     either endian-ness.  */
+  if (GET_CODE (src) == VEC_SELECT
+      && REG_P (XEXP (src, 0)) && REG_P (dst)
+      && REGNO (XEXP (src, 0)) == REGNO (dst))
+    {
+      rtx par = XEXP (src, 1);
+      int i;
+
+      for (i = 0; i < XVECLEN (par, 0); i++)
+       {
+         rtx tem = XVECEXP (par, 0, i);
+         if (!CONST_INT_P (tem) || INTVAL (tem) != i)
+           return 0;
+       }
+      return 1;
+    }
+

I think for big endian it needs to be:

    INTVAL (tem) != i + base

where base is something like:

    int base = GET_MODE_NUNITS (GET_MODE (XEXP (src, 0))) - XVECLEN (par, 0);

E.g. a big-endian V4HI looks like:

    msb          lsb
    0000111122223333

and shortening it to say V2HI only gives the low 32 bits:

            msb  lsb
            22223333

But, in this case we want

        msb  lsb
        00001111

I was under the impression that the const vector parallel for vec_select represents the element indexes of the array in memory order. Therefore,

in bigendian,

         msb             lsb
         0000 1111 2222 3333
element  a[0] a[1] a[2] a[3]

and in littleendian

         msb             lsb
         3333 2222 1111 0000
element  a[3] a[2] a[1] a[0]


so shouldn't a
  vec_select:V2HI ( (reg:V4HI) (parallel ([const 0] [const 1]))

represent the elements {0000, 1111} in both endiannesses? Is my understanding broken?

Thanks,
Tejas.

Reply via email to