From 3bdf2bbd3e87625fb26815d48e36fc7fb3656aca Mon Sep 17 00:00:00 2001 From: Ken Werner Date: Fri, 8 Oct 2010 16:50:55 +0000 Subject: [PATCH] gdb: * valops.c (value_cast): Handle vector types. * valarith.c (value_binop): Widen scalar to vector if appropriate. gdb/testsuite: * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. --- gdb/ChangeLog | 5 ++++ gdb/testsuite/ChangeLog | 5 ++++ gdb/testsuite/gdb.base/gnu_vector.c | 34 +++++++++++++++++++-------- gdb/testsuite/gdb.base/gnu_vector.exp | 34 ++++++++++++++++++++++++--- gdb/valarith.c | 30 +++++++++++++++++++---- gdb/valops.c | 23 +++++++++++++++++- 6 files changed, 112 insertions(+), 19 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 783e62ead9d..31a82363cd7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2010-10-08 Ken Werner + + * valops.c (value_cast): Handle vector types. + * valarith.c (value_binop): Widen scalar to vector if appropriate. + 2010-10-08 Ulrich Weigand * arm-tdep.c (thumb_expand_immediate): New function. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 3686c823abb..ae98e6eb630 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-08 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. + 2010-10-06 Ken Werner * gdb.base/constvars.c (logical, lugged, luck, lunar, lumen, lurk, diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c index 4bcb6e58b2a..5b335cd352c 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.c +++ b/gdb/testsuite/gdb.base/gnu_vector.c @@ -17,16 +17,30 @@ Contributed by Ken Werner */ -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}; -float __attribute__ ((vector_size (4 * sizeof(float)))) f4a = {2, 4, 8, 16}; -float __attribute__ ((vector_size (4 * sizeof(float)))) f4b = {1, 2, 8, 4}; -unsigned int __attribute__ ((vector_size (4 * sizeof(unsigned int)))) ui4 = {2, 4, 8, 16}; -int __attribute__ ((vector_size (2 * sizeof(int)))) i2 = {1, 2}; -long long __attribute__ ((vector_size (2 * sizeof(long long)))) ll2 = {1, 2}; -float __attribute__ ((vector_size (2 * sizeof(float)))) f2 = {1, 2}; -double __attribute__ ((vector_size (2 * sizeof(double)))) d2 = {1, 2}; +typedef int __attribute__ ((vector_size (4 * sizeof(int)))) int4; +typedef unsigned int __attribute__ ((vector_size (4 * sizeof(unsigned int)))) uint4; +typedef char __attribute__ ((vector_size (4 * sizeof(char)))) char4; +typedef float __attribute__ ((vector_size (4 * sizeof(float)))) float4; + +typedef int __attribute__ ((vector_size (2 * sizeof(int)))) int2; +typedef long long __attribute__ ((vector_size (2 * sizeof(long long)))) longlong2; +typedef float __attribute__ ((vector_size (2 * sizeof(float)))) float2; +typedef double __attribute__ ((vector_size (2 * sizeof(double)))) double2; + +int ia = 2; +int ib = 1; +float fa = 2; +float fb = 1; +char4 c4 = {1, 2, 3, 4}; +int4 i4a = {2, 4, 8, 16}; +int4 i4b = {1, 2, 8, 4}; +float4 f4a = {2, 4, 8, 16}; +float4 f4b = {1, 2, 8, 4}; +uint4 ui4 = {2, 4, 8, 16}; +int2 i2 = {1, 2}; +longlong2 ll2 = {1, 2}; +float2 f2 = {1, 2}; +double2 d2 = {1, 2}; int main () diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp index bedc059382e..e786365fb6d 100644 --- a/gdb/testsuite/gdb.base/gnu_vector.exp +++ b/gdb/testsuite/gdb.base/gnu_vector.exp @@ -76,9 +76,37 @@ gdb_test "print f4a - f4b" "\\\$$decimal = \\{1, 2, 0, 12\\}" 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 (int2) 1" "\\\$$decimal = \\{1, 1\\}" +gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}" +gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}" +gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}" +gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}" +gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}" +gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}" +gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}" + +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" diff --git a/gdb/valarith.c b/gdb/valarith.c index d75fdd2b530..554c4ff3a29 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -1435,14 +1435,34 @@ vector_binop (struct value *val1, struct value *val2, enum exp_opcode op) struct value * value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { + struct value *val; struct type *type1 = check_typedef (value_type (arg1)); struct type *type2 = check_typedef (value_type (arg2)); - - if ((TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)) - || (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2))) - return vector_binop (arg1, arg2, op); + int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type1)); + int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type2)); + + if (!t1_is_vec && !t2_is_vec) + val = scalar_binop (arg1, arg2, op); + else if (t1_is_vec && t2_is_vec) + val = vector_binop (arg1, arg2, op); else - return scalar_binop (arg1, arg2, op); + { + /* Widen the scalar operand to a vector. */ + struct value **v = t1_is_vec ? &arg2 : &arg1; + struct type *t = t1_is_vec ? type2 : type1; + + if (TYPE_CODE (t) != TYPE_CODE_FLT + && TYPE_CODE (t) != TYPE_CODE_DECFLOAT + && !is_integral_type (t)) + error (_("Argument to operation not a number or boolean.")); + + *v = value_cast (t1_is_vec ? type1 : type2, *v); + val = vector_binop (arg1, arg2, op); + } + + return val; } /* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ diff --git a/gdb/valops.c b/gdb/valops.c index 13c83ffc474..fe4576ec8ae 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -421,7 +421,8 @@ value_cast (struct type *type, struct value *arg2) } 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 value *arg2) 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) -- 2.30.2