On 11/10/2011 11:09 AM, Jakub Jelinek wrote:
> + if (TREE_CODE (arg0) == VECTOR_CST)
> + {
> + for (i = 0, t = TREE_VECTOR_CST_ELTS (arg0);
> + i < nelements && t; i++, t = TREE_CHAIN (t))
> + elements[i] = TREE_VALUE (t);
> + if (t)
> + return NULL_TREE;
> + }
> + else
> + FOR_EACH_VEC_ELT (constructor_elt, CONSTRUCTOR_ELTS (arg0), i, elt)
> + if (i >= nelements)
> + return NULL_TREE;
> + else
> + elements[i] = elt->value;
> + if (i < nelements)
> + return NULL_TREE;
Subroutine.
> + if (TREE_CODE (arg0) == VECTOR_CST)
> + {
> + for (i = 0, t = TREE_VECTOR_CST_ELTS (arg1);
Typo in test -- arg1. Not that you'll make that mistake after
reusing the above subroutine. ;-)
> + for (i = 0; i < nelements; i++)
> + {
> + unsigned int idx;
> + switch (code)
> + {
> + case VEC_EXTRACT_EVEN_EXPR:
> + idx = i * 2;
> + break;
> + case VEC_EXTRACT_ODD_EXPR:
> + idx = i * 2 + 1;
> + break;
> + case VEC_INTERLEAVE_HIGH_EXPR:
> + idx = (i + nelements) / 2 + ((i & 1) ? nelements : 0);
> + break;
> + case VEC_INTERLEAVE_LOW_EXPR:
> + idx = i / 2 + ((i & 1) ? nelements : 0);
> + break;
> + default:
> + gcc_unreachable ();
> + }
> +
> + if (!CONSTANT_CLASS_P (elements[idx]))
> + need_ctor = true;
> + elements[i + 2 * nelements] = elements[idx];
> + }
> +
> + if (need_ctor)
> + {
> + VEC(constructor_elt,gc) *v
> + = VEC_alloc (constructor_elt, gc, nelements);
> + for (i = 0; i < nelements; i++)
> + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
> + elements[2 * nelements + i]);
> + return build_constructor (type, v);
> + }
> + else
> + {
> + tree vals = NULL_TREE;
> + for (i = 0; i < nelements; i++)
> + vals = tree_cons (NULL_TREE,
> + elements[3 * nelements - i - 1], vals);
> + return build_vector (type, vals);
> + }
>From need_ctor on, definitely a subroutine.
It's tempting to suggest that you build an integral array of the indicies
so that this whole block can be shared with vec_perm.
> + for (i = 0, t = TREE_VECTOR_CST_ELTS (arg2);
> + i < nelements && t; i++, t = TREE_CHAIN (t))
> + {
> + unsigned HOST_WIDE_INT idx;
> + if (!host_integerp (TREE_VALUE (t), 1))
> + return NULL_TREE;
> + idx = tree_low_cst (TREE_VALUE (t), 1);
> + if (idx >= nelements * 2)
> + return NULL_TREE;
VEC_PERM_EXPR is explicitly modulo. Don't fail, mask.
r~