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.
This commit is contained in:
Andrew Burgess 2013-01-25 17:16:43 +00:00
parent d79dcc73ac
commit 8954db33ac
10 changed files with 238 additions and 53 deletions

View file

@ -1,3 +1,21 @@
2013-01-25 Andrew Burgess <aburgess@broadcom.com>
Ulrich Weigand <uweigand@de.ibm.com>
* 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.
2013-01-25 Yao Qi <yao@codesourcery.com>
* event-loop.c: Include "queue.h".

View file

@ -683,6 +683,58 @@ vector_relop (struct expression *exp, struct value *val1, struct value *val2,
return ret;
}
/* Perform a cast of ARG into TYPE. There's sadly a lot of duplication in
here from valops.c:value_cast, opencl is different only in the
behaviour of scalar to vector casting. As far as possibly we're going
to try and delegate back to the standard value_cast function. */
static struct value *
opencl_value_cast (struct type *type, struct value *arg)
{
if (type != value_type (arg))
{
/* Casting scalar to vector is a special case for OpenCL, scalar
is cast to element type of vector then replicated into each
element of the vector. First though, we need to work out if
this is a scalar to vector cast; code lifted from
valops.c:value_cast. */
enum type_code code1, code2;
struct type *to_type;
int scalar;
to_type = check_typedef (type);
code1 = TYPE_CODE (to_type);
code2 = TYPE_CODE (check_typedef (value_type (arg)));
if (code2 == TYPE_CODE_REF)
code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
|| code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
|| code2 == TYPE_CODE_RANGE);
if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
{
struct type *eltype;
/* Cast to the element type of the vector here as
value_vector_widen will error if the scalar value is
truncated by the cast. To avoid the error, cast (and
possibly truncate) here. */
eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
arg = value_cast (eltype, arg);
return value_vector_widen (arg, type);
}
else
/* Standard cast handler. */
arg = value_cast (type, arg);
}
return arg;
}
/* Perform a relational operation on two operands. */
static struct value *
@ -718,7 +770,7 @@ opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t))
error (_("Argument to operation not a number or boolean."));
*v = value_cast (t1_is_vec ? type1 : type2, *v);
*v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
val = vector_relop (exp, arg1, arg2, op);
}
@ -740,6 +792,46 @@ evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
switch (op)
{
/* Handle assignment and cast operators to support OpenCL-style
scalar-to-vector widening. */
case BINOP_ASSIGN:
(*pos)++;
arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
type1 = value_type (arg1);
arg2 = evaluate_subexp (type1, exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
if (deprecated_value_modifiable (arg1)
&& VALUE_LVAL (arg1) != lval_internalvar)
arg2 = opencl_value_cast (type1, arg2);
return value_assign (arg1, arg2);
case UNOP_CAST:
type1 = exp->elts[*pos + 1].type;
(*pos) += 2;
arg1 = evaluate_subexp (type1, exp, pos, noside);
if (noside == EVAL_SKIP)
return value_from_longest (builtin_type (exp->gdbarch)->
builtin_int, 1);
return opencl_value_cast (type1, arg1);
case UNOP_CAST_TYPE:
(*pos)++;
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
type1 = value_type (arg1);
arg1 = evaluate_subexp (type1, exp, pos, noside);
if (noside == EVAL_SKIP)
return value_from_longest (builtin_type (exp->gdbarch)->
builtin_int, 1);
return opencl_value_cast (type1, arg1);
/* Handle binary relational and equality operators that are either not
or differently defined for GNU vectors. */
case BINOP_EQUAL:
@ -852,12 +944,12 @@ evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
/* Widen the scalar operand to a vector if necessary. */
if (t2_is_vec || !t3_is_vec)
{
arg3 = value_cast (type2, arg3);
arg3 = opencl_value_cast (type2, arg3);
type3 = value_type (arg3);
}
else if (!t2_is_vec || t3_is_vec)
{
arg2 = value_cast (type3, arg2);
arg2 = opencl_value_cast (type3, arg2);
type2 = value_type (arg2);
}
else if (!t2_is_vec || !t3_is_vec)

View file

@ -1,3 +1,12 @@
2013-01-25 Andrew Burgess <aburgess@broadcom.com>
* 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.
2013-01-24 Tiago Stürmer Daitx <tdaitx@linux.vnet.ibm.com>
* gdb.base/prologue-include.c: New file.

View file

@ -31,6 +31,7 @@ int ia = 2;
int ib = 1;
float fa = 2;
float fb = 1;
long long lla __attribute__ ((mode(DI))) = 0x0000000100000001ll;
char4 c4 = {1, 2, 3, 4};
int4 i4a = {2, 4, 8, 16};
int4 i4b = {1, 2, 8, 4};

View file

@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
# 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\\}"
# When casting to vector the input type must have the same length as
# the total length of the vector.
gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
gdb_test "print i4a << 1" "\\\$$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 >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
@ -130,6 +150,10 @@ gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different ty
gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
gdb_test "print (double2) f2" "Cannot convert between vector values of different sizes"
gdb_test "print (int4) c4" "Cannot convert between vector values of different sizes"
gdb_test "print (char4) i4a" "Cannot convert between vector values of different sizes"
# Test ptype on vector types.
gdb_test "ptype c4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
gdb_test "ptype char4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"

View file

@ -50,6 +50,9 @@ enum E
{ v1, v2, v3
};
struct s vec_data_1 = {1, 1};
struct s vec_data_2 = {1, 2};
int
main ()
{

View file

@ -118,7 +118,7 @@ proc test_fields {lang} {
# Test gdb.Type.array.
gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(1)))" \
".1, 2." "cast to array with one argument"
gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(0, 1)))" \
gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
".1, 2." "cast to array with two arguments"
gdb_test "python print (ar\[0\].type == ar\[0\].type)" "True"
@ -126,16 +126,19 @@ proc test_fields {lang} {
# Test gdb.Type.vector.
# Note: vectors cast differently than arrays. Here ar[0] is replicated
# for the size of the vector.
gdb_py_test_silent_cmd \
"python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
gdb_test "python print (vec1)" ".1, 1." "cast to vector with one argument"
gdb_py_test_silent_cmd \
"python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
gdb_test "python print (vec2)" ".1, 1." "cast to vector with two arguments"
gdb_test "python print (vec1 == vec2)" "True"
gdb_py_test_silent_cmd \
"python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
gdb_test "python print (vec1 == vec3)" "False"
gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
gdb_test "python print vec1 == vec2" "True"
gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
gdb_test "python print vec1 == vec3" "False"
}
}

View file

@ -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);
}

View file

@ -546,29 +546,13 @@ 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;
LONGEST low_bound, high_bound;
int i;
if (!get_array_bounds (type, &low_bound, &high_bound))
error (_("Could not determine the vector bounds"));
eltype = check_typedef (TYPE_TARGET_TYPE (type));
arg2 = value_cast (eltype, arg2);
val = allocate_value (type);
for (i = 0; i < high_bound - low_bound + 1; 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 (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
&& code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
&& TYPE_LENGTH (type) != TYPE_LENGTH (type2))
error (_("Cannot convert between vector values of different sizes"));
else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
&& TYPE_LENGTH (type) != TYPE_LENGTH (type2))
error (_("can only cast scalar to vector of same size"));
else if (code1 == TYPE_CODE_VOID)
{
return value_zero (type, not_lval);

View file

@ -482,6 +482,12 @@ extern void read_value_memory (struct value *val, int embedded_offset,
int stack, CORE_ADDR memaddr,
gdb_byte *buffer, size_t length);
/* Cast SCALAR_VALUE to the element type of VECTOR_TYPE, then replicate
into each element of a new vector value with VECTOR_TYPE. */
struct value *value_vector_widen (struct value *scalar_value,
struct type *vector_type);
#include "symtab.h"