aboutsummaryrefslogtreecommitdiff
path: root/gdb/valarith.c
diff options
context:
space:
mode:
authorKen Werner <ken.werner@de.ibm.com>2010-08-11 16:48:26 +0000
committerKen Werner <ken.werner@de.ibm.com>2010-08-11 16:48:26 +0000
commit7346b668d73fe13b9b07b805379ff0e03d3aef5e (patch)
treeeb5fbe1c80b3888b5cff8410b6a7de90699b36f7 /gdb/valarith.c
parent3e4c12352587411b09071bd92002d481cebb8f1d (diff)
downloadgdb-7346b668d73fe13b9b07b805379ff0e03d3aef5e.zip
gdb-7346b668d73fe13b9b07b805379ff0e03d3aef5e.tar.gz
gdb-7346b668d73fe13b9b07b805379ff0e03d3aef5e.tar.bz2
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.
Diffstat (limited to 'gdb/valarith.c')
-rw-r--r--gdb/valarith.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 0c40905..d75fdd2 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. */