/* Lower vector operations to scalar operations.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
{
if (bitpos)
return gimplify_build3 (bsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
-
- /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
- anyway be stored in memory, so prefer NOP_EXPR. */
- else if (TYPE_MODE (type) == BLKmode)
- return gimplify_build1 (bsi, VIEW_CONVERT_EXPR, type, t);
else
- return gimplify_build1 (bsi, NOP_EXPR, type, t);
+ return gimplify_build1 (bsi, VIEW_CONVERT_EXPR, type, t);
}
static tree
{
case PLUS_EXPR:
case MINUS_EXPR:
- if (!TYPE_TRAP_SIGNED (type))
+ if (!TYPE_OVERFLOW_TRAPS (type))
return expand_vector_addition (bsi, do_binop, do_plus_minus, type,
TREE_OPERAND (rhs, 0),
TREE_OPERAND (rhs, 1), code);
break;
case NEGATE_EXPR:
- if (!TYPE_TRAP_SIGNED (type))
+ if (!TYPE_OVERFLOW_TRAPS (type))
return expand_vector_addition (bsi, do_unop, do_negate, type,
TREE_OPERAND (rhs, 0),
NULL_TREE, code);
enum machine_mode best_mode = VOIDmode, mode;
int best_nunits = 0;
- if (GET_MODE_CLASS (inner_mode) == MODE_FLOAT)
+ if (SCALAR_FLOAT_MODE_P (inner_mode))
mode = MIN_MODE_VECTOR_FLOAT;
else
mode = MIN_MODE_VECTOR_INT;
{
case RETURN_EXPR:
stmt = TREE_OPERAND (stmt, 0);
- if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
+ if (!stmt || TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
return;
/* FALLTHRU */
- case MODIFY_EXPR:
- p_lhs = &TREE_OPERAND (stmt, 0);
- p_rhs = &TREE_OPERAND (stmt, 1);
+ case GIMPLE_MODIFY_STMT:
+ p_lhs = &GIMPLE_STMT_OPERAND (stmt, 0);
+ p_rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
lhs = *p_lhs;
rhs = *p_rhs;
break;
gcc_assert (code != CONVERT_EXPR);
op = optab_for_tree_code (code, type);
+ /* For widening/narrowing vector operations, the relevant type is of the
+ arguments, not the widened result. */
+ 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_MOD_EXPR
+ || code == VEC_PACK_SAT_EXPR)
+ type = TREE_TYPE (TREE_OPERAND (rhs, 0));
+
/* Optabs will try converting a negation into a subtraction, so
look for it as well. TODO: negation of floating-point vectors
might be turned into an exclusive OR toggling the sign bit. */
if (lang_hooks.types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
*p_rhs = rhs;
else
- {
- /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
- be stored in memory anyway, so prefer NOP_EXPR. We should also try
- performing the VIEW_CONVERT_EXPR on the left side of the
- assignment. */
- if (TYPE_MODE (TREE_TYPE (rhs)) == BLKmode)
- *p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
- else
- *p_rhs = gimplify_build1 (bsi, NOP_EXPR, TREE_TYPE (lhs), rhs);
- }
+ *p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
mark_stmt_modified (bsi_stmt (*bsi));
}
return flag_tree_vectorize != 0;
}
-static void
+static unsigned int
expand_vector_operations (void)
{
block_stmt_iterator bsi;
update_stmt_if_modified (bsi_stmt (bsi));
}
}
+ return 0;
}
struct tree_opt_pass pass_lower_vector =