gdb/ChangeLog:* gdb/valarith.c (vector_binop): New function.(scalar_binop): Likewise...
authorKen Werner <ken.werner@de.ibm.com>
Wed, 11 Aug 2010 16:48:26 +0000 (16:48 +0000)
committerKen Werner <ken.werner@de.ibm.com>
Wed, 11 Aug 2010 16:48:26 +0000 (16:48 +0000)
gdb/ChangeLog
gdb/eval.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/Makefile.in
gdb/testsuite/gdb.base/gnu_vector.c [new file with mode: 0644]
gdb/testsuite/gdb.base/gnu_vector.exp [new file with mode: 0644]
gdb/valarith.c
gdb/value.c

index 4d94b97..5098a78 100644 (file)
@@ -1,3 +1,13 @@
+2010-08-11  Ken Werner  <ken.werner@de.ibm.com>
+
+       * 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  <braddr@puremagic.com>
 
        * d-lang.c (extract_identifiers): Handle multiple digits.
index 2694781..635db34 100644 (file)
@@ -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;
index 778d13e..479e563 100644 (file)
@@ -1,3 +1,9 @@
+2010-08-11  Ken Werner  <ken.werner@de.ibm.com>
+
+       * 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  <pmuldoon@redhat.com>
 
        * gdb.python/python.c: New File.
index 5e8e385..57fc572 100644 (file)
@@ -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 (file)
index 0000000..8efb4cb
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+
+   Contributed by Ken Werner <ken.werner@de.ibm.com>  */
+
+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 (file)
index 0000000..b2f1dab
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.  */
+#
+# Contributed by Ken Werner <ken.werner@de.ibm.com>.
+#
+# 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"
+
index 0c40905..d75fdd2 100644 (file)
@@ -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);
+}
 \f
 /* Simulate the C operator ! -- return 1 if ARG1 contains zero.  */
 
index d552402..b65ba32 100644 (file)
@@ -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: