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~