Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Ken Werner <ken@linux.vnet.ibm.com>
To: "Ulrich Weigand" <uweigand@de.ibm.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [patch] Scalar to vector widening
Date: Thu, 07 Oct 2010 20:41:00 -0000	[thread overview]
Message-ID: <201010072241.13455.ken@linux.vnet.ibm.com> (raw)
In-Reply-To: <201010051808.o95I87Xt013258@d12av02.megacenter.de.ibm.com>

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

  reply	other threads:[~2010-10-07 20:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-17 14:39 Ken Werner
2010-09-28 16:08 ` Ken Werner
2010-10-05 18:08 ` Ulrich Weigand
2010-10-07 20:41   ` Ken Werner [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201010072241.13455.ken@linux.vnet.ibm.com \
    --to=ken@linux.vnet.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=uweigand@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox