diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a52f4a6becc..7e5f8cd5386 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-02-13 Stan Shebs + + * c-typeck.c (digest_init): Handle vectors. + (really_start_incremental_init): Same. + (pop_init_level): Same. + (process_init_element): Same. + + * varasm.c (output_constant): Same. + + * expr.c (clear_storage): Same. + (store_constructor): Same. + 2002-02-12 Eric Christopher * explow.c (hard_function_value): Add comment explaining diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 5d5b5f97870..3e00e04b48b 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4830,6 +4830,8 @@ digest_init (type, init, require_constant, constructor_constant) TYPE_MAIN_VARIANT (type)) || (code == ARRAY_TYPE && comptypes (TREE_TYPE (inside_init), type)) + || (code == VECTOR_TYPE + && comptypes (TREE_TYPE (inside_init), type)) || (code == POINTER_TYPE && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE) @@ -5341,6 +5343,14 @@ really_start_incremental_init (type) constructor_unfilled_index = constructor_index; } + else if (TREE_CODE (constructor_type) == VECTOR_TYPE) + { + /* Vectors are like simple fixed-size arrays. */ + constructor_max_index = + build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0); + constructor_index = convert (bitsizetype, integer_zero_node); + constructor_unfilled_index = constructor_index; + } else { /* Handle the case of int x = {5}; */ @@ -5623,7 +5633,8 @@ pop_init_level (implicit) ; else if (TREE_CODE (constructor_type) != RECORD_TYPE && TREE_CODE (constructor_type) != UNION_TYPE - && TREE_CODE (constructor_type) != ARRAY_TYPE) + && TREE_CODE (constructor_type) != ARRAY_TYPE + && TREE_CODE (constructor_type) != VECTOR_TYPE) { /* A nonincremental scalar initializer--just return the element, after verifying there is just one. */ @@ -6832,6 +6843,31 @@ process_init_element (value) constructor_unfilled_index. */ constructor_unfilled_index = constructor_index; } + else if (TREE_CODE (constructor_type) == VECTOR_TYPE) + { + tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); + + /* Do a basic check of initializer size. Note that vectors + always have a fixed size derived from their type. */ + if (tree_int_cst_lt (constructor_max_index, constructor_index)) + { + pedwarn_init ("excess elements in vector initializer"); + break; + } + + /* Now output the actual element. */ + if (value) + output_init_element (value, elttype, constructor_index, 1); + + constructor_index + = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node); + + if (! value) + /* If we are doing the bookkeeping for an element that was + directly output as a constructor, we must update + constructor_unfilled_index. */ + constructor_unfilled_index = constructor_index; + } /* Handle the sole element allowed in a braced initializer for a scalar variable. */ diff --git a/gcc/expr.c b/gcc/expr.c index 13995eef670..702b6897218 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -2562,7 +2562,8 @@ clear_storage (object, size) /* If OBJECT is not BLKmode and SIZE is the same size as its mode, just move a zero. Otherwise, do this a piece at a time. */ - if (GET_MODE (object) != BLKmode + if ((GET_MODE (object) != BLKmode + && !VECTOR_MODE_P (GET_MODE (object))) && GET_CODE (size) == CONST_INT && GET_MODE_SIZE (GET_MODE (object)) == (unsigned int) INTVAL (size)) emit_move_insn (object, CONST0_RTX (GET_MODE (object))); @@ -4528,20 +4529,34 @@ store_constructor (exp, target, cleared, size) get_alias_set (TREE_TYPE (field))); } } - else if (TREE_CODE (type) == ARRAY_TYPE) + else if (TREE_CODE (type) == ARRAY_TYPE + || TREE_CODE (type) == VECTOR_TYPE) { tree elt; int i; int need_to_clear; tree domain = TYPE_DOMAIN (type); tree elttype = TREE_TYPE (type); - int const_bounds_p = (TYPE_MIN_VALUE (domain) - && TYPE_MAX_VALUE (domain) - && host_integerp (TYPE_MIN_VALUE (domain), 0) - && host_integerp (TYPE_MAX_VALUE (domain), 0)); + int const_bounds_p; HOST_WIDE_INT minelt = 0; HOST_WIDE_INT maxelt = 0; + /* Vectors are like arrays, but the domain is stored via an array + type indirectly. */ + if (TREE_CODE (type) == VECTOR_TYPE) + { + /* Note that although TYPE_DEBUG_REPRESENTATION_TYPE uses + the same field as TYPE_DOMAIN, we are not guaranteed that + it always will. */ + domain = TYPE_DEBUG_REPRESENTATION_TYPE (type); + domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain))); + } + + const_bounds_p = (TYPE_MIN_VALUE (domain) + && TYPE_MAX_VALUE (domain) + && host_integerp (TYPE_MIN_VALUE (domain), 0) + && host_integerp (TYPE_MAX_VALUE (domain), 0)); + /* If we have constant bounds for the range of the type, get them. */ if (const_bounds_p) { @@ -4665,6 +4680,7 @@ store_constructor (exp, target, cleared, size) if (GET_CODE (target) == MEM && !MEM_KEEP_ALIAS_SET_P (target) + && TREE_CODE (type) == ARRAY_TYPE && TYPE_NONALIASED_COMPONENT (type)) { target = copy_rtx (target); @@ -4762,6 +4778,7 @@ store_constructor (exp, target, cleared, size) bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1)); if (GET_CODE (target) == MEM && !MEM_KEEP_ALIAS_SET_P (target) + && TREE_CODE (type) == ARRAY_TYPE && TYPE_NONALIASED_COMPONENT (type)) { target = copy_rtx (target); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d9766b06395..d85cdbb559b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-02-13 Stan Shebs + + * gcc.dg/altivec-3.c: New. + 2002-02-12 Jakub Jelinek * gcc.dg/Wunreachable-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/altivec-3.c b/gcc/testsuite/gcc.dg/altivec-3.c new file mode 100644 index 00000000000..c82f1e2a214 --- /dev/null +++ b/gcc/testsuite/gcc.dg/altivec-3.c @@ -0,0 +1,69 @@ +/* { dg-do run { target powerpc-*-*altivec powerpc-*-*-*altivec } } */ +/* { dg-options "-maltivec" } */ + +typedef int int4 __attribute__ ((mode(V4SI))); +typedef float float4 __attribute__ ((mode(V4SF))); + +int4 a1 = (int4) { 100, 200, 300, 400 }; +int4 a2 = (int4) { 500, 600, 700, 800 }; + +float4 f1 = (float4) { 1.0, 2.0, 3.0, 4.0 }; +float4 f2 = (float4) { 5.0, 6.0, 7.0, 8.0 }; + +int i3[4] __attribute__((aligned(16))); +int j3[4] __attribute__((aligned(16))); +float h3[4] __attribute__((aligned(16))); +float g3[4] __attribute__((aligned(16))); + +#define vec_store(dst, src) \ + __builtin_altivec_st_internal_4si ((int *) dst, (int4) src) + +#define vec_add_int4(x, y) \ + __builtin_altivec_vaddsws (x, y) + +#define vec_add_float4(x, y) \ + __builtin_altivec_vaddfp (x, y) + +#define my_abs(x) (x > 0.0F ? x : -x) + +void +compare_int4 (int *a, int *b) +{ + int i; + + for (i = 0; i < 4; ++i) + if (a[i] != b[i]) + abort (); +} + +void +compare_float4 (float *a, float *b) +{ + int i; + + for (i = 0; i < 4; ++i) + if (my_abs(a[i] - b[i]) >= 1.0e-6) + abort (); +} + +main () +{ + int loc1 = 600, loc2 = 800; + int4 a3 = (int4) { loc1, loc2, 1000, 1200 }; + int4 itmp; + double locf = 12.0; + float4 f3 = (float4) { 6.0, 8.0, 10.0, 12.0 }; + float4 ftmp; + + vec_store (i3, a3); + itmp = vec_add_int4 (a1, a2); + vec_store (j3, itmp); + compare_int4 (i3, j3); + + vec_store (g3, f3); + ftmp = vec_add_float4 (f1, f2); + vec_store (h3, ftmp); + compare_float4 (g3, h3); + + exit (0); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index e542817d1d0..0ca2172c32c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -4519,6 +4519,7 @@ output_constant (exp, size, align) break; case ARRAY_TYPE: + case VECTOR_TYPE: if (TREE_CODE (exp) == CONSTRUCTOR) { output_constructor (exp, size, align);