OSDN Git Service

* lower-subreg.c (simple_move_operand): New static function,
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-generic.c
index f9c9fda..82d4814 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
    
@@ -106,13 +106,8 @@ tree_vec_extract (block_stmt_iterator *bsi, tree type,
 {
   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
@@ -306,14 +301,14 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
       {
       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);
@@ -353,7 +348,7 @@ type_for_widest_vector_mode (enum machine_mode inner_mode, optab op)
   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;
@@ -385,14 +380,14 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
     {
     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;
@@ -416,6 +411,17 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
   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.  */
@@ -455,16 +461,7 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
   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));
 }
@@ -478,7 +475,7 @@ gate_expand_vector_operations (void)
   return flag_tree_vectorize != 0;
 }
 
-static void
+static unsigned int
 expand_vector_operations (void)
 {
   block_stmt_iterator bsi;
@@ -492,6 +489,7 @@ expand_vector_operations (void)
          update_stmt_if_modified (bsi_stmt (bsi));
        }
     }
+  return 0;
 }
 
 struct tree_opt_pass pass_lower_vector =