ChangeLog: 2010-10-07 Ken Werner * valops.c (value_cast): Handle vector types. * eval.c (binop_promote): Likewise. (evaluate_subexp_standard) : Call value_cast to widen scalars to vectors. testsuite/ChangeLog: 2010-10-07 Ken Werner * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. Index: gdb/eval.c =================================================================== RCS file: /cvs/src/src/gdb/eval.c,v retrieving revision 1.139 diff -p -u -r1.139 eval.c --- gdb/eval.c 11 Aug 2010 16:48:26 -0000 1.139 +++ gdb/eval.c 7 Oct 2010 20:16:53 -0000 @@ -574,6 +574,7 @@ binop_promote (const struct language_def struct type *promoted_type = NULL; struct type *type1; struct type *type2; + int t1_is_vec, t2_is_vec; *arg1 = coerce_ref (*arg1); *arg2 = coerce_ref (*arg2); @@ -581,15 +582,21 @@ binop_promote (const struct language_def type1 = check_typedef (value_type (*arg1)); type2 = check_typedef (value_type (*arg2)); - if ((TYPE_CODE (type1) != TYPE_CODE_FLT + t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)); + t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)); + + if (((TYPE_CODE (type1) != TYPE_CODE_FLT && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT && !is_integral_type (type1)) || (TYPE_CODE (type2) != TYPE_CODE_FLT && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT && !is_integral_type (type2))) + && t1_is_vec == t2_is_vec) return; - if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT + if (t1_is_vec != t2_is_vec) + promoted_type = t1_is_vec ? type1 : type2; + else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT || TYPE_CODE (type2) == TYPE_CODE_DECFLOAT) { /* No promotion required. */ @@ -2035,8 +2042,12 @@ evaluate_subexp_standard (struct type *e /* For shift and integer exponentiation operations, only promote the first argument. */ - if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP) - && is_integral_type (value_type (arg2))) + if (op == BINOP_LSH || op == BINOP_RSH) + { + arg2 = value_cast (check_typedef (value_type (arg1)), arg2); + unop_promote (exp->language_defn, exp->gdbarch, &tmp); + } + else if (op == BINOP_EXP && is_integral_type (value_type (arg2))) unop_promote (exp->language_defn, exp->gdbarch, &tmp); else binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2); @@ -2130,9 +2141,13 @@ evaluate_subexp_standard (struct type *e { /* For shift and integer exponentiation operations, only promote the first argument. */ - if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP) - && is_integral_type (value_type (arg2))) + if (op == BINOP_LSH || op == BINOP_RSH) + { + arg2 = value_cast (check_typedef (value_type (arg1)), arg2); unop_promote (exp->language_defn, exp->gdbarch, &arg1); + } + else if (op == BINOP_EXP && is_integral_type (value_type (arg2))) + unop_promote (exp->language_defn, exp->gdbarch, &arg1); else binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.251 diff -p -u -r1.251 valops.c --- gdb/valops.c 24 Sep 2010 14:47:53 -0000 1.251 +++ gdb/valops.c 7 Oct 2010 20:16:53 -0000 @@ -421,7 +421,8 @@ value_cast (struct type *type, struct va } if (current_language->c_style_arrays - && TYPE_CODE (type2) == TYPE_CODE_ARRAY) + && TYPE_CODE (type2) == TYPE_CODE_ARRAY + && !TYPE_VECTOR (type2)) arg2 = value_coerce_array (arg2); if (TYPE_CODE (type2) == TYPE_CODE_FUNC) @@ -537,6 +538,26 @@ value_cast (struct type *type, struct va minus one, instead of biasing the normal case. */ return value_from_longest (type, -1); } + else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar) + { + /* Widen the scalar to a vector. */ + struct type *eltype; + struct value *val; + int i, n; + + eltype = check_typedef (TYPE_TARGET_TYPE (type)); + arg2 = value_cast (eltype, arg2); + val = allocate_value (type); + n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype); + + for (i = 0; i < n; i++) + { + /* Duplicate the contents of arg2 into the destination vector. */ + memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)), + value_contents_all (arg2), TYPE_LENGTH (eltype)); + } + return val; + } else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) Index: gdb/testsuite/gdb.base/gnu_vector.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.c --- gdb/testsuite/gdb.base/gnu_vector.c 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.c 7 Oct 2010 20:16:53 -0000 @@ -17,6 +17,10 @@ Contributed by Ken Werner */ +int ia = 2; +int ib = 1; +float fa = 2; +float fb = 1; char __attribute__ ((vector_size (4 * sizeof(char)))) c4 = {1, 2, 3, 4}; int __attribute__ ((vector_size (4 * sizeof(int)))) i4a = {2, 4, 8, 16}; int __attribute__ ((vector_size (4 * sizeof(int)))) i4b = {1, 2, 8, 4}; Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.exp 7 Oct 2010 20:16:53 -0000 @@ -76,9 +76,28 @@ gdb_test "print f4a - f4b" "\\\$$decimal gdb_test "print f4a * f4b" "\\\$$decimal = \\{2, 8, 64, 64\\}" gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}" -# Test error conditions -gdb_test "print i4a + 1" "Vector operations are only supported among vectors" -gdb_test "print 1 + f4a" "Vector operations are only supported among vectors" +# Test scalar to vector widening +gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}" +gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}" +gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}" + +gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}" +gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}" +gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" +gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}" + +gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}" +gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}" +gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}" +gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}" + +gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" + +# Test some error scenarios gdb_test "print i4a + d2" "Cannot perform operation on vectors with different types" gdb_test "print d2 + i4a" "Cannot perform operation on vectors with different types" gdb_test "print f4a + ll2" "Cannot perform operation on vectors with different types"