* [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