X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fopencl-lang.c;h=dfb68c0fa8749eea90b2f94940f7597b2346d7c5;hb=173981bc49c9e8fce9271cb47714952dbe2ec627;hp=4ef469867cbc89195628a895f0de776841050290;hpb=ea5e6b0efed02c5f934df7420aa9fa55aa84b635;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c index 4ef469867c..dfb68c0fa8 100644 --- a/gdb/opencl-lang.c +++ b/gdb/opencl-lang.c @@ -1,5 +1,5 @@ /* OpenCL language support for GDB, the GNU debugger. - Copyright (C) 2010-2012 Free Software Foundation, Inc. + Copyright (C) 2010-2016 Free Software Foundation, Inc. Contributed by Ken Werner . @@ -19,15 +19,13 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_string.h" #include "gdbtypes.h" #include "symtab.h" #include "expression.h" #include "parser-defs.h" -#include "symtab.h" #include "language.h" +#include "varobj.h" #include "c-lang.h" -#include "gdb_assert.h" extern void _initialize_opencl_language (void); @@ -71,7 +69,7 @@ static struct gdbarch_data *opencl_type_data; static struct type ** builtin_opencl_type (struct gdbarch *gdbarch) { - return gdbarch_data (gdbarch, opencl_type_data); + return (struct type **) gdbarch_data (gdbarch, opencl_type_data); } /* Returns the corresponding OpenCL vector type from the given type code, @@ -156,11 +154,11 @@ struct lval_closure static struct lval_closure * allocate_lval_closure (int *indices, int n, struct value *val) { - struct lval_closure *c = XZALLOC (struct lval_closure); + struct lval_closure *c = XCNEW (struct lval_closure); c->refc = 1; c->n = n; - c->indices = XCALLOC (n, int); + c->indices = XCNEWVEC (int, n); memcpy (c->indices, indices, n * sizeof (int)); value_incref (val); /* Increment the reference counter of the value. */ c->val = val; @@ -240,58 +238,6 @@ lval_func_write (struct value *v, struct value *fromval) value_free_to_mark (mark); } -/* Return nonzero if all bits in V within OFFSET and LENGTH are valid. */ - -static int -lval_func_check_validity (const struct value *v, int offset, int length) -{ - struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); - /* Size of the target type in bits. */ - int elsize = - TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; - int startrest = offset % elsize; - int start = offset / elsize; - int endrest = (offset + length) % elsize; - int end = (offset + length) / elsize; - int i; - - if (endrest) - end++; - - if (end > c->n) - return 0; - - for (i = start; i < end; i++) - { - int comp_offset = (i == start) ? startrest : 0; - int comp_length = (i == end) ? endrest : elsize; - - if (!value_bits_valid (c->val, c->indices[i] * elsize + comp_offset, - comp_length)) - return 0; - } - - return 1; -} - -/* Return nonzero if any bit in V is valid. */ - -static int -lval_func_check_any_valid (const struct value *v) -{ - struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); - /* Size of the target type in bits. */ - int elsize = - TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; - int i; - - for (i = 0; i < c->n; i++) - if (value_bits_valid (c->val, c->indices[i] * elsize, elsize)) - return 1; - - return 0; -} - /* Return nonzero if bits in V from OFFSET and LENGTH represent a synthetic pointer. */ @@ -358,8 +304,6 @@ static const struct lval_funcs opencl_value_funcs = { lval_func_read, lval_func_write, - lval_func_check_validity, - lval_func_check_any_valid, NULL, /* indirect */ NULL, /* coerce_ref */ lval_func_check_synthetic_pointer, @@ -683,6 +627,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 +714,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 +736,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 +888,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) @@ -943,15 +979,13 @@ Cannot perform conditional operation on vectors with different sizes")); } else { + struct value *v = value_struct_elt (&arg1, NULL, + &exp->elts[pc + 2].string, NULL, + "structure"); + if (noside == EVAL_AVOID_SIDE_EFFECTS) - return - value_zero (lookup_struct_elt_type - (value_type (arg1),&exp->elts[pc + 2].string, 0), - lval_memory); - else - return value_struct_elt (&arg1, NULL, - &exp->elts[pc + 2].string, NULL, - "structure"); + v = value_zero (value_type (v), not_lval); + return v; } } default: @@ -973,7 +1007,7 @@ opencl_print_type (struct type *type, const char *varstring, be printed using their TYPE_NAME. */ if (show > 0) { - CHECK_TYPEDEF (type); + type = check_typedef (type); if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && TYPE_NAME (type) != NULL) show = 0; @@ -1012,6 +1046,7 @@ const struct exp_descriptor exp_descriptor_opencl = const struct language_defn opencl_language_defn = { "opencl", /* Language name */ + "OpenCL C", language_opencl, range_check_off, case_sensitive_on, @@ -1047,6 +1082,9 @@ const struct language_defn opencl_language_defn = c_get_string, NULL, /* la_get_symbol_name_cmp */ iterate_over_symbols, + &default_varobj_ops, + NULL, + NULL, LANG_MAGIC };