From 7346b668d73fe13b9b07b805379ff0e03d3aef5e Mon Sep 17 00:00:00 2001 From: Ken Werner Date: Wed, 11 Aug 2010 16:48:26 +0000 Subject: [PATCH] gdb/ChangeLog:* gdb/valarith.c (vector_binop): New function.(scalar_binop): Likewise.(value_binop): Call scalar_binop or vector_binop depending on the types.* gdb/eval.c (ptrmath_type_p): Return 0 in case of TYPE_VECTOR.(evaluate_subexp_with_coercion): Add vector check to not convert vectorsto pointers.* gdb/value.c (coerce_array): Add vector check to not coerce vectors.testsuite/ChangeLog:* gdb.base/Makefile.in (EXECUTABLES): Add gnu_vector.* gdb.base/gnu_vector.c: New File.* gdb.base/gnu_vector.exp: Likewise. --- gdb/ChangeLog | 10 +++ gdb/eval.c | 3 +- gdb/testsuite/ChangeLog | 6 ++ gdb/testsuite/gdb.base/Makefile.in | 2 +- gdb/testsuite/gdb.base/gnu_vector.c | 34 ++++++++++ gdb/testsuite/gdb.base/gnu_vector.exp | 94 +++++++++++++++++++++++++++ gdb/valarith.c | 69 +++++++++++++++++++- gdb/value.c | 2 +- 8 files changed, 215 insertions(+), 5 deletions(-) create mode 100644 gdb/testsuite/gdb.base/gnu_vector.c create mode 100644 gdb/testsuite/gdb.base/gnu_vector.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4d94b977ca..5098a78743 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2010-08-11 Ken Werner + + * gdb/valarith.c (vector_binop): New function. + (scalar_binop): Likewise. + (value_binop): Call scalar_binop or vector_binop depending on the types. + * gdb/eval.c (ptrmath_type_p): Return 0 in case of TYPE_VECTOR. + (evaluate_subexp_with_coercion): Add vector check to not convert vectors + to pointers. + * gdb/value.c (coerce_array): Add vector check to not coerce vectors. + 2010-08-11 Brad Roberts * d-lang.c (extract_identifiers): Handle multiple digits. diff --git a/gdb/eval.c b/gdb/eval.c index 26947812e6..635db34e22 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -736,7 +736,7 @@ ptrmath_type_p (const struct language_defn *lang, struct type *type) return 1; case TYPE_CODE_ARRAY: - return lang->c_style_arrays; + return TYPE_VECTOR (type) ? 0 : lang->c_style_arrays; default: return 0; @@ -2956,6 +2956,7 @@ evaluate_subexp_with_coercion (struct expression *exp, var = exp->elts[pc + 2].symbol; type = check_typedef (SYMBOL_TYPE (var)); if (TYPE_CODE (type) == TYPE_CODE_ARRAY + && !TYPE_VECTOR (type) && CAST_IS_CONVERSION (exp->language_defn)) { (*pos) += 4; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 778d13e7c4..479e563866 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-08-11 Ken Werner + + * gdb.base/Makefile.in (EXECUTABLES): Add gnu_vector. + * gdb.base/gnu_vector.c: New File. + * gdb.base/gnu_vector.exp: Likewise. + 2010-08-11 Phil Muldoon * gdb.python/python.c: New File. diff --git a/gdb/testsuite/gdb.base/Makefile.in b/gdb/testsuite/gdb.base/Makefile.in index 5e8e38593f..57fc5727f8 100644 --- a/gdb/testsuite/gdb.base/Makefile.in +++ b/gdb/testsuite/gdb.base/Makefile.in @@ -13,7 +13,7 @@ EXECUTABLES = all-types annota1 bitfields break \ solib solib_sl so-impl-ld so-indr-cl \ step-line step-test structs structs2 \ twice-tmp varargs vforked-prog watchpoint whatis catch-syscall \ - pr10179 + pr10179 gnu_vector MISCELLANEOUS = coremmap.data ../foobar.baz \ shr1.sl shr2.sl solib_sl.sl solib1.sl solib2.sl diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c new file mode 100644 index 0000000000..8efb4cb8f2 --- /dev/null +++ b/gdb/testsuite/gdb.base/gnu_vector.c @@ -0,0 +1,34 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contributed by Ken Werner */ + +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}; + +int +main () +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp new file mode 100644 index 0000000000..b2f1dab684 --- /dev/null +++ b/gdb/testsuite/gdb.base/gnu_vector.exp @@ -0,0 +1,94 @@ +# Copyright 2010 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . */ +# +# Contributed by Ken Werner . +# +# Tests GDBs support for GNU vectors. +# http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + +if $tracelevel { + strace $tracelevel +} + +set testfile "gnu_vector" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if [get_compiler_info ${binfile}] { + return -1 +} + +# Check if our compiler is a GCC that suppports the vector extension +if { ![test_compiler_info gcc-4-*] } { + setup_xfail "*-*-*" + fail "This compiler can not handle GNU vectors" + return 0 +} + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug}] } { + return -1 +} + +if { ![runto main] } { + fail "runto main" + return -1 +} + +# Test binary operators on integer vector types +gdb_test "print i4a" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print i4b" "\\\$$decimal = \\{1, 2, 8, 4\\}" +# Arithmetic operators +gdb_test "print i4a + i4b" "\\\$$decimal = \\{3, 6, 16, 20\\}" +gdb_test "print i4a - i4b" "\\\$$decimal = \\{1, 2, 0, 12\\}" +gdb_test "print i4a * i4b" "\\\$$decimal = \\{2, 8, 64, 64\\}" +gdb_test "print i4a / i4b" "\\\$$decimal = \\{2, 2, 1, 4\\}" +gdb_test "print i4a % i4b" "\\\$$decimal = \\{0, 0, 0, 0\\}" +# Bitwise operators +gdb_test "print i4a & i4b" "\\\$$decimal = \\{0, 0, 8, 0\\}" +gdb_test "print i4a | i4b" "\\\$$decimal = \\{3, 6, 8, 20\\}" +gdb_test "print i4a ^ i4b" "\\\$$decimal = \\{3, 6, 0, 20\\}" +# Shift operators +gdb_test "print i4a << i4b" "\\\$$decimal = \\{4, 16, 2048, 256\\}" +gdb_test "print i4a >> i4b" "\\\$$decimal = \\{1, 1, 0, 1\\}" + +# Test binary operators on floating point vector types +gdb_test "print f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print f4b" "\\\$$decimal = \\{1, 2, 8, 4\\}" +# Arithmetic operators +gdb_test "print f4a + f4b" "\\\$$decimal = \\{3, 6, 16, 20\\}" +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" +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" +gdb_test "print ll2 + f4a" "Cannot perform operation on vectors with different types" +gdb_test "print i2 + ll2" "Cannot perform operation on vectors with different types" +gdb_test "print ll2 + i2" "Cannot perform operation on vectors with different types" +gdb_test "print i4a + ll2" "Cannot perform operation on vectors with different types" +gdb_test "print ll2 + i4a" "Cannot perform operation on vectors with different types" +gdb_test "print f4a + d2" "Cannot perform operation on vectors with different types" +gdb_test "print d2 + f4a" "Cannot perform operation on vectors with different types" +gdb_test "print ui4 + i4a" "Cannot perform operation on vectors with different types" +gdb_test "print i4a + ui4" "Cannot perform operation on vectors with different types" +gdb_test "print i4a + i2" "Cannot perform operation on vectors with different sizes" +gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different sizes" +gdb_test "print f4a + f2" "Cannot perform operation on vectors with different sizes" +gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different sizes" + diff --git a/gdb/valarith.c b/gdb/valarith.c index 0c4090581b..d75fdd2b53 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -929,8 +929,8 @@ value_args_as_decimal (struct value *arg1, struct value *arg2, Does not support addition and subtraction on pointers; use value_ptradd, value_ptrsub or value_ptrdiff for those operations. */ -struct value * -value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) +static struct value * +scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { struct value *val; struct type *type1, *type2, *result_type; @@ -1379,6 +1379,71 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) return val; } + +/* Performs a binary operation on two vector operands by calling scalar_binop + for each pair of vector components. */ + +static struct value * +vector_binop (struct value *val1, struct value *val2, enum exp_opcode op) +{ + struct value *val, *tmp, *mark; + struct type *type1, *type2, *eltype1, *eltype2, *result_type; + int t1_is_vec, t2_is_vec, elsize, n, i; + + type1 = check_typedef (value_type (val1)); + type2 = check_typedef (value_type (val2)); + + t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type1)) ? 1 : 0; + t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type2)) ? 1 : 0; + + if (!t1_is_vec || !t2_is_vec) + error (_("Vector operations are only supported among vectors")); + + eltype1 = check_typedef (TYPE_TARGET_TYPE (type1)); + eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)); + + if (TYPE_CODE (eltype1) != TYPE_CODE (eltype2) + || TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) + || TYPE_UNSIGNED (eltype1) != TYPE_UNSIGNED (eltype2)) + error (_("Cannot perform operation on vectors with different types")); + + elsize = TYPE_LENGTH (eltype1); + n = TYPE_LENGTH (type1) / elsize; + + if (n != TYPE_LENGTH (type2) / TYPE_LENGTH (eltype2)) + error (_("Cannot perform operation on vectors with different sizes")); + + val = allocate_value (type1); + mark = value_mark (); + for (i = 0; i < n; i++) + { + tmp = value_binop (value_subscript (val1, i), + value_subscript (val2, i), op); + memcpy (value_contents_writeable (val) + i * elsize, + value_contents_all (tmp), + elsize); + } + value_free_to_mark (mark); + + return val; +} + +/* Perform a binary operation on two operands. */ + +struct value * +value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) +{ + 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); + else + return scalar_binop (arg1, arg2, op); +} /* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ diff --git a/gdb/value.c b/gdb/value.c index d55240216b..b65ba32eb3 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2407,7 +2407,7 @@ coerce_array (struct value *arg) switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - if (current_language->c_style_arrays) + if (!TYPE_VECTOR (type) && current_language->c_style_arrays) arg = value_coerce_array (arg); break; case TYPE_CODE_FUNC: