* [patch] Scalar to vector widening
@ 2010-09-17 14:39 Ken Werner
2010-09-28 16:08 ` Ken Werner
2010-10-05 18:08 ` Ulrich Weigand
0 siblings, 2 replies; 8+ messages in thread
From: Ken Werner @ 2010-09-17 14:39 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: Text/Plain, Size: 262 bytes --]
Hi,
This patch adds support for widening scalars to vectors to allow binary
operations with mixed operand types. It mainly extends the binop_promote
function to call widen_scalar_to_vector if required. No regressions on i686-*-
linux-gnu.
Regards
Ken Werner
[-- Attachment #2: widen-scalar-to-vector.patch --]
[-- Type: text/x-patch, Size: 9498 bytes --]
ChangeLog:
2010-09-17 Ken Werner <ken.werner@de.ibm.com>
* value.h (widen_scalar_to_vector): Declare.
* valops.c (widen_scalar_to_vector): New function.
(value_assign): Add call to widen_scalar_to_vector.
* eval.c (binop_promote, evaluate_subexp_standard)
<BINOP_ASSIGN_MODIFY, BINOP_LSH, BINOP_RSH>: Likewise.
testsuite/ChangeLog:
2010-09-17 Ken Werner <ken.werner@de.ibm.com>
* gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables.
* gdb.base/gnu_vector.exp: Add tests for scalar to vector widening.
Index: gdb/eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.139
diff -p -u -r1.139 eval.c
--- gdb/eval.c 11 Aug 2010 16:48:26 -0000 1.139
+++ gdb/eval.c 17 Sep 2010 10:56:28 -0000
@@ -574,6 +574,7 @@ binop_promote (const struct language_def
struct type *promoted_type = NULL;
struct type *type1;
struct type *type2;
+ int t1_is_vec, t2_is_vec;
*arg1 = coerce_ref (*arg1);
*arg2 = coerce_ref (*arg2);
@@ -581,15 +582,26 @@ binop_promote (const struct language_def
type1 = check_typedef (value_type (*arg1));
type2 = check_typedef (value_type (*arg2));
- if ((TYPE_CODE (type1) != TYPE_CODE_FLT
- && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT
- && !is_integral_type (type1))
- || (TYPE_CODE (type2) != TYPE_CODE_FLT
- && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT
- && !is_integral_type (type2)))
+ t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1));
+ t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2));
+
+ if (((TYPE_CODE (type1) != TYPE_CODE_FLT
+ && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT
+ && !is_integral_type (type1))
+ || (TYPE_CODE (type2) != TYPE_CODE_FLT
+ && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT
+ && !is_integral_type (type2)))
+ && t1_is_vec == t2_is_vec)
return;
- if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT
+ if (t1_is_vec != t2_is_vec)
+ {
+ /* Wide the scalar operand to vector. */
+ struct value **v = t1_is_vec ? arg2 : arg1;
+ struct type *t = t1_is_vec ? type1 : type2;
+ *v = widen_scalar_to_vector (t, *v);
+ }
+ else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT
|| TYPE_CODE (type2) == TYPE_CODE_DECFLOAT)
{
/* No promotion required. */
@@ -2035,8 +2047,13 @@ evaluate_subexp_standard (struct type *e
/* For shift and integer exponentiation operations,
only promote the first argument. */
- if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
- && is_integral_type (value_type (arg2)))
+ if (op == BINOP_LSH || op == BINOP_RSH)
+ {
+ arg2 = widen_scalar_to_vector (check_typedef (value_type (arg1)),
+ arg2);
+ unop_promote (exp->language_defn, exp->gdbarch, &tmp);
+ }
+ else if (op == BINOP_EXP && is_integral_type (value_type (arg2)))
unop_promote (exp->language_defn, exp->gdbarch, &tmp);
else
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
@@ -2130,8 +2147,14 @@ evaluate_subexp_standard (struct type *e
{
/* For shift and integer exponentiation operations,
only promote the first argument. */
- if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
- && is_integral_type (value_type (arg2)))
+ if (op == BINOP_LSH || op == BINOP_RSH)
+ {
+ arg2 =
+ widen_scalar_to_vector (check_typedef (value_type (arg1)),
+ arg2);
+ unop_promote (exp->language_defn, exp->gdbarch, &arg1);
+ }
+ else if (op == BINOP_EXP && is_integral_type (value_type (arg2)))
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
else
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.249
diff -p -u -r1.249 valops.c
--- gdb/valops.c 14 Jul 2010 14:54:58 -0000 1.249
+++ gdb/valops.c 17 Sep 2010 10:56:29 -0000
@@ -1079,7 +1079,15 @@ value_assign (struct value *toval, struc
type = value_type (toval);
if (VALUE_LVAL (toval) != lval_internalvar)
- fromval = value_cast (type, fromval);
+ {
+ struct type *fromtype = check_typedef (value_type (fromval));
+ struct type *totype = check_typedef (type);
+ if (!(TYPE_CODE (fromtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (fromtype))
+ && (TYPE_CODE (totype) == TYPE_CODE_ARRAY && TYPE_VECTOR (totype)))
+ fromval = widen_scalar_to_vector (type, fromval);
+ else
+ fromval = value_cast (type, fromval);
+ }
else
{
/* Coerce arrays and functions to pointers, except for arrays
@@ -3607,6 +3615,37 @@ cast_into_complex (struct type *type, st
error (_("cannot cast non-number to complex"));
}
+/* Widens the scalar val to a vector of type dst_type. */
+
+struct value *
+widen_scalar_to_vector (struct type *dst_type, struct value *val)
+{
+ struct type *val_type, *eltype;
+ struct value *ret;
+ int i, n;
+
+ val_type = check_typedef (value_type (val));
+
+ if ((TYPE_CODE (val_type) == TYPE_CODE_ARRAY && TYPE_VECTOR (val_type))
+ || !(TYPE_CODE (dst_type) == TYPE_CODE_ARRAY && TYPE_VECTOR (dst_type)))
+ return val;
+
+ eltype = check_typedef (TYPE_TARGET_TYPE (dst_type));
+ val = value_cast (eltype, val);
+
+ ret = allocate_value (dst_type);
+
+ n = TYPE_LENGTH (dst_type) / TYPE_LENGTH (eltype);
+ for (i = 0; i < n; i++)
+ {
+ /* Duplicate the contents of val into the destination vector. */
+ memcpy (value_contents_writeable (ret) + (i * TYPE_LENGTH (eltype)),
+ value_contents_all (val),
+ TYPE_LENGTH (eltype));
+ }
+ return ret;
+}
+
void
_initialize_valops (void)
{
Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.161
diff -p -u -r1.161 value.h
--- gdb/value.h 7 Jul 2010 16:15:18 -0000 1.161
+++ gdb/value.h 17 Sep 2010 10:56:29 -0000
@@ -721,6 +721,9 @@ extern struct value *value_slice (struct
extern struct value *value_literal_complex (struct value *, struct value *,
struct type *);
+extern struct value *widen_scalar_to_vector (struct type *dst_type,
+ struct value *val);
+
extern struct value *find_function_in_inferior (const char *,
struct objfile **);
Index: gdb/testsuite/gdb.base/gnu_vector.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v
retrieving revision 1.1
diff -p -u -r1.1 gnu_vector.c
--- gdb/testsuite/gdb.base/gnu_vector.c 11 Aug 2010 16:48:26 -0000 1.1
+++ gdb/testsuite/gdb.base/gnu_vector.c 17 Sep 2010 10:56:29 -0000
@@ -17,10 +17,16 @@
Contributed by Ken Werner <ken.werner@de.ibm.com> */
+int ia = 2;
+int ib = 1;
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 fa = 2;
+float fb = 1;
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};
Index: gdb/testsuite/gdb.base/gnu_vector.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v
retrieving revision 1.1
diff -p -u -r1.1 gnu_vector.exp
--- gdb/testsuite/gdb.base/gnu_vector.exp 11 Aug 2010 16:48:26 -0000 1.1
+++ gdb/testsuite/gdb.base/gnu_vector.exp 17 Sep 2010 10:56:29 -0000
@@ -72,9 +72,28 @@ gdb_test "print f4a - f4b" "\\\$$decimal
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"
+# Test scalar to vector widening
+gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
+
+gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print i4a << ib" "\\\$$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 = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+
+# Test some error scenarios
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"
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [patch] Scalar to vector widening 2010-09-17 14:39 [patch] Scalar to vector widening Ken Werner @ 2010-09-28 16:08 ` Ken Werner 2010-10-05 18:08 ` Ulrich Weigand 1 sibling, 0 replies; 8+ messages in thread From: Ken Werner @ 2010-09-28 16:08 UTC (permalink / raw) To: gdb-patches On Friday, September 17, 2010 2:58:29 pm Ken Werner wrote: > This patch adds support for widening scalars to vectors to allow binary > operations with mixed operand types. It mainly extends the binop_promote > function to call widen_scalar_to_vector if required. No regressions on > i686-*- linux-gnu. Ping. -ken ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-09-17 14:39 [patch] Scalar to vector widening Ken Werner 2010-09-28 16:08 ` Ken Werner @ 2010-10-05 18:08 ` Ulrich Weigand 2010-10-07 20:41 ` Ken Werner 1 sibling, 1 reply; 8+ messages in thread From: Ulrich Weigand @ 2010-10-05 18:08 UTC (permalink / raw) To: Ken Werner; +Cc: gdb-patches Ken Werner wrote: > This patch adds support for widening scalars to vectors to allow binary > operations with mixed operand types. It mainly extends the binop_promote > function to call widen_scalar_to_vector if required. No regressions on i686-*- > linux-gnu. > * value.h (widen_scalar_to_vector): Declare. > * valops.c (widen_scalar_to_vector): New function. > (value_assign): Add call to widen_scalar_to_vector. > * eval.c (binop_promote, evaluate_subexp_standard) > <BINOP_ASSIGN_MODIFY, BINOP_LSH, BINOP_RSH>: Likewise. I've been thinking about this a bit. One piece that's missing here is support for explicit casts. For OpenCL vectors (and that seems like a useful extension in general), you can use an explicit type cast operation to widen a scalar value to a vector, e.g. like float f = 1.0f; float4 v = (float4) f; I think it would be better to change your patch to perform the operation you're doing in the new widen_scalar_to_vector routine simply in value_cast instead (if the source is a scalar and the target type a vector type). This would support the above-mentioned OpenCL language feature, and it would also simplify implict widening for operators. Note that e.g. both binop_promote and value_assign already call value_cast in their regular operation; it's just a matter of using the appropriate target type ... Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-10-05 18:08 ` Ulrich Weigand @ 2010-10-07 20:41 ` Ken Werner 2010-10-08 13:14 ` Ulrich Weigand 0 siblings, 1 reply; 8+ messages in thread From: Ken Werner @ 2010-10-07 20:41 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches [-- Attachment #1: Type: Text/Plain, Size: 504 bytes --] On Tuesday, October 05, 2010 8:08:07 pm Ulrich Weigand wrote: > I think it would be better to change your patch to perform the > operation you're doing in the new widen_scalar_to_vector routine > simply in value_cast instead (if the source is a scalar and the > target type a vector type). This is a bright idea! The attached patch enhances value_cast to be able widen scalars to vectors as suggested. Tested on i686-*-linux-gnu with no regressions. Any comments are appreciated as usual. Thanks Ken [-- Attachment #2: widen-scalar-to-vector.patch --] [-- Type: text/x-patch, Size: 7612 bytes --] ChangeLog: 2010-10-07 Ken Werner <ken.werner@de.ibm.com> * valops.c (value_cast): Handle vector types. * eval.c (binop_promote): Likewise. (evaluate_subexp_standard) <BINOP_ASSIGN_MODIFY, BINOP_LSH, BINOP_RSH>: Call value_cast to widen scalars to vectors. testsuite/ChangeLog: 2010-10-07 Ken Werner <ken.werner@de.ibm.com> * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. Index: gdb/eval.c =================================================================== RCS file: /cvs/src/src/gdb/eval.c,v retrieving revision 1.139 diff -p -u -r1.139 eval.c --- gdb/eval.c 11 Aug 2010 16:48:26 -0000 1.139 +++ gdb/eval.c 7 Oct 2010 20:16:53 -0000 @@ -574,6 +574,7 @@ binop_promote (const struct language_def struct type *promoted_type = NULL; struct type *type1; struct type *type2; + int t1_is_vec, t2_is_vec; *arg1 = coerce_ref (*arg1); *arg2 = coerce_ref (*arg2); @@ -581,15 +582,21 @@ binop_promote (const struct language_def type1 = check_typedef (value_type (*arg1)); type2 = check_typedef (value_type (*arg2)); - if ((TYPE_CODE (type1) != TYPE_CODE_FLT + t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1)); + t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)); + + if (((TYPE_CODE (type1) != TYPE_CODE_FLT && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT && !is_integral_type (type1)) || (TYPE_CODE (type2) != TYPE_CODE_FLT && TYPE_CODE (type2) != TYPE_CODE_DECFLOAT && !is_integral_type (type2))) + && t1_is_vec == t2_is_vec) return; - if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT + if (t1_is_vec != t2_is_vec) + promoted_type = t1_is_vec ? type1 : type2; + else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT || TYPE_CODE (type2) == TYPE_CODE_DECFLOAT) { /* No promotion required. */ @@ -2035,8 +2042,12 @@ evaluate_subexp_standard (struct type *e /* For shift and integer exponentiation operations, only promote the first argument. */ - if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP) - && is_integral_type (value_type (arg2))) + if (op == BINOP_LSH || op == BINOP_RSH) + { + arg2 = value_cast (check_typedef (value_type (arg1)), arg2); + unop_promote (exp->language_defn, exp->gdbarch, &tmp); + } + else if (op == BINOP_EXP && is_integral_type (value_type (arg2))) unop_promote (exp->language_defn, exp->gdbarch, &tmp); else binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2); @@ -2130,9 +2141,13 @@ evaluate_subexp_standard (struct type *e { /* For shift and integer exponentiation operations, only promote the first argument. */ - if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP) - && is_integral_type (value_type (arg2))) + if (op == BINOP_LSH || op == BINOP_RSH) + { + arg2 = value_cast (check_typedef (value_type (arg1)), arg2); unop_promote (exp->language_defn, exp->gdbarch, &arg1); + } + else if (op == BINOP_EXP && is_integral_type (value_type (arg2))) + unop_promote (exp->language_defn, exp->gdbarch, &arg1); else binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.251 diff -p -u -r1.251 valops.c --- gdb/valops.c 24 Sep 2010 14:47:53 -0000 1.251 +++ gdb/valops.c 7 Oct 2010 20:16:53 -0000 @@ -421,7 +421,8 @@ value_cast (struct type *type, struct va } if (current_language->c_style_arrays - && TYPE_CODE (type2) == TYPE_CODE_ARRAY) + && TYPE_CODE (type2) == TYPE_CODE_ARRAY + && !TYPE_VECTOR (type2)) arg2 = value_coerce_array (arg2); if (TYPE_CODE (type2) == TYPE_CODE_FUNC) @@ -537,6 +538,26 @@ value_cast (struct type *type, struct va 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; + int i, n; + + eltype = check_typedef (TYPE_TARGET_TYPE (type)); + arg2 = value_cast (eltype, arg2); + val = allocate_value (type); + n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype); + + for (i = 0; i < n; 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 (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) Index: gdb/testsuite/gdb.base/gnu_vector.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.c --- gdb/testsuite/gdb.base/gnu_vector.c 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.c 7 Oct 2010 20:16:53 -0000 @@ -17,6 +17,10 @@ Contributed by Ken Werner <ken.werner@de.ibm.com> */ +int ia = 2; +int ib = 1; +float fa = 2; +float fb = 1; char __attribute__ ((vector_size (4 * sizeof(char)))) c4 = {1, 2, 3, 4}; int __attribute__ ((vector_size (4 * sizeof(int)))) i4a = {2, 4, 8, 16}; int __attribute__ ((vector_size (4 * sizeof(int)))) i4b = {1, 2, 8, 4}; Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.exp 7 Oct 2010 20:16:53 -0000 @@ -76,9 +76,28 @@ gdb_test "print f4a - f4b" "\\\$$decimal 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" +# Test scalar to vector widening +gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}" +gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}" +gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}" + +gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}" +gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}" +gdb_test "print i4a << ib" "\\\$$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 = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" + +# Test some error scenarios 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" ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-10-07 20:41 ` Ken Werner @ 2010-10-08 13:14 ` Ulrich Weigand 2010-10-08 16:37 ` Ken Werner 0 siblings, 1 reply; 8+ messages in thread From: Ulrich Weigand @ 2010-10-08 13:14 UTC (permalink / raw) To: Ken Werner; +Cc: gdb-patches Ken Werner wrote: > @@ -2035,8 +2042,12 @@ evaluate_subexp_standard (struct type *e > > /* For shift and integer exponentiation operations, > only promote the first argument. */ > - if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP) > - && is_integral_type (value_type (arg2))) > + if (op == BINOP_LSH || op == BINOP_RSH) > + { > + arg2 = value_cast (check_typedef (value_type (arg1)), arg2); > + unop_promote (exp->language_defn, exp->gdbarch, &tmp); > + } I don't think these are quite right. If, say, arg2 is a vector of different type, this may get simply cast away. Likewise, if arg1 is a very short integer type, the cast may actually remove valid bits in arg2 ... I think the cast really should only be done if one side is a vector and the other a scalar. However, I don't quite like distributing the code between the various promotion routines. In fact, I'm starting to think this shouldn't actually be though of as a promotion at all. Instead, why not simply handle the case directly in vector_binop? If only one side is a vector and the other is a scalar, cast it there. This should simplify the patch even further. [ Note that value_binop already today performs type conversions (e.g. from integer to float). We only split off those performed by the GDB logic (value_binop) itself from those performed by language- specific promotion rules where the latter are ambiguous of change between languages. If value_binop gets called with a pair of a vector and a scalar, it ought to do *something* anyway, so we might as well decide the straight-forward widening is what happens. ] > +# Test scalar to vector widening > +gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" > +gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}" > +gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}" > +gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}" > +gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}" > + > +gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}" > +gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" > +gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}" > +gdb_test "print i4a << ib" "\\\$$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 = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}" > +gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" Since we've now added support for casts, maybe a couple of tests for that capability would also be helpful. Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-10-08 13:14 ` Ulrich Weigand @ 2010-10-08 16:37 ` Ken Werner 2010-10-08 16:44 ` Ulrich Weigand 0 siblings, 1 reply; 8+ messages in thread From: Ken Werner @ 2010-10-08 16:37 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches [-- Attachment #1: Type: Text/Plain, Size: 905 bytes --] On Friday, October 08, 2010 3:14:41 pm Ulrich Weigand wrote: > I don't think these are quite right. If, say, arg2 is a vector of > different type, this may get simply cast away. Likewise, if arg1 > is a very short integer type, the cast may actually remove valid > bits in arg2 ... I think the cast really should only be done if > one side is a vector and the other a scalar. Oh, I overlooked that - thanks. > However, I don't quite like distributing the code between the various > promotion routines. In fact, I'm starting to think this shouldn't > actually be though of as a promotion at all. Instead, why not simply > handle the case directly in vector_binop? If only one side is a vector > and the other is a scalar, cast it there. This should simplify the > patch even further. Sounds good. Attached is a new version of the patch. Tested on i686-*-linux- gnu, no regressions. Regards Ken [-- Attachment #2: widen-scalar-to-vector.patch --] [-- Type: text/x-patch, Size: 8293 bytes --] ChangeLog: 2010-10-08 Ken Werner <ken.werner@de.ibm.com> * valops.c (value_cast): Handle vector types. * valarith.c (value_binop): Widen scalar to vector if appropriate. testsuite/ChangeLog: 2010-10-08 Ken Werner <ken.werner@de.ibm.com> * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. Index: gdb/valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.86 diff -p -u -r1.86 valarith.c --- gdb/valarith.c 11 Aug 2010 16:48:26 -0000 1.86 +++ gdb/valarith.c 8 Oct 2010 16:22:00 -0000 @@ -1435,14 +1435,34 @@ vector_binop (struct value *val1, struct struct value * value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) { + struct value *val; 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); + int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type1)); + int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY + && TYPE_VECTOR (type2)); + + if (!t1_is_vec && !t2_is_vec) + val = scalar_binop (arg1, arg2, op); + else if (t1_is_vec && t2_is_vec) + val = vector_binop (arg1, arg2, op); else - return scalar_binop (arg1, arg2, op); + { + /* Widen the scalar operand to a vector. */ + struct value **v = t1_is_vec ? &arg2 : &arg1; + struct type *t = t1_is_vec ? type2 : type1; + + if (TYPE_CODE (t) != TYPE_CODE_FLT + && TYPE_CODE (t) != TYPE_CODE_DECFLOAT + && !is_integral_type (t)) + error (_("Argument to operation not a number or boolean.")); + + *v = value_cast (t1_is_vec ? type1 : type2, *v); + val = vector_binop (arg1, arg2, op); + } + + return val; } \f /* Simulate the C operator ! -- return 1 if ARG1 contains zero. */ Index: gdb/valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.251 diff -p -u -r1.251 valops.c --- gdb/valops.c 24 Sep 2010 14:47:53 -0000 1.251 +++ gdb/valops.c 8 Oct 2010 16:22:01 -0000 @@ -421,7 +421,8 @@ value_cast (struct type *type, struct va } if (current_language->c_style_arrays - && TYPE_CODE (type2) == TYPE_CODE_ARRAY) + && TYPE_CODE (type2) == TYPE_CODE_ARRAY + && !TYPE_VECTOR (type2)) arg2 = value_coerce_array (arg2); if (TYPE_CODE (type2) == TYPE_CODE_FUNC) @@ -537,6 +538,26 @@ value_cast (struct type *type, struct va 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; + int i, n; + + eltype = check_typedef (TYPE_TARGET_TYPE (type)); + arg2 = value_cast (eltype, arg2); + val = allocate_value (type); + n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype); + + for (i = 0; i < n; 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 (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) Index: gdb/testsuite/gdb.base/gnu_vector.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.c --- gdb/testsuite/gdb.base/gnu_vector.c 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.c 8 Oct 2010 16:22:01 -0000 @@ -17,16 +17,30 @@ Contributed by Ken Werner <ken.werner@de.ibm.com> */ -char __attribute__ ((vector_size (4 * sizeof(char)))) c4 = {1, 2, 3, 4}; -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}; +typedef int __attribute__ ((vector_size (4 * sizeof(int)))) int4; +typedef unsigned int __attribute__ ((vector_size (4 * sizeof(unsigned int)))) uint4; +typedef char __attribute__ ((vector_size (4 * sizeof(char)))) char4; +typedef float __attribute__ ((vector_size (4 * sizeof(float)))) float4; + +typedef int __attribute__ ((vector_size (2 * sizeof(int)))) int2; +typedef long long __attribute__ ((vector_size (2 * sizeof(long long)))) longlong2; +typedef float __attribute__ ((vector_size (2 * sizeof(float)))) float2; +typedef double __attribute__ ((vector_size (2 * sizeof(double)))) double2; + +int ia = 2; +int ib = 1; +float fa = 2; +float fb = 1; +char4 c4 = {1, 2, 3, 4}; +int4 i4a = {2, 4, 8, 16}; +int4 i4b = {1, 2, 8, 4}; +float4 f4a = {2, 4, 8, 16}; +float4 f4b = {1, 2, 8, 4}; +uint4 ui4 = {2, 4, 8, 16}; +int2 i2 = {1, 2}; +longlong2 ll2 = {1, 2}; +float2 f2 = {1, 2}; +double2 d2 = {1, 2}; int main () Index: gdb/testsuite/gdb.base/gnu_vector.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v retrieving revision 1.2 diff -p -u -r1.2 gnu_vector.exp --- gdb/testsuite/gdb.base/gnu_vector.exp 6 Oct 2010 08:44:15 -0000 1.2 +++ gdb/testsuite/gdb.base/gnu_vector.exp 8 Oct 2010 16:22:01 -0000 @@ -76,9 +76,37 @@ gdb_test "print f4a - f4b" "\\\$$decimal 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" +# 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\\}" + +gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}" +gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}" +gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}" + +gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}" +gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}" +gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}" +gdb_test "print i4a << ib" "\\\$$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 = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}" +gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}" + +# Test some error scenarios 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" ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-10-08 16:37 ` Ken Werner @ 2010-10-08 16:44 ` Ulrich Weigand 2010-10-08 16:52 ` Ken Werner 0 siblings, 1 reply; 8+ messages in thread From: Ulrich Weigand @ 2010-10-08 16:44 UTC (permalink / raw) To: Ken Werner; +Cc: gdb-patches Ken Werner wrote: > ChangeLog: > > 2010-10-08 Ken Werner <ken.werner@de.ibm.com> > > * valops.c (value_cast): Handle vector types. > * valarith.c (value_binop): Widen scalar to vector if appropriate. > > testsuite/ChangeLog: > > 2010-10-08 Ken Werner <ken.werner@de.ibm.com> > > * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. > * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. This version is OK. Thanks, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] Scalar to vector widening 2010-10-08 16:44 ` Ulrich Weigand @ 2010-10-08 16:52 ` Ken Werner 0 siblings, 0 replies; 8+ messages in thread From: Ken Werner @ 2010-10-08 16:52 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Friday, October 08, 2010 6:43:41 pm Ulrich Weigand wrote: > Ken Werner wrote: > > ChangeLog: > > > > 2010-10-08 Ken Werner <ken.werner@de.ibm.com> > > > > * valops.c (value_cast): Handle vector types. > > * valarith.c (value_binop): Widen scalar to vector if appropriate. > > > > testsuite/ChangeLog: > > > > 2010-10-08 Ken Werner <ken.werner@de.ibm.com> > > > > * gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables. > > * gdb.base/gnu_vector.exp: Add tests for scalar to vector widening. > > This version is OK. Patch applied: http://sourceware.org/ml/gdb-cvs/2010-10/msg00055.html Thanks Ken ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-10-08 16:52 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-09-17 14:39 [patch] Scalar to vector widening Ken Werner 2010-09-28 16:08 ` Ken Werner 2010-10-05 18:08 ` Ulrich Weigand 2010-10-07 20:41 ` Ken Werner 2010-10-08 13:14 ` Ulrich Weigand 2010-10-08 16:37 ` Ken Werner 2010-10-08 16:44 ` Ulrich Weigand 2010-10-08 16:52 ` Ken Werner
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox