return NULL_RTX;
}
\f
-/* Examine CTOR to discover:
- * how many scalar fields are set to nonzero values,
- and place it in *P_NZ_ELTS;
- * how many scalar fields are set to non-constant values,
- and place it in *P_NC_ELTS; and
- * how many scalar fields in total are in CTOR,
- and place it in *P_ELT_COUNT.
- * if a type is a union, and the initializer from the constructor
- is not the largest element in the union, then set *p_must_clear. */
+/* Helper for categorize_ctor_elements. Identical interface. */
-static void
+static bool
categorize_ctor_elements_1 (tree ctor, HOST_WIDE_INT *p_nz_elts,
- HOST_WIDE_INT *p_nc_elts,
HOST_WIDE_INT *p_elt_count,
bool *p_must_clear)
{
unsigned HOST_WIDE_INT idx;
- HOST_WIDE_INT nz_elts, nc_elts, elt_count;
+ HOST_WIDE_INT nz_elts, elt_count;
tree value, purpose;
+ /* Whether CTOR is a valid constant initializer, in accordance with what
+ initializer_constant_valid_p does. If inferred from the constructor
+ elements, true until proven otherwise. */
+ bool const_from_elts_p = constructor_static_from_elts_p (ctor);
+ bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
+
nz_elts = 0;
- nc_elts = 0;
elt_count = 0;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
{
case CONSTRUCTOR:
{
- HOST_WIDE_INT nz = 0, nc = 0, ic = 0;
- categorize_ctor_elements_1 (value, &nz, &nc, &ic, p_must_clear);
+ HOST_WIDE_INT nz = 0, ic = 0;
+
+ bool const_elt_p
+ = categorize_ctor_elements_1 (value, &nz, &ic, p_must_clear);
+
nz_elts += mult * nz;
- nc_elts += mult * nc;
- elt_count += mult * ic;
+ elt_count += mult * ic;
+
+ if (const_from_elts_p && const_p)
+ const_p = const_elt_p;
}
break;
default:
nz_elts += mult;
elt_count += mult;
- if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
- nc_elts += mult;
+
+ if (const_from_elts_p && const_p)
+ const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
+ != NULL_TREE;
break;
}
}
}
*p_nz_elts += nz_elts;
- *p_nc_elts += nc_elts;
*p_elt_count += elt_count;
+
+ return const_p;
}
-void
+/* Examine CTOR to discover:
+ * how many scalar fields are set to nonzero values,
+ and place it in *P_NZ_ELTS;
+ * how many scalar fields in total are in CTOR,
+ and place it in *P_ELT_COUNT.
+ * if a type is a union, and the initializer from the constructor
+ is not the largest element in the union, then set *p_must_clear.
+
+ Return whether or not CTOR is a valid static constant initializer, the same
+ as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
+
+bool
categorize_ctor_elements (tree ctor, HOST_WIDE_INT *p_nz_elts,
- HOST_WIDE_INT *p_nc_elts,
HOST_WIDE_INT *p_elt_count,
bool *p_must_clear)
{
*p_nz_elts = 0;
- *p_nc_elts = 0;
*p_elt_count = 0;
*p_must_clear = false;
- categorize_ctor_elements_1 (ctor, p_nz_elts, p_nc_elts, p_elt_count,
- p_must_clear);
+
+ return
+ categorize_ctor_elements_1 (ctor, p_nz_elts, p_elt_count, p_must_clear);
}
/* Count the number of scalars in TYPE. Return -1 on overflow or
if (TREE_CODE (exp) == CONSTRUCTOR)
{
- HOST_WIDE_INT nz_elts, nc_elts, count, elts;
+ HOST_WIDE_INT nz_elts, count, elts;
bool must_clear;
- categorize_ctor_elements (exp, &nz_elts, &nc_elts, &count, &must_clear);
+ categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
if (must_clear)
return 1;
if (TREE_CODE (exp) == CONSTRUCTOR)
{
- HOST_WIDE_INT nz_elts, nc_elts, count;
+ HOST_WIDE_INT nz_elts, count;
bool must_clear;
- categorize_ctor_elements (exp, &nz_elts, &nc_elts, &count, &must_clear);
+ categorize_ctor_elements (exp, &nz_elts, &count, &must_clear);
return nz_elts == 0;
}
case ZERO_EXTEND:
case SIGN_EXTEND:
case TRUNCATE:
+ case FLOAT_EXTEND:
+ case FLOAT_TRUNCATE:
convert_move (target, op1, code == ZERO_EXTEND);
return target;
return REDUCE_BIT_FIELD (op0);
}
- op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode,
+ modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
if (GET_MODE (op0) == mode)
;
subtarget, &op0, &op1, 0);
return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
- case FIX_ROUND_EXPR:
- case FIX_FLOOR_EXPR:
- case FIX_CEIL_EXPR:
- gcc_unreachable (); /* Not used for C. */
-
case FIX_TRUNC_EXPR:
op0 = expand_normal (TREE_OPERAND (exp, 0));
if (target == 0 || modifier == EXPAND_STACK_PARM)
return target;
}
+ case VEC_UNPACK_HI_EXPR:
+ case VEC_UNPACK_LO_EXPR:
+ {
+ op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
+ this_optab = optab_for_tree_code (code, type);
+ temp = expand_widen_pattern_expr (exp, op0, NULL_RTX, NULL_RTX,
+ target, unsignedp);
+ gcc_assert (temp);
+ return temp;
+ }
+
+ case VEC_WIDEN_MULT_HI_EXPR:
+ case VEC_WIDEN_MULT_LO_EXPR:
+ {
+ tree oprnd0 = TREE_OPERAND (exp, 0);
+ tree oprnd1 = TREE_OPERAND (exp, 1);
+
+ expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, 0);
+ target = expand_widen_pattern_expr (exp, op0, op1, NULL_RTX,
+ target, unsignedp);
+ gcc_assert (target);
+ return target;
+ }
+
+ case VEC_PACK_MOD_EXPR:
+ case VEC_PACK_SAT_EXPR:
+ {
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ goto binop;
+ }
+
default:
return lang_hooks.expand_expr (exp, original_target, tmode,
modifier, alt_rtl);