summaryrefslogtreecommitdiff
path: root/gdb/valarith.c
diff options
context:
space:
mode:
authoraburgess <aburgess>2013-01-25 17:16:32 +0000
committeraburgess <aburgess>2013-01-25 17:16:32 +0000
commitfebdbbf9cb02f4f696e889874d43fea5d4006c2e (patch)
treef36ea99f3d67992b6082c45140684a65347da6f8 /gdb/valarith.c
parentfb5e48c5990d7d6ef7e9921a075df50ad21950a5 (diff)
downloadgdb-febdbbf9cb02f4f696e889874d43fea5d4006c2e.tar.gz
http://sourceware.org/ml/gdb-patches/2012-11/msg00312.html
gdb/ChangeLog * valarith.c (value_vector_widen): New function for replicating a scalar into a vector. (value_binop): Use value_vector_widen to widen scalar to vector rather than casting, this better matches gcc C behaviour. * valops.c (value_casst): Update logic for casting between vector types, and for casting from scalar to vector, try to match gcc C behaviour. * value.h (value_vector_widen): Declare. * opencl-lang.c (opencl_value_cast): New opencl specific casting function, handle special case for casting scalar to vector. (opencl_relop): Use opencl_value_cast. (evaluate_subexp_opencl): Use opencl_value_cast instead of value_cast, and handle BINOP_ASSIGN, UNOP_CAST, and UNOP_CAST_TYPE in order to use opencl_value_cast. gdb/testsuite/ChangeLog * gdb.base/gnu_vector.c: New variable for use in tests. * gdb.base/gnu_vector.exp: Update and extend tests to reflect changes in scalar to vector casting and widening. * gdb.python/py-type.c: New variables for use in tests. * gdb.python/py-type.exp: Update vector related tests to reflect changes in scalar to vector casting and widening.
Diffstat (limited to 'gdb/valarith.c')
-rw-r--r--gdb/valarith.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 074cf36fba3..894a87ac048 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1346,6 +1346,49 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
return val;
}
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+ replicating SCALAR_VALUE for each element of the vector. Only scalar
+ types that can be cast to the type of one element of the vector are
+ acceptable. The newly created vector value is returned upon success,
+ otherwise an error is thrown. */
+
+struct value *
+value_vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+ /* Widen the scalar to a vector. */
+ struct type *eltype, *scalar_type;
+ struct value *val, *elval;
+ LONGEST low_bound, high_bound;
+ int i;
+
+ CHECK_TYPEDEF (vector_type);
+
+ gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
+ && TYPE_VECTOR (vector_type));
+
+ if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+ error (_("Could not determine the vector bounds"));
+
+ eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+ elval = value_cast (eltype, scalar_value);
+
+ scalar_type = check_typedef (value_type (scalar_value));
+
+ /* If we reduced the length of the scalar then check we didn't loose any
+ important bits. */
+ if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+ && !value_equal (elval, scalar_value))
+ error (_("conversion of scalar to vector involves truncation"));
+
+ val = allocate_value (vector_type);
+ for (i = 0; i < high_bound - low_bound + 1; i++)
+ /* Duplicate the contents of elval into the destination vector. */
+ memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+ value_contents_all (elval), TYPE_LENGTH (eltype));
+
+ return val;
+}
+
/* Performs a binary operation on two vector operands by calling scalar_binop
for each pair of vector components. */
@@ -1425,7 +1468,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
&& !is_integral_type (t))
error (_("Argument to operation not a number or boolean."));
- *v = value_cast (t1_is_vec ? type1 : type2, *v);
+ /* Replicate the scalar value to make a vector value. */
+ *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);
+
val = vector_binop (arg1, arg2, op);
}