- /* For widening vector operations, the relevant type is of the arguments,
- not the widened result. */
- if (code == WIDEN_SUM_EXPR)
- type = TREE_TYPE (TREE_OPERAND (rhs, 0));
+ /* The signedness is determined from input argument. */
+ if (code == VEC_UNPACK_FLOAT_HI_EXPR
+ || code == VEC_UNPACK_FLOAT_LO_EXPR)
+ type = TREE_TYPE (rhs1);
+
+ /* Choose between vector shift/rotate by vector and vector shift/rotate by
+ scalar */
+ if (code == LSHIFT_EXPR
+ || code == RSHIFT_EXPR
+ || code == LROTATE_EXPR
+ || code == RROTATE_EXPR)
+ {
+ /* If the 2nd argument is vector, we need a vector/vector shift */
+ if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs2))))
+ op = optab_for_tree_code (code, type, optab_vector);
+ else
+ {
+ /* Try for a vector/scalar shift, and if we don't have one, see if we
+ have a vector/vector shift */
+ op = optab_for_tree_code (code, type, optab_scalar);
+ if (!op
+ || (op->handlers[(int) TYPE_MODE (type)].insn_code
+ == CODE_FOR_nothing))
+ op = optab_for_tree_code (code, type, optab_vector);
+ }
+ }
+ else
+ op = optab_for_tree_code (code, type, optab_default);
+
+ /* For widening/narrowing vector operations, the relevant type is of the
+ arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
+ calculated in the same way above. */
+ if (code == WIDEN_SUM_EXPR
+ || code == VEC_WIDEN_MULT_HI_EXPR
+ || code == VEC_WIDEN_MULT_LO_EXPR
+ || code == VEC_UNPACK_HI_EXPR
+ || code == VEC_UNPACK_LO_EXPR
+ || code == VEC_PACK_TRUNC_EXPR
+ || code == VEC_PACK_SAT_EXPR
+ || code == VEC_PACK_FIX_TRUNC_EXPR)
+ type = TREE_TYPE (rhs1);