@@ -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);
@@ -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
@@ -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. */
@@ -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);
@@ -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)