This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] GNU vector unop support


Hi,

This patch implements some unary operations for GNU vectors.
The following operators have been verified:
- pre/post increment (++)
- pre/post decrement (--)
- unary plus (+)
- unary minus (-)
- bitwise not/complement (~)

It also prevents GDB from returning a lvalue in case of post 
increment/decrement.
Tested on i686-*-linux-gnu, no regressions.

Regards
Ken Werner
ChangeLog:

2010-09-17  Ken Werner  <ken.werner@de.ibm.com>

	* eval.c (evaluate_subexp_standard) <UNOP_POSTINCREMENT,
	UNOP_POSTDECREMENT>: Copy arg1 to prevent returning a lvalue.
	* valarith.c (value_pos, value_neg, value_complement): Handle
	vector types.
	* valops.c (value_one): Likewise.

testsuite/ChangeLog:

2010-09-17  Ken Werner  <ken.werner@de.ibm.com>

	* gdb.base/gnu_vector.exp: Add unary operator tests.


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	16 Sep 2010 10:30:43 -0000
@@ -2739,7 +2739,14 @@ evaluate_subexp_standard (struct type *e
 	}
       else
 	{
-	  if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
+	  type = value_type (arg1);
+	  arg3 = allocate_value (type);
+
+	  /* Copy the value to prevent to return a lvalue.  */
+	  memcpy (value_contents_raw (arg3), value_contents (arg1),
+		 TYPE_LENGTH (type));
+
+	  if (ptrmath_type_p (exp->language_defn, type))
 	    arg2 = value_ptradd (arg1, 1);
 	  else
 	    {
@@ -2751,7 +2758,7 @@ evaluate_subexp_standard (struct type *e
 	    }
 
 	  value_assign (arg1, arg2);
-	  return arg1;
+	  return arg3;
 	}
 
     case UNOP_POSTDECREMENT:
@@ -2764,7 +2771,14 @@ evaluate_subexp_standard (struct type *e
 	}
       else
 	{
-	  if (ptrmath_type_p (exp->language_defn, value_type (arg1)))
+	  type = value_type (arg1);
+	  arg3 = allocate_value (type);
+
+	  /* Copy the value to prevent to return a lvalue.  */
+	  memcpy (value_contents_raw (arg3), value_contents (arg1),
+		 TYPE_LENGTH (type));
+
+	  if (ptrmath_type_p (exp->language_defn, type))
 	    arg2 = value_ptradd (arg1, -1);
 	  else
 	    {
@@ -2776,7 +2790,7 @@ evaluate_subexp_standard (struct type *e
 	    }
 
 	  value_assign (arg1, arg2);
-	  return arg1;
+	  return arg3;
 	}
 
     case OP_THIS:
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	16 Sep 2010 10:30:43 -0000
@@ -1673,39 +1673,58 @@ value_less (struct value *arg1, struct v
 struct value *
 value_pos (struct value *arg1)
 {
+  struct value *val;
   struct type *type;
 
   arg1 = coerce_ref (arg1);
   type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    return value_from_double (type, value_as_double (arg1));
-  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
-    return value_from_decfloat (type, value_contents (arg1));
-  else if (is_integral_type (type))
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
     {
-      return value_from_longest (type, value_as_long (arg1));
+      val = allocate_value (type);
+      memcpy (value_contents_raw (val), value_contents (arg1),
+	      TYPE_LENGTH (type));
     }
+  else if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    val = value_from_double (type, value_as_double (arg1));
+  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
+    val = value_from_decfloat (type, value_contents (arg1));
+  else if (is_integral_type (type))
+    val = value_from_longest (type, value_as_long (arg1));
   else
-    {
       error ("Argument to positive operation not a number.");
-      return 0;			/* For lint -- never reached */
-    }
+
+  return val;
 }
 
 struct value *
 value_neg (struct value *arg1)
 {
+  struct value *val;
   struct type *type;
 
   arg1 = coerce_ref (arg1);
   type = check_typedef (value_type (arg1));
 
-  if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+      int i, n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
+      struct value *tmp;
+
+      val = allocate_value (type);
+      for (i = 0; i < n; i++)
+	{
+	  tmp = value_neg (value_subscript (arg1, i));
+	  memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
+		  value_contents_all (tmp), TYPE_LENGTH (eltype));
+	}
+    }
+  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
     {
-      struct value *val = allocate_value (type);
       int len = TYPE_LENGTH (type);
       gdb_byte decbytes[16];  /* a decfloat is at most 128 bits long */
+      val = allocate_value (type);
 
       memcpy (decbytes, value_contents (arg1), len);
 
@@ -1715,33 +1734,53 @@ value_neg (struct value *arg1)
 	decbytes[0] = decbytes[0] | 0x80;
 
       memcpy (value_contents_raw (val), decbytes, len);
-      return val;
+
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    return value_from_double (type, -value_as_double (arg1));
+    val = value_from_double (type, -value_as_double (arg1));
   else if (is_integral_type (type))
-    {
-      return value_from_longest (type, -value_as_long (arg1));
-    }
+    val = value_from_longest (type, -value_as_long (arg1));
   else
-    {
-      error (_("Argument to negate operation not a number."));
-      return 0;			/* For lint -- never reached */
-    }
+    error (_("Argument to negate operation not a number."));
+
+  return val;
 }
 
 struct value *
 value_complement (struct value *arg1)
 {
   struct type *type;
+  struct value *val;
 
   arg1 = coerce_ref (arg1);
   type = check_typedef (value_type (arg1));
 
-  if (!is_integral_type (type))
-    error (_("Argument to complement operation not an integer or boolean."));
-
-  return value_from_longest (type, ~value_as_long (arg1));
+  if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type))
+    {
+      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type));
+      int i, n = TYPE_LENGTH (type) / TYPE_LENGTH (eltype);
+      struct value *tmp;
+
+      if (!is_integral_type (eltype))
+	error(_("\
+Argument to complement operation not an integer or boolean vector."));
+
+      val = allocate_value (type);
+      for (i = 0; i < n; i++)
+	{
+	  tmp = value_complement (value_subscript (arg1, i));
+	  memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
+		  value_contents_all (tmp), TYPE_LENGTH (eltype));
+	}
+    }
+  else
+    {
+      if (!is_integral_type (type))
+	error (_
+	       ("Argument to complement operation not an integer or boolean."));
+      val = value_from_longest (type, ~value_as_long (arg1));
+    }
+  return val;
 }
 
 /* The INDEX'th bit of SET value whose value_type is TYPE,
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	16 Sep 2010 10:30:43 -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)
@@ -833,7 +834,20 @@ value_one (struct type *type, enum lval_
   struct type *type1 = check_typedef (type);
   struct value *val;
 
-  if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
+  if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
+    {
+      struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type1));
+      int i, n = TYPE_LENGTH (type1) / TYPE_LENGTH (eltype);
+      struct value *tmp;
+      val = allocate_value (type);
+      for (i = 0; i < n; i++)
+	{
+	  tmp = value_one (eltype, lv);
+	  memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
+		  value_contents_all (tmp), TYPE_LENGTH (eltype));
+	}
+    }
+  else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
     {
       enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
       gdb_byte v[16];
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	16 Sep 2010 10:30:43 -0000
@@ -46,7 +46,7 @@ if { ![runto main] } {
     return -1
 }
 
-# Test binary operators on integer vector types
+# Test operators on integer vector types
 gdb_test "print i4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4b" "\\\$$decimal = \\{1, 2, 8, 4\\}"
 # Arithmetic operators
@@ -55,15 +55,23 @@ gdb_test "print i4a - i4b" "\\\$$decimal
 gdb_test "print i4a * i4b" "\\\$$decimal = \\{2, 8, 64, 64\\}"
 gdb_test "print i4a / i4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
 gdb_test "print i4a % i4b" "\\\$$decimal = \\{0, 0, 0, 0\\}"
+gdb_test "print i4a++" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print ++i4a" "\\\$$decimal = \\{4, 6, 10, 18\\}"
+gdb_test "print i4a--" "\\\$$decimal = \\{4, 6, 10, 18\\}"
+gdb_test "print --i4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print +i4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print -i4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
+
 # Bitwise operators
 gdb_test "print i4a & i4b" "\\\$$decimal = \\{0, 0, 8, 0\\}"
 gdb_test "print i4a | i4b" "\\\$$decimal = \\{3, 6, 8, 20\\}"
 gdb_test "print i4a ^ i4b" "\\\$$decimal = \\{3, 6, 0, 20\\}"
+gdb_test "print ~i4a" "\\\$$decimal = \\{-3, -5, -9, -17\\}"
 # Shift operators
 gdb_test "print i4a << i4b" "\\\$$decimal = \\{4, 16, 2048, 256\\}"
 gdb_test "print i4a >> i4b" "\\\$$decimal = \\{1, 1, 0, 1\\}"
 
-# Test binary operators on floating point vector types
+# Test operators on floating point vector types
 gdb_test "print f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print f4b" "\\\$$decimal = \\{1, 2, 8, 4\\}"
 # Arithmetic operators
@@ -71,6 +79,8 @@ gdb_test "print f4a + f4b" "\\\$$decimal
 gdb_test "print f4a - f4b" "\\\$$decimal = \\{1, 2, 0, 12\\}"
 gdb_test "print f4a * f4b" "\\\$$decimal = \\{2, 8, 64, 64\\}"
 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 error conditions
 gdb_test "print i4a + 1" "Vector operations are only supported among vectors"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]