public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC] LONGEST and ULONGEST function template instantiation
@ 2017-06-13 11:29 Yao Qi
  2017-06-13 11:33 ` Yao Qi
  2017-06-14 16:12 ` Pedro Alves
  0 siblings, 2 replies; 7+ messages in thread
From: Yao Qi @ 2017-06-13 11:29 UTC (permalink / raw)
  To: gdb-patches

This patch converts functions extract_{unsigned,signed}_integer
to a function template extract_integer, which has two instantiations.  It
also does the similar changes to store__{unsigned,signed}_integer,
regcache::raw_read_{unsigned,signed}, regcache::raw_write_{unsigned,signed},
regcache::cooked_read_{unsigned,signed},
regcache::cooked_write_{unsigned,signed}.  It is an RFC, because I
am not sure people like it or hate it :)

This patch was posted here
https://sourceware.org/ml/gdb-patches/2017-05/msg00492.html but the
problem was fixed in a different way.  However, I think the patch is still
useful to shorten the code.

The patch increase the binary code size (measured on x86_64-linux), from

$ size ./gdb
   text    data     bss     dec     hex filename
23856767        2395936  364616 26617319        19625e7 ./gdb

to

$ size ./gdb
   text    data     bss     dec     hex filename
23858667        2395936  364616 26619219        1962d53 ./gdb

The patch is tested on x86_64-linux.

gdb:

2017-06-13  Alan Hayward  <alan.hayward@arm.com>
	    Yao Qi  <yao.qi@linaro.org>

	* defs.h (LongType): New alias.
	(extract_signed_integer): Remove declaration.
	(extract_unsigned_integer): Likewise.
	(extract_integer): New function template.
	(extract_unsigned_integer): New macro.
	(extract_signed_integer): New macro.
	(store_integer): New function template.
	(store_signed_integer): New macro.
	(store_unsigned_integer): New macro.
	* findvar.c (extract_signed_integer): Remove.
	(extract_unsigned_integer): Remove.
	(store_signed_integer): Remove.
	(store_unsigned_integer): Remove.
	* regcache.c (regcache_raw_read_signed): Update.
	(regcache::raw_read_signed): Remove.
	(regcache::raw_read): New function.
	(regcache::raw_read_unsigned): Remove.
	(regcache_raw_read_unsigned): Update.
	(regcache_raw_write_unsigned): Update.
	(regcache::raw_write_signed): Remove.
	(regcache::raw_write): New function.
	(regcache_cooked_read_signed): Update.
	(regcache::raw_write_unsigned): Remove.
	(regcache::cooked_read_signed): Remove.
	(regcache_cooked_read_unsigned): Update.
	(regcache::cooked_read_unsigned): Remove.
	(regcache_cooked_write_signed): Update.
	(regcache_cooked_write_unsigned): Update.
	* regcache.h (regcache) <raw_read_signed>: Remove.
	<raw_write_signed, raw_read_unsigned, raw_write_unsigned>: Remove.
	<raw_read, raw_write>: New.
	<cooked_read_signed, cooked_write_signed>: Remove.
	<cooked_write_unsigned, cooked_read_unsigned>: Remove.
	<cooked_read, cooked_write>: New.
	* sh64-tdep.c (sh64_pseudo_register_read): Update.
	(sh64_pseudo_register_write): Update.
---
 gdb/defs.h      | 108 +++++++++++++++++++++++++++++++++++++++++++----
 gdb/findvar.c   | 127 +-------------------------------------------------------
 gdb/regcache.c  | 124 +++++++++++++++++-------------------------------------
 gdb/regcache.h  |  36 +++++++++-------
 gdb/sh64-tdep.c |  12 +++---
 5 files changed, 166 insertions(+), 241 deletions(-)

diff --git a/gdb/defs.h b/gdb/defs.h
index a1a97bb..5ef94f5 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -627,6 +627,11 @@ enum symbol_needs_kind
   SYMBOL_NEEDS_FRAME
 };
 
+template<typename T>
+using LongType = typename std::enable_if<(std::is_same<T, LONGEST>::value
+					  || std::is_same<T, ULONGEST>::value),
+					 T>::type;
+
 /* Dynamic target-system-dependent parameters for GDB.  */
 #include "gdbarch.h"
 
@@ -637,11 +642,61 @@ enum { MAX_REGISTER_SIZE = 64 };
 
 /* In findvar.c.  */
 
-extern LONGEST extract_signed_integer (const gdb_byte *, int,
-				       enum bfd_endian);
+/* All 'extract' functions return a host-format integer from a target-format
+   integer at ADDR which is LEN bytes long.  */
 
-extern ULONGEST extract_unsigned_integer (const gdb_byte *, int,
-					  enum bfd_endian);
+template<typename T>
+LongType<T>
+extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order)
+{
+  T retval = 0;
+  const unsigned char *p;
+  const unsigned char *startaddr = addr;
+  const unsigned char *endaddr = startaddr + len;
+
+  if (len > (int) sizeof (T))
+    error (_("\
+That operation is not available on integers of more than %d bytes."),
+	   (int) sizeof (T));
+
+  /* Start at the most significant end of the integer, and work towards
+     the least significant.  */
+  if (byte_order == BFD_ENDIAN_BIG)
+    {
+      p = startaddr;
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  ++p;
+	}
+      for (; p < endaddr; ++p)
+	retval = (retval << 8) | *p;
+    }
+  else
+    {
+      p = endaddr - 1;
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  --p;
+	}
+      for (; p >= startaddr; --p)
+	retval = (retval << 8) | *p;
+    }
+  return retval;
+}
+
+template ULONGEST extract_integer<ULONGEST>
+  (const gdb_byte *addr, int len, enum bfd_endian byte_order);
+
+template LONGEST extract_integer<LONGEST>
+  (const gdb_byte *addr, int len, enum bfd_endian byte_order);
+
+#define extract_unsigned_integer extract_integer<ULONGEST>
+
+#define extract_signed_integer extract_integer<LONGEST>
 
 extern int extract_long_unsigned_integer (const gdb_byte *, int,
 					  enum bfd_endian, LONGEST *);
@@ -649,11 +704,48 @@ extern int extract_long_unsigned_integer (const gdb_byte *, int,
 extern CORE_ADDR extract_typed_address (const gdb_byte *buf,
 					struct type *type);
 
-extern void store_signed_integer (gdb_byte *, int,
-				  enum bfd_endian, LONGEST);
+/* All 'store' functions accept a host-format integer and store a
+   target-format integer at ADDR which is LEN bytes long.  */
 
-extern void store_unsigned_integer (gdb_byte *, int,
-				    enum bfd_endian, ULONGEST);
+template<typename T>
+typename std::enable_if<(std::is_same<T, LONGEST>::value
+			 || std::is_same<T, ULONGEST>::value),
+			void>::type
+store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order,
+	       T val)
+{
+  gdb_byte *p;
+  gdb_byte *startaddr = addr;
+  gdb_byte *endaddr = startaddr + len;
+
+  /* Start at the least significant end of the integer, and work towards
+     the most significant.  */
+  if (byte_order == BFD_ENDIAN_BIG)
+    {
+      for (p = endaddr - 1; p >= startaddr; --p)
+	{
+	  *p = val & 0xff;
+	  val >>= 8;
+	}
+    }
+  else
+    {
+      for (p = startaddr; p < endaddr; ++p)
+	{
+	  *p = val & 0xff;
+	  val >>= 8;
+	}
+    }
+}
+
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order, ULONGEST val);
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order, LONGEST val);
+
+#define store_signed_integer store_integer<LONGEST>
+
+#define store_unsigned_integer store_integer<ULONGEST>
 
 extern void store_typed_address (gdb_byte *buf, struct type *type,
 				 CORE_ADDR addr);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 6c18e25..4caf125 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -35,9 +35,7 @@
 #include "dwarf2loc.h"
 #include "selftest.h"
 
-/* Basic byte-swapping routines.  All 'extract' functions return a
-   host-format integer from a target-format integer at ADDR which is
-   LEN bytes long.  */
+/* Basic byte-swapping routines.  */
 
 #if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
   /* 8 bit characters are a pretty safe assumption these days, so we
@@ -47,70 +45,6 @@
 you lose
 #endif
 
-LONGEST
-extract_signed_integer (const gdb_byte *addr, int len,
-			enum bfd_endian byte_order)
-{
-  LONGEST retval;
-  const unsigned char *p;
-  const unsigned char *startaddr = addr;
-  const unsigned char *endaddr = startaddr + len;
-
-  if (len > (int) sizeof (LONGEST))
-    error (_("\
-That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (LONGEST));
-
-  /* Start at the most significant end of the integer, and work towards
-     the least significant.  */
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      p = startaddr;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (++p; p < endaddr; ++p)
-	retval = (retval << 8) | *p;
-    }
-  else
-    {
-      p = endaddr - 1;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (--p; p >= startaddr; --p)
-	retval = (retval << 8) | *p;
-    }
-  return retval;
-}
-
-ULONGEST
-extract_unsigned_integer (const gdb_byte *addr, int len,
-			  enum bfd_endian byte_order)
-{
-  ULONGEST retval;
-  const unsigned char *p;
-  const unsigned char *startaddr = addr;
-  const unsigned char *endaddr = startaddr + len;
-
-  if (len > (int) sizeof (ULONGEST))
-    error (_("\
-That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (ULONGEST));
-
-  /* Start at the most significant end of the integer, and work towards
-     the least significant.  */
-  retval = 0;
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	retval = (retval << 8) | *p;
-    }
-  else
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	retval = (retval << 8) | *p;
-    }
-  return retval;
-}
 
 /* Sometimes a long long unsigned integer can be extracted as a
    LONGEST value.  This is done so that we can print these values
@@ -178,65 +112,6 @@ extract_typed_address (const gdb_byte *buf, struct type *type)
   return gdbarch_pointer_to_address (get_type_arch (type), type, buf);
 }
 
-/* All 'store' functions accept a host-format integer and store a
-   target-format integer at ADDR which is LEN bytes long.  */
-
-void
-store_signed_integer (gdb_byte *addr, int len,
-		      enum bfd_endian byte_order, LONGEST val)
-{
-  gdb_byte *p;
-  gdb_byte *startaddr = addr;
-  gdb_byte *endaddr = startaddr + len;
-
-  /* Start at the least significant end of the integer, and work towards
-     the most significant.  */
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-  else
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-}
-
-void
-store_unsigned_integer (gdb_byte *addr, int len,
-			enum bfd_endian byte_order, ULONGEST val)
-{
-  unsigned char *p;
-  unsigned char *startaddr = (unsigned char *) addr;
-  unsigned char *endaddr = startaddr + len;
-
-  /* Start at the least significant end of the integer, and work towards
-     the most significant.  */
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-  else
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-}
-
 /* Store the address ADDR as a pointer of type TYPE at BUF, in target
    form.  */
 void
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 43ea430..4ec33d4 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -662,11 +662,14 @@ enum register_status
 regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_signed (regnum, val);
+  return regcache->raw_read (regnum, val);
 }
 
-enum register_status
-regcache::raw_read_signed (int regnum, LONGEST *val)
+template<typename T>
+typename std::enable_if<(std::is_same<T, LONGEST>::value
+			 || std::is_same<T, ULONGEST>::value),
+			enum register_status>::type
+regcache::raw_read (int regnum, T *val)
 {
   gdb_byte *buf;
   enum register_status status;
@@ -675,9 +678,9 @@ regcache::raw_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = raw_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T> (buf,
+			       m_descr->sizeof_register[regnum],
+			       gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -688,44 +691,28 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
 			    ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_unsigned (regnum, val);
-}
-
-
-enum register_status
-regcache::raw_read_unsigned (int regnum, ULONGEST *val)
-{
-  gdb_byte *buf;
-  enum register_status status;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = raw_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->raw_read (regnum, val);
 }
 
 void
 regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_signed (regnum, val);
+  regcache->raw_write (regnum, val);
 }
 
-void
-regcache::raw_write_signed (int regnum, LONGEST val)
+template<typename T>
+typename std::enable_if<(std::is_same<T, LONGEST>::value
+			 || std::is_same<T, ULONGEST>::value),
+			void>::type
+regcache::raw_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   raw_write (regnum, buf);
 }
 
@@ -734,19 +721,7 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
 			     ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_unsigned (regnum, val);
-}
-
-void
-regcache::raw_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  raw_write (regnum, buf);
+  regcache->raw_write (regnum, val);
 }
 
 LONGEST
@@ -857,11 +832,14 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum,
 			     LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_signed (regnum, val);
+  return regcache->cooked_read (regnum, val);
 }
 
-enum register_status
-regcache::cooked_read_signed (int regnum, LONGEST *val)
+template<typename T>
+typename std::enable_if<(std::is_same<T, LONGEST>::value
+			 || std::is_same<T, ULONGEST>::value),
+			enum register_status>::type
+regcache::cooked_read (int regnum, T *val)
 {
   enum register_status status;
   gdb_byte *buf;
@@ -870,9 +848,8 @@ regcache::cooked_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = cooked_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T>(buf, m_descr->sizeof_register[regnum],
+			      gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -883,25 +860,7 @@ regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
 			       ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_unsigned (regnum, val);
-}
-
-enum register_status
-regcache::cooked_read_unsigned (int regnum, ULONGEST *val)
-{
-  enum register_status status;
-  gdb_byte *buf;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = cooked_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->cooked_read (regnum, val);
 }
 
 void
@@ -909,18 +868,21 @@ regcache_cooked_write_signed (struct regcache *regcache, int regnum,
 			      LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_signed (regnum, val);
+  regcache->cooked_write (regnum, val);
 }
 
-void
-regcache::cooked_write_signed (int regnum, LONGEST val)
+template<typename T>
+typename std::enable_if<(std::is_same<T, LONGEST>::value
+			 || std::is_same<T, ULONGEST>::value),
+			void>::type
+regcache::cooked_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   cooked_write (regnum, buf);
 }
 
@@ -929,19 +891,7 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
 				ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_unsigned (regnum, val);
-}
-
-void
-regcache::cooked_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  cooked_write (regnum, buf);
+  regcache->cooked_write (regnum, val);
 }
 
 /* See regcache.h.  */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 4cf27a0..9ba3cf8 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -282,23 +282,31 @@ public:
 #endif
   void raw_write (int regnum, const gdb_byte *buf);
 
-  enum register_status raw_read_signed (int regnum, LONGEST *val);
-
-  void raw_write_signed (int regnum, LONGEST val);
-
-  enum register_status raw_read_unsigned (int regnum, ULONGEST *val);
-
-  void raw_write_unsigned (int regnum, ULONGEST val);
+  template<typename T>
+  typename std::enable_if<(std::is_same<T, LONGEST>::value
+			   || std::is_same<T, ULONGEST>::value),
+			  enum register_status>::type
+  raw_read (int regnum, T *val);
+
+  template<typename T>
+  typename std::enable_if<(std::is_same<T, LONGEST>::value
+			   || std::is_same<T, ULONGEST>::value),
+			  void>::type
+  raw_write (int regnum, T val);
 
   struct value *cooked_read_value (int regnum);
 
-  enum register_status cooked_read_signed (int regnum, LONGEST *val);
-
-  void cooked_write_signed (int regnum, LONGEST val);
-
-  enum register_status cooked_read_unsigned (int regnum, ULONGEST *val);
-
-  void cooked_write_unsigned (int regnum, ULONGEST val);
+  template<typename T>
+  typename std::enable_if<(std::is_same<T, LONGEST>::value
+			   || std::is_same<T, ULONGEST>::value),
+			  enum register_status>::type
+  cooked_read (int regnum, T *val);
+
+  template<typename T>
+  typename std::enable_if<(std::is_same<T, LONGEST>::value
+			   || std::is_same<T, ULONGEST>::value),
+			  void>::type
+  cooked_write (int regnum, T val);
 
   void raw_update (int regnum);
 
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index dd18e9f..5aeb235 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1665,11 +1665,11 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
        */
       /* *INDENT-ON* */
       /* Get FPSCR as an int.  */
-      status = regcache->raw_read_unsigned (fpscr_base_regnum, &fpscr_value);
+      status = regcache->raw_read (fpscr_base_regnum, &fpscr_value);
       if (status != REG_VALID)
 	return status;
       /* Get SR as an int.  */
-      status = regcache->raw_read_unsigned (sr_base_regnum, &sr_value);
+      status = regcache->raw_read (sr_base_regnum, &sr_value);
       if (status != REG_VALID)
 	return status;
       /* Build the new value.  */
@@ -1847,15 +1847,15 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       fpscr_value = fpscr_c_value & fpscr_mask;
       sr_value = (fpscr_value & sr_mask) >> 6;
       
-      regcache->raw_read_unsigned (fpscr_base_regnum, &old_fpscr_value);
+      regcache->raw_read (fpscr_base_regnum, &old_fpscr_value);
       old_fpscr_value &= 0xfffc0002;
       fpscr_value |= old_fpscr_value;
-      regcache->raw_write_unsigned (fpscr_base_regnum, fpscr_value);
+      regcache->raw_write (fpscr_base_regnum, fpscr_value);
 
-      regcache->raw_read_unsigned (sr_base_regnum, &old_sr_value);
+      regcache->raw_read (sr_base_regnum, &old_sr_value);
       old_sr_value &= 0xffff8fff;
       sr_value |= old_sr_value;
-      regcache->raw_write_unsigned (sr_base_regnum, sr_value);
+      regcache->raw_write (sr_base_regnum, sr_value);
     }
 
   else if (reg_nr == FPUL_C_REGNUM)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-13 11:29 [RFC] LONGEST and ULONGEST function template instantiation Yao Qi
@ 2017-06-13 11:33 ` Yao Qi
  2017-06-14 13:54   ` Alan Hayward
  2017-06-14 16:12 ` Pedro Alves
  1 sibling, 1 reply; 7+ messages in thread
From: Yao Qi @ 2017-06-13 11:33 UTC (permalink / raw)
  To: gdb-patches; +Cc: Alan Hayward

On Tue, Jun 13, 2017 at 12:29 PM, Yao Qi <qiyaoltc@gmail.com> wrote:

>
> This patch was posted here
> https://sourceware.org/ml/gdb-patches/2017-05/msg00492.html but the
> problem was fixed in a different way.  However, I think the patch is still
> useful to shorten the code.

Add Alan to CC.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-13 11:33 ` Yao Qi
@ 2017-06-14 13:54   ` Alan Hayward
  0 siblings, 0 replies; 7+ messages in thread
From: Alan Hayward @ 2017-06-14 13:54 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches, nd


> On 13 Jun 2017, at 12:33, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
> On Tue, Jun 13, 2017 at 12:29 PM, Yao Qi <qiyaoltc@gmail.com> wrote:
> 
>> 
>> This patch was posted here
>> https://sourceware.org/ml/gdb-patches/2017-05/msg00492.html but the
>> problem was fixed in a different way.  However, I think the patch is still
>> useful to shorten the code.
> 
> Add Alan to CC.
> 

> It is an RFC, because I am not sure people like it or hate it :)

My only objection to this would be that “enable_if” is fairly confusing.
However, having said that, I think the end result is quite nice, and
calling the functions is very simple, so I withdraw my objection.

It would be nice if the header files could use “LongType” instead of
the longer “enable_if” block, however I remember when I tried this
myself and couldn’t find a way around it.


Alan.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-13 11:29 [RFC] LONGEST and ULONGEST function template instantiation Yao Qi
  2017-06-13 11:33 ` Yao Qi
@ 2017-06-14 16:12 ` Pedro Alves
  2017-06-15 11:59   ` Yao Qi
  1 sibling, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2017-06-14 16:12 UTC (permalink / raw)
  To: Yao Qi, Alan Hayward; +Cc: gdb-patches

On 06/13/2017 12:29 PM, Yao Qi wrote:
> This patch converts functions extract_{unsigned,signed}_integer
> to a function template extract_integer, which has two instantiations.  It
> also does the similar changes to store__{unsigned,signed}_integer,
> regcache::raw_read_{unsigned,signed}, regcache::raw_write_{unsigned,signed},
> regcache::cooked_read_{unsigned,signed},
> regcache::cooked_write_{unsigned,signed}.  It is an RFC, because I
> am not sure people like it or hate it :)

I like it, but I'd like it more with a few tweaks to the
implementation.  :-)  See patch below.

> 
> This patch was posted here
> https://sourceware.org/ml/gdb-patches/2017-05/msg00492.html but the
> problem was fixed in a different way.  However, I think the patch is still
> useful to shorten the code.
> 
> The patch increase the binary code size (measured on x86_64-linux), from
> 
> $ size ./gdb
>    text    data     bss     dec     hex filename
> 23856767        2395936  364616 26617319        19625e7 ./gdb
> 
> to
> 
> $ size ./gdb
>    text    data     bss     dec     hex filename
> 23858667        2395936  364616 26619219        1962d53 ./gdb

The version below has no impact on code size:

$ size gdb.before gdb.after
   text    data     bss     dec     hex filename
7535236  125008  181184 7841428  77a694 gdb.before
7535236  125008  181184 7841428  77a694 gdb.after

Since the templates will ever only be instantiated with T=LONGEST
and T=ULONGEST, then there's no actual need to move the
templates' definitions to the header file.  
Even if we wanted to move the functions to the header so that
their bodies can be inlined for performance (no idea whether it
really helps anything), I'd still think this is a useful
intermediate step, since it avoids both changing and moving the
function bodies at the same time.

> +
> +#define extract_unsigned_integer extract_integer<ULONGEST>
> +
> +#define extract_signed_integer extract_integer<LONGEST>


These can be static inline functions, instead of macros.



On 06/14/2017 02:54 PM, Alan Hayward wrote:

> My only objection to this would be that “enable_if” is fairly confusing.
> However, having said that, I think the end result is quite nice, and
> calling the functions is very simple, so I withdraw my objection.
> 
> It would be nice if the header files could use “LongType” instead of
> the longer “enable_if” block, however I remember when I tried this
> myself and couldnÂ’t find a way around it.
> 

In C++11 we have default template params, so we can use those for the
SFINAE magic instead of having to use a function's parameter of the
function's return type.  Also, I think that using the "gdb::Requires"
helper makes the parameter's intention clearer.

From bce7ebe33950b5a2cd5343d9a678ad23f02ec625 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Wed, 14 Jun 2017 16:24:07 +0100
Subject: [PATCH] extract/store integer templates

---
 gdb/defs.h      |  47 +++++++++++++++++++-----
 gdb/findvar.c   | 105 ++++++++++++++++++------------------------------------
 gdb/regcache.c  | 108 +++++++++++++-------------------------------------------
 gdb/regcache.h  |  20 +++++------
 gdb/sh64-tdep.c |  12 +++----
 5 files changed, 113 insertions(+), 179 deletions(-)

diff --git a/gdb/defs.h b/gdb/defs.h
index a1a97bb..55d16d1 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -82,6 +82,11 @@ enum compile_i_scope_types
     COMPILE_I_PRINT_VALUE_SCOPE,
   };
 
+
+template<typename T>
+using RequireLongest = gdb::Requires<gdb::Or<std::is_same<T, LONGEST>,
+					     std::is_same<T, ULONGEST>>>;
+
 /* Just in case they're not defined in stdio.h.  */
 
 #ifndef SEEK_SET
@@ -637,11 +642,22 @@ enum { MAX_REGISTER_SIZE = 64 };
 
 /* In findvar.c.  */
 
-extern LONGEST extract_signed_integer (const gdb_byte *, int,
-				       enum bfd_endian);
+template<typename T, typename = RequireLongest<T>>
+T extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order);
 
-extern ULONGEST extract_unsigned_integer (const gdb_byte *, int,
-					  enum bfd_endian);
+static inline LONGEST
+extract_signed_integer (const gdb_byte *addr, int len,
+			enum bfd_endian byte_order)
+{
+  return extract_integer<LONGEST> (addr, len, byte_order);
+}
+
+static inline ULONGEST
+extract_unsigned_integer (const gdb_byte *addr, int len,
+			  enum bfd_endian byte_order)
+{
+  return extract_integer<ULONGEST> (addr, len, byte_order);
+}
 
 extern int extract_long_unsigned_integer (const gdb_byte *, int,
 					  enum bfd_endian, LONGEST *);
@@ -649,11 +665,26 @@ extern int extract_long_unsigned_integer (const gdb_byte *, int,
 extern CORE_ADDR extract_typed_address (const gdb_byte *buf,
 					struct type *type);
 
-extern void store_signed_integer (gdb_byte *, int,
-				  enum bfd_endian, LONGEST);
+/* All 'store' functions accept a host-format integer and store a
+   target-format integer at ADDR which is LEN bytes long.  */
 
-extern void store_unsigned_integer (gdb_byte *, int,
-				    enum bfd_endian, ULONGEST);
+template<typename T, typename = RequireLongest<T>>
+extern void store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order,
+			   T val);
+
+static inline void
+store_signed_integer (gdb_byte *addr, int len,
+		      enum bfd_endian byte_order, LONGEST val)
+{
+  return store_integer (addr, len, byte_order, val);
+}
+
+static inline void
+store_unsigned_integer (gdb_byte *addr, int len,
+			enum bfd_endian byte_order, ULONGEST val)
+{
+  return store_integer (addr, len, byte_order, val);
+}
 
 extern void store_typed_address (gdb_byte *buf, struct type *type,
 				 CORE_ADDR addr);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 6c18e25..beb127e 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -47,70 +47,54 @@
 you lose
 #endif
 
-LONGEST
-extract_signed_integer (const gdb_byte *addr, int len,
-			enum bfd_endian byte_order)
+template<typename T, typename>
+T
+extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order)
 {
-  LONGEST retval;
+  T retval = 0;
   const unsigned char *p;
   const unsigned char *startaddr = addr;
   const unsigned char *endaddr = startaddr + len;
 
-  if (len > (int) sizeof (LONGEST))
+  if (len > (int) sizeof (T))
     error (_("\
 That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (LONGEST));
+	   (int) sizeof (T));
 
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
   if (byte_order == BFD_ENDIAN_BIG)
     {
       p = startaddr;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (++p; p < endaddr; ++p)
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  ++p;
+	}
+      for (; p < endaddr; ++p)
 	retval = (retval << 8) | *p;
     }
   else
     {
       p = endaddr - 1;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (--p; p >= startaddr; --p)
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  --p;
+	}
+      for (; p >= startaddr; --p)
 	retval = (retval << 8) | *p;
     }
   return retval;
 }
 
-ULONGEST
-extract_unsigned_integer (const gdb_byte *addr, int len,
-			  enum bfd_endian byte_order)
-{
-  ULONGEST retval;
-  const unsigned char *p;
-  const unsigned char *startaddr = addr;
-  const unsigned char *endaddr = startaddr + len;
-
-  if (len > (int) sizeof (ULONGEST))
-    error (_("\
-That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (ULONGEST));
-
-  /* Start at the most significant end of the integer, and work towards
-     the least significant.  */
-  retval = 0;
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	retval = (retval << 8) | *p;
-    }
-  else
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	retval = (retval << 8) | *p;
-    }
-  return retval;
-}
+/* Explicit instantiations.  */
+template LONGEST extract_integer<LONGEST> (const gdb_byte *addr, int len,
+					   enum bfd_endian byte_order);
+template ULONGEST extract_integer<ULONGEST> (const gdb_byte *addr, int len,
+					     enum bfd_endian byte_order);
 
 /* Sometimes a long long unsigned integer can be extracted as a
    LONGEST value.  This is done so that we can print these values
@@ -180,10 +164,10 @@ extract_typed_address (const gdb_byte *buf, struct type *type)
 
 /* All 'store' functions accept a host-format integer and store a
    target-format integer at ADDR which is LEN bytes long.  */
-
+template<typename T, typename>
 void
-store_signed_integer (gdb_byte *addr, int len,
-		      enum bfd_endian byte_order, LONGEST val)
+store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order,
+	       T val)
 {
   gdb_byte *p;
   gdb_byte *startaddr = addr;
@@ -209,33 +193,14 @@ store_signed_integer (gdb_byte *addr, int len,
     }
 }
 
-void
-store_unsigned_integer (gdb_byte *addr, int len,
-			enum bfd_endian byte_order, ULONGEST val)
-{
-  unsigned char *p;
-  unsigned char *startaddr = (unsigned char *) addr;
-  unsigned char *endaddr = startaddr + len;
+/* Explicit instantiations.  */
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order,
+			     LONGEST val);
 
-  /* Start at the least significant end of the integer, and work towards
-     the most significant.  */
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-  else
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-}
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order,
+			     ULONGEST val);
 
 /* Store the address ADDR as a pointer of type TYPE at BUF, in target
    form.  */
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 46f4641..608717f 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -662,11 +662,12 @@ enum register_status
 regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_signed (regnum, val);
+  return regcache->raw_read (regnum, val);
 }
 
+template<typename T, typename>
 enum register_status
-regcache::raw_read_signed (int regnum, LONGEST *val)
+regcache::raw_read (int regnum, T *val)
 {
   gdb_byte *buf;
   enum register_status status;
@@ -675,9 +676,9 @@ regcache::raw_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = raw_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T> (buf,
+			       m_descr->sizeof_register[regnum],
+			       gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -688,44 +689,26 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
 			    ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_unsigned (regnum, val);
-}
-
-
-enum register_status
-regcache::raw_read_unsigned (int regnum, ULONGEST *val)
-{
-  gdb_byte *buf;
-  enum register_status status;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = raw_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->raw_read (regnum, val);
 }
 
 void
 regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_signed (regnum, val);
+  regcache->raw_write (regnum, val);
 }
 
+template<typename T, typename>
 void
-regcache::raw_write_signed (int regnum, LONGEST val)
+regcache::raw_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   raw_write (regnum, buf);
 }
 
@@ -734,19 +717,7 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
 			     ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_unsigned (regnum, val);
-}
-
-void
-regcache::raw_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  raw_write (regnum, buf);
+  regcache->raw_write (regnum, val);
 }
 
 LONGEST
@@ -857,11 +828,12 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum,
 			     LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_signed (regnum, val);
+  return regcache->cooked_read (regnum, val);
 }
 
+template<typename T, typename>
 enum register_status
-regcache::cooked_read_signed (int regnum, LONGEST *val)
+regcache::cooked_read (int regnum, T *val)
 {
   enum register_status status;
   gdb_byte *buf;
@@ -870,9 +842,8 @@ regcache::cooked_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = cooked_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T> (buf, m_descr->sizeof_register[regnum],
+			       gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -883,25 +854,7 @@ regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
 			       ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_unsigned (regnum, val);
-}
-
-enum register_status
-regcache::cooked_read_unsigned (int regnum, ULONGEST *val)
-{
-  enum register_status status;
-  gdb_byte *buf;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = cooked_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->cooked_read (regnum, val);
 }
 
 void
@@ -909,18 +862,19 @@ regcache_cooked_write_signed (struct regcache *regcache, int regnum,
 			      LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_signed (regnum, val);
+  regcache->cooked_write (regnum, val);
 }
 
+template<typename T, typename>
 void
-regcache::cooked_write_signed (int regnum, LONGEST val)
+regcache::cooked_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   cooked_write (regnum, buf);
 }
 
@@ -929,19 +883,7 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
 				ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_unsigned (regnum, val);
-}
-
-void
-regcache::cooked_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  cooked_write (regnum, buf);
+  regcache->cooked_write (regnum, val);
 }
 
 /* See regcache.h.  */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 4cf27a0..3f3f823 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -282,23 +282,19 @@ public:
 #endif
   void raw_write (int regnum, const gdb_byte *buf);
 
-  enum register_status raw_read_signed (int regnum, LONGEST *val);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status raw_read (int regnum, T *val);
 
-  void raw_write_signed (int regnum, LONGEST val);
-
-  enum register_status raw_read_unsigned (int regnum, ULONGEST *val);
-
-  void raw_write_unsigned (int regnum, ULONGEST val);
+  template<typename T, typename = RequireLongest<T>>
+  void raw_write (int regnum, T val);
 
   struct value *cooked_read_value (int regnum);
 
-  enum register_status cooked_read_signed (int regnum, LONGEST *val);
-
-  void cooked_write_signed (int regnum, LONGEST val);
-
-  enum register_status cooked_read_unsigned (int regnum, ULONGEST *val);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status cooked_read (int regnum, T *val);
 
-  void cooked_write_unsigned (int regnum, ULONGEST val);
+  template<typename T, typename = RequireLongest<T>>
+  void cooked_write (int regnum, T val);
 
   void raw_update (int regnum);
 
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index 4eb8947..3273197 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1665,11 +1665,11 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
        */
       /* *INDENT-ON* */
       /* Get FPSCR as an int.  */
-      status = regcache->raw_read_unsigned (fpscr_base_regnum, &fpscr_value);
+      status = regcache->raw_read (fpscr_base_regnum, &fpscr_value);
       if (status != REG_VALID)
 	return status;
       /* Get SR as an int.  */
-      status = regcache->raw_read_unsigned (sr_base_regnum, &sr_value);
+      status = regcache->raw_read (sr_base_regnum, &sr_value);
       if (status != REG_VALID)
 	return status;
       /* Build the new value.  */
@@ -1847,15 +1847,15 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       fpscr_value = fpscr_c_value & fpscr_mask;
       sr_value = (fpscr_value & sr_mask) >> 6;
       
-      regcache->raw_read_unsigned (fpscr_base_regnum, &old_fpscr_value);
+      regcache->raw_read (fpscr_base_regnum, &old_fpscr_value);
       old_fpscr_value &= 0xfffc0002;
       fpscr_value |= old_fpscr_value;
-      regcache->raw_write_unsigned (fpscr_base_regnum, fpscr_value);
+      regcache->raw_write (fpscr_base_regnum, fpscr_value);
 
-      regcache->raw_read_unsigned (sr_base_regnum, &old_sr_value);
+      regcache->raw_read (sr_base_regnum, &old_sr_value);
       old_sr_value &= 0xffff8fff;
       sr_value |= old_sr_value;
-      regcache->raw_write_unsigned (sr_base_regnum, sr_value);
+      regcache->raw_write (sr_base_regnum, sr_value);
     }
 
   else if (reg_nr == FPUL_C_REGNUM)
-- 
2.5.5


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-14 16:12 ` Pedro Alves
@ 2017-06-15 11:59   ` Yao Qi
  2017-06-15 16:19     ` Pedro Alves
  0 siblings, 1 reply; 7+ messages in thread
From: Yao Qi @ 2017-06-15 11:59 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Alan Hayward, gdb-patches

Pedro Alves <palves@redhat.com> writes:

Hi Pedro,
I pick up your patch, and update the ChangeLog entry.

> The version below has no impact on code size:
>
> $ size gdb.before gdb.after
>    text    data     bss     dec     hex filename
> 7535236  125008  181184 7841428  77a694 gdb.before
> 7535236  125008  181184 7841428  77a694 gdb.after

I can't reproduce your result with gcc 5.4.0 on Ubuntu 16.04.  The
patched GDB size increased by 112, but it doesn't matter.

before:
$ size ./gdb
   text	   data	    bss	    dec	    hex	filename
7733505	 144208	 180768	8058481	 7af671	./gdb

after:
$ size ./gdb
   text    data     bss     dec     hex filename
7733617  144208  180768 8058593  7af6e1 ./gdb

-- 
Yao (齐尧)
From cb61b39bb2a35e6ac81dce31019e3dabbc111292 Mon Sep 17 00:00:00 2001
From: Yao Qi <yao.qi@linaro.org>
Date: Thu, 15 Jun 2017 11:06:58 +0100
Subject: [PATCH] extract/store integer function template

This patch converts functions extract_{unsigned,signed}_integer
to a function template extract_integer, which has two instantiations.  It
also does the similar changes to store__{unsigned,signed}_integer,
regcache::raw_read_{unsigned,signed}, regcache::raw_write_{unsigned,signed},
regcache::cooked_read_{unsigned,signed},
regcache::cooked_write_{unsigned,signed}.

This patch was posted here
https://sourceware.org/ml/gdb-patches/2017-05/msg00492.html but the
problem was fixed in a different way.  However, I think the patch is still
useful to shorten the code.

gdb:

2017-06-15  Alan Hayward  <alan.hayward@arm.com>
	    Pedro Alves  <palves@redhat.com>
	    Yao Qi  <yao.qi@linaro.org>

	* defs.h (RequireLongest): New.
	(extract_integer): Declare function template.
	(extract_signed_integer): Remove the declaration, but define it
	static inline.
	(extract_unsigned_integer): Likewise.
	(store_integer): Declare function template.
	(store_signed_integer): Remove the declaration, but define it
	static inline.
	(store_unsigned_integer): Likewise.
	* findvar.c (extract_integer): New function template.
	(extract_signed_integer): Remove.
	(extract_unsigned_integer): Remove.
	(extract_integer<LONGEST>, extract_integer<ULONGEST>): Explicit
	instantiations.
	(store_integer): New function template.
	(store_signed_integer): Remove.
	(store_unsigned_integer): Remove.
	(store_integer): Explicit instantiations.
	* regcache.c (regcache_raw_read_signed): Update.
	(regcache::raw_read): New function.
	(regcache::raw_read_signed): Remove.
	(regcache::raw_read_unsigned): Remove.
	(regcache_raw_read_unsigned): Update.
	(regcache_raw_write_unsigned): Update.
	(regcache::raw_write_signed): Remove.
	(regcache::raw_write): New function.
	(regcache_cooked_read_signed): Update.
	(regcache::raw_write_unsigned): Remove.
	(regcache::cooked_read_signed): Remove.
	(regcache_cooked_read_unsigned): Update.
	(regcache::cooked_read_unsigned): Remove.
	(regcache_cooked_write_signed): Update.
	(regcache_cooked_write_unsigned): Update.
	* regcache.h (regcache) <raw_read_signed>: Remove.
	<raw_write_signed, raw_read_unsigned, raw_write_unsigned>: Remove.
	<raw_read, raw_write>: New.
	<cooked_read_signed, cooked_write_signed>: Remove.
	<cooked_write_unsigned, cooked_read_unsigned>: Remove.
	<cooked_read, cooked_write>: New.
	* sh64-tdep.c (sh64_pseudo_register_read): Update.
	(sh64_pseudo_register_write): Update.

diff --git a/gdb/defs.h b/gdb/defs.h
index a1a97bb..55d16d1 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -82,6 +82,11 @@ enum compile_i_scope_types
     COMPILE_I_PRINT_VALUE_SCOPE,
   };
 
+
+template<typename T>
+using RequireLongest = gdb::Requires<gdb::Or<std::is_same<T, LONGEST>,
+					     std::is_same<T, ULONGEST>>>;
+
 /* Just in case they're not defined in stdio.h.  */
 
 #ifndef SEEK_SET
@@ -637,11 +642,22 @@ enum { MAX_REGISTER_SIZE = 64 };
 
 /* In findvar.c.  */
 
-extern LONGEST extract_signed_integer (const gdb_byte *, int,
-				       enum bfd_endian);
+template<typename T, typename = RequireLongest<T>>
+T extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order);
 
-extern ULONGEST extract_unsigned_integer (const gdb_byte *, int,
-					  enum bfd_endian);
+static inline LONGEST
+extract_signed_integer (const gdb_byte *addr, int len,
+			enum bfd_endian byte_order)
+{
+  return extract_integer<LONGEST> (addr, len, byte_order);
+}
+
+static inline ULONGEST
+extract_unsigned_integer (const gdb_byte *addr, int len,
+			  enum bfd_endian byte_order)
+{
+  return extract_integer<ULONGEST> (addr, len, byte_order);
+}
 
 extern int extract_long_unsigned_integer (const gdb_byte *, int,
 					  enum bfd_endian, LONGEST *);
@@ -649,11 +665,26 @@ extern int extract_long_unsigned_integer (const gdb_byte *, int,
 extern CORE_ADDR extract_typed_address (const gdb_byte *buf,
 					struct type *type);
 
-extern void store_signed_integer (gdb_byte *, int,
-				  enum bfd_endian, LONGEST);
+/* All 'store' functions accept a host-format integer and store a
+   target-format integer at ADDR which is LEN bytes long.  */
 
-extern void store_unsigned_integer (gdb_byte *, int,
-				    enum bfd_endian, ULONGEST);
+template<typename T, typename = RequireLongest<T>>
+extern void store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order,
+			   T val);
+
+static inline void
+store_signed_integer (gdb_byte *addr, int len,
+		      enum bfd_endian byte_order, LONGEST val)
+{
+  return store_integer (addr, len, byte_order, val);
+}
+
+static inline void
+store_unsigned_integer (gdb_byte *addr, int len,
+			enum bfd_endian byte_order, ULONGEST val)
+{
+  return store_integer (addr, len, byte_order, val);
+}
 
 extern void store_typed_address (gdb_byte *buf, struct type *type,
 				 CORE_ADDR addr);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 6c18e25..beb127e 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -47,70 +47,54 @@
 you lose
 #endif
 
-LONGEST
-extract_signed_integer (const gdb_byte *addr, int len,
-			enum bfd_endian byte_order)
+template<typename T, typename>
+T
+extract_integer (const gdb_byte *addr, int len, enum bfd_endian byte_order)
 {
-  LONGEST retval;
+  T retval = 0;
   const unsigned char *p;
   const unsigned char *startaddr = addr;
   const unsigned char *endaddr = startaddr + len;
 
-  if (len > (int) sizeof (LONGEST))
+  if (len > (int) sizeof (T))
     error (_("\
 That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (LONGEST));
+	   (int) sizeof (T));
 
   /* Start at the most significant end of the integer, and work towards
      the least significant.  */
   if (byte_order == BFD_ENDIAN_BIG)
     {
       p = startaddr;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (++p; p < endaddr; ++p)
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  ++p;
+	}
+      for (; p < endaddr; ++p)
 	retval = (retval << 8) | *p;
     }
   else
     {
       p = endaddr - 1;
-      /* Do the sign extension once at the start.  */
-      retval = ((LONGEST) * p ^ 0x80) - 0x80;
-      for (--p; p >= startaddr; --p)
+      if (std::is_signed<T>::value)
+	{
+	  /* Do the sign extension once at the start.  */
+	  retval = ((LONGEST) * p ^ 0x80) - 0x80;
+	  --p;
+	}
+      for (; p >= startaddr; --p)
 	retval = (retval << 8) | *p;
     }
   return retval;
 }
 
-ULONGEST
-extract_unsigned_integer (const gdb_byte *addr, int len,
-			  enum bfd_endian byte_order)
-{
-  ULONGEST retval;
-  const unsigned char *p;
-  const unsigned char *startaddr = addr;
-  const unsigned char *endaddr = startaddr + len;
-
-  if (len > (int) sizeof (ULONGEST))
-    error (_("\
-That operation is not available on integers of more than %d bytes."),
-	   (int) sizeof (ULONGEST));
-
-  /* Start at the most significant end of the integer, and work towards
-     the least significant.  */
-  retval = 0;
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	retval = (retval << 8) | *p;
-    }
-  else
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	retval = (retval << 8) | *p;
-    }
-  return retval;
-}
+/* Explicit instantiations.  */
+template LONGEST extract_integer<LONGEST> (const gdb_byte *addr, int len,
+					   enum bfd_endian byte_order);
+template ULONGEST extract_integer<ULONGEST> (const gdb_byte *addr, int len,
+					     enum bfd_endian byte_order);
 
 /* Sometimes a long long unsigned integer can be extracted as a
    LONGEST value.  This is done so that we can print these values
@@ -180,10 +164,10 @@ extract_typed_address (const gdb_byte *buf, struct type *type)
 
 /* All 'store' functions accept a host-format integer and store a
    target-format integer at ADDR which is LEN bytes long.  */
-
+template<typename T, typename>
 void
-store_signed_integer (gdb_byte *addr, int len,
-		      enum bfd_endian byte_order, LONGEST val)
+store_integer (gdb_byte *addr, int len, enum bfd_endian byte_order,
+	       T val)
 {
   gdb_byte *p;
   gdb_byte *startaddr = addr;
@@ -209,33 +193,14 @@ store_signed_integer (gdb_byte *addr, int len,
     }
 }
 
-void
-store_unsigned_integer (gdb_byte *addr, int len,
-			enum bfd_endian byte_order, ULONGEST val)
-{
-  unsigned char *p;
-  unsigned char *startaddr = (unsigned char *) addr;
-  unsigned char *endaddr = startaddr + len;
+/* Explicit instantiations.  */
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order,
+			     LONGEST val);
 
-  /* Start at the least significant end of the integer, and work towards
-     the most significant.  */
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      for (p = endaddr - 1; p >= startaddr; --p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-  else
-    {
-      for (p = startaddr; p < endaddr; ++p)
-	{
-	  *p = val & 0xff;
-	  val >>= 8;
-	}
-    }
-}
+template void store_integer (gdb_byte *addr, int len,
+			     enum bfd_endian byte_order,
+			     ULONGEST val);
 
 /* Store the address ADDR as a pointer of type TYPE at BUF, in target
    form.  */
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 43ea430..7eeb737 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -662,11 +662,12 @@ enum register_status
 regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_signed (regnum, val);
+  return regcache->raw_read (regnum, val);
 }
 
+template<typename T, typename>
 enum register_status
-regcache::raw_read_signed (int regnum, LONGEST *val)
+regcache::raw_read (int regnum, T *val)
 {
   gdb_byte *buf;
   enum register_status status;
@@ -675,9 +676,9 @@ regcache::raw_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = raw_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T> (buf,
+			       m_descr->sizeof_register[regnum],
+			       gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -688,44 +689,26 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
 			    ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->raw_read_unsigned (regnum, val);
-}
-
-
-enum register_status
-regcache::raw_read_unsigned (int regnum, ULONGEST *val)
-{
-  gdb_byte *buf;
-  enum register_status status;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = raw_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->raw_read (regnum, val);
 }
 
 void
 regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_signed (regnum, val);
+  regcache->raw_write (regnum, val);
 }
 
+template<typename T, typename>
 void
-regcache::raw_write_signed (int regnum, LONGEST val)
+regcache::raw_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   raw_write (regnum, buf);
 }
 
@@ -734,19 +717,7 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
 			     ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->raw_write_unsigned (regnum, val);
-}
-
-void
-regcache::raw_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_raw_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  raw_write (regnum, buf);
+  regcache->raw_write (regnum, val);
 }
 
 LONGEST
@@ -857,11 +828,12 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum,
 			     LONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_signed (regnum, val);
+  return regcache->cooked_read (regnum, val);
 }
 
+template<typename T, typename>
 enum register_status
-regcache::cooked_read_signed (int regnum, LONGEST *val)
+regcache::cooked_read (int regnum, T *val)
 {
   enum register_status status;
   gdb_byte *buf;
@@ -870,9 +842,8 @@ regcache::cooked_read_signed (int regnum, LONGEST *val)
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
   status = cooked_read (regnum, buf);
   if (status == REG_VALID)
-    *val = extract_signed_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
+    *val = extract_integer<T> (buf, m_descr->sizeof_register[regnum],
+			       gdbarch_byte_order (m_descr->gdbarch));
   else
     *val = 0;
   return status;
@@ -883,25 +854,7 @@ regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
 			       ULONGEST *val)
 {
   gdb_assert (regcache != NULL);
-  return regcache->cooked_read_unsigned (regnum, val);
-}
-
-enum register_status
-regcache::cooked_read_unsigned (int regnum, ULONGEST *val)
-{
-  enum register_status status;
-  gdb_byte *buf;
-
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  status = cooked_read (regnum, buf);
-  if (status == REG_VALID)
-    *val = extract_unsigned_integer
-      (buf, m_descr->sizeof_register[regnum],
-       gdbarch_byte_order (m_descr->gdbarch));
-  else
-    *val = 0;
-  return status;
+  return regcache->cooked_read (regnum, val);
 }
 
 void
@@ -909,18 +862,19 @@ regcache_cooked_write_signed (struct regcache *regcache, int regnum,
 			      LONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_signed (regnum, val);
+  regcache->cooked_write (regnum, val);
 }
 
+template<typename T, typename>
 void
-regcache::cooked_write_signed (int regnum, LONGEST val)
+regcache::cooked_write (int regnum, T val)
 {
   gdb_byte *buf;
 
   gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
   buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_signed_integer (buf, m_descr->sizeof_register[regnum],
-			gdbarch_byte_order (m_descr->gdbarch), val);
+  store_integer (buf, m_descr->sizeof_register[regnum],
+		 gdbarch_byte_order (m_descr->gdbarch), val);
   cooked_write (regnum, buf);
 }
 
@@ -929,19 +883,7 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
 				ULONGEST val)
 {
   gdb_assert (regcache != NULL);
-  regcache->cooked_write_unsigned (regnum, val);
-}
-
-void
-regcache::cooked_write_unsigned (int regnum, ULONGEST val)
-{
-  gdb_byte *buf;
-
-  gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
-  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, m_descr->sizeof_register[regnum],
-			  gdbarch_byte_order (m_descr->gdbarch), val);
-  cooked_write (regnum, buf);
+  regcache->cooked_write (regnum, val);
 }
 
 /* See regcache.h.  */
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 4cf27a0..3f3f823 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -282,23 +282,19 @@ public:
 #endif
   void raw_write (int regnum, const gdb_byte *buf);
 
-  enum register_status raw_read_signed (int regnum, LONGEST *val);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status raw_read (int regnum, T *val);
 
-  void raw_write_signed (int regnum, LONGEST val);
-
-  enum register_status raw_read_unsigned (int regnum, ULONGEST *val);
-
-  void raw_write_unsigned (int regnum, ULONGEST val);
+  template<typename T, typename = RequireLongest<T>>
+  void raw_write (int regnum, T val);
 
   struct value *cooked_read_value (int regnum);
 
-  enum register_status cooked_read_signed (int regnum, LONGEST *val);
-
-  void cooked_write_signed (int regnum, LONGEST val);
-
-  enum register_status cooked_read_unsigned (int regnum, ULONGEST *val);
+  template<typename T, typename = RequireLongest<T>>
+  enum register_status cooked_read (int regnum, T *val);
 
-  void cooked_write_unsigned (int regnum, ULONGEST val);
+  template<typename T, typename = RequireLongest<T>>
+  void cooked_write (int regnum, T val);
 
   void raw_update (int regnum);
 
diff --git a/gdb/sh64-tdep.c b/gdb/sh64-tdep.c
index dd18e9f..5aeb235 100644
--- a/gdb/sh64-tdep.c
+++ b/gdb/sh64-tdep.c
@@ -1665,11 +1665,11 @@ sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
        */
       /* *INDENT-ON* */
       /* Get FPSCR as an int.  */
-      status = regcache->raw_read_unsigned (fpscr_base_regnum, &fpscr_value);
+      status = regcache->raw_read (fpscr_base_regnum, &fpscr_value);
       if (status != REG_VALID)
 	return status;
       /* Get SR as an int.  */
-      status = regcache->raw_read_unsigned (sr_base_regnum, &sr_value);
+      status = regcache->raw_read (sr_base_regnum, &sr_value);
       if (status != REG_VALID)
 	return status;
       /* Build the new value.  */
@@ -1847,15 +1847,15 @@ sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
       fpscr_value = fpscr_c_value & fpscr_mask;
       sr_value = (fpscr_value & sr_mask) >> 6;
       
-      regcache->raw_read_unsigned (fpscr_base_regnum, &old_fpscr_value);
+      regcache->raw_read (fpscr_base_regnum, &old_fpscr_value);
       old_fpscr_value &= 0xfffc0002;
       fpscr_value |= old_fpscr_value;
-      regcache->raw_write_unsigned (fpscr_base_regnum, fpscr_value);
+      regcache->raw_write (fpscr_base_regnum, fpscr_value);
 
-      regcache->raw_read_unsigned (sr_base_regnum, &old_sr_value);
+      regcache->raw_read (sr_base_regnum, &old_sr_value);
       old_sr_value &= 0xffff8fff;
       sr_value |= old_sr_value;
-      regcache->raw_write_unsigned (sr_base_regnum, sr_value);
+      regcache->raw_write (sr_base_regnum, sr_value);
     }
 
   else if (reg_nr == FPUL_C_REGNUM)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-15 11:59   ` Yao Qi
@ 2017-06-15 16:19     ` Pedro Alves
  2017-06-16 14:46       ` Yao Qi
  0 siblings, 1 reply; 7+ messages in thread
From: Pedro Alves @ 2017-06-15 16:19 UTC (permalink / raw)
  To: Yao Qi; +Cc: Alan Hayward, gdb-patches

On 06/15/2017 12:59 PM, Yao Qi wrote:
> Pedro Alves <palves@redhat.com> writes:
> 
> Hi Pedro,
> I pick up your patch, and update the ChangeLog entry.

Thanks.  FAOD, fine with me to push it in.

>> The version below has no impact on code size:
>>
>> $ size gdb.before gdb.after
>>    text    data     bss     dec     hex filename
>> 7535236  125008  181184 7841428  77a694 gdb.before
>> 7535236  125008  181184 7841428  77a694 gdb.after
> 
> I can't reproduce your result with gcc 5.4.0 on Ubuntu 16.04.  The
> patched GDB size increased by 112, but it doesn't matter.
> 
> before:
> $ size ./gdb
>    text	   data	    bss	    dec	    hex	filename
> 7733505	 144208	 180768	8058481	 7af671	./gdb
> 
> after:
> $ size ./gdb
>    text    data     bss     dec     hex filename
> 7733617  144208  180768 8058593  7af6e1 ./gdb

Curious, I see the same too now.  Dunno what I did
before.

Diffing "size -A" (and stripping addr column) shows:

-gdb.before.stripped  :
+gdb.after.stripped  :
 .rela.plt              16344
 .init                     26
 .plt                   10912
-.text                4239945
+.text                4239705
 .fini                      9
-.rodata              2280312
+.rodata              2280728
 .stapsdt.base              1
-.eh_frame_hdr         126004
-.eh_frame             745124
+.eh_frame_hdr         125996
+.eh_frame             745084


So it results in less code after all.  The increase is
in .rodata.  Maybe the result of longer mangled names or
longer strings for __FUNCTION__.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [RFC] LONGEST and ULONGEST function template instantiation
  2017-06-15 16:19     ` Pedro Alves
@ 2017-06-16 14:46       ` Yao Qi
  0 siblings, 0 replies; 7+ messages in thread
From: Yao Qi @ 2017-06-16 14:46 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Alan Hayward, gdb-patches

On Thu, Jun 15, 2017 at 5:19 PM, Pedro Alves <palves@redhat.com> wrote:
> On 06/15/2017 12:59 PM, Yao Qi wrote:
>> Pedro Alves <palves@redhat.com> writes:
>>
>> Hi Pedro,
>> I pick up your patch, and update the ChangeLog entry.
>
> Thanks.  FAOD, fine with me to push it in.
>

Patch is pushed in.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-06-16 14:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-13 11:29 [RFC] LONGEST and ULONGEST function template instantiation Yao Qi
2017-06-13 11:33 ` Yao Qi
2017-06-14 13:54   ` Alan Hayward
2017-06-14 16:12 ` Pedro Alves
2017-06-15 11:59   ` Yao Qi
2017-06-15 16:19     ` Pedro Alves
2017-06-16 14:46       ` Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).