From 7a36499abc7d110e83cb60f4895d0fcfbab43bf4 Mon Sep 17 00:00:00 2001 From: Ivo Raisr Date: Mon, 16 Jan 2017 08:45:48 -0800 Subject: [PATCH] gdb: sparc: split real and pseudo registers. gdb/ChangeLog: 2017-01-16 Ivo Raisr Split real and pseudo registers. * sparc-tdep.h (SPARC_CORE_REGISTERS): New macro. (sparc32_pseudo_regnum): New enum. * sparc64-tdep.h (sparc64_pseudo_regnum): New enum. * sparc-tdep.c (SPARC32_FPU_REGISTERS): New macro. (SPARC32_CP0_REGISTERS): New macro. (sparc32_pseudo_register_name): New function. (sparc32_register_name): Use sparc32_pseudo_register_name. (sparc32_pseudo_register_type): New function. (sparc32_register_type): Use sparc32_pseudo_register_type. (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Handle pseudo register numbers. * sparc64-tdep.c SPARC64_FPU_REGISTERS): New macro. (SPARC64_CP0_REGISTERS): New macro. (sparc64_pseudo_register_name): New function. (sparc64_register_name): Use sparc64_pseudo_register_name. (sparc64_pseudo_register_type): New function. (sparc64_register_type): Use sparc64_pseudo_register_type. (sparc64_pseudo_register_read, sparc64_pseudo_register_write): Handle pseudo register numbers. (sparc64_store_floating_fields, sparc64_extract_floating_fields, sparc64_store_arguments): Handle pseudo register numbers. --- gdb/ChangeLog | 25 ++++++++ gdb/sparc-tdep.c | 67 +++++++++++++++------- gdb/sparc-tdep.h | 15 ++++- gdb/sparc64-tdep.c | 163 ++++++++++++++++++++++++++++++++--------------------- gdb/sparc64-tdep.h | 7 ++- 5 files changed, 190 insertions(+), 87 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 39d66b8..89696f2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2017-01-16 Ivo Raisr + + Split real and pseudo registers. + * sparc-tdep.h (SPARC_CORE_REGISTERS): New macro. + (sparc32_pseudo_regnum): New enum. + * sparc64-tdep.h (sparc64_pseudo_regnum): New enum. + * sparc-tdep.c (SPARC32_FPU_REGISTERS): New macro. + (SPARC32_CP0_REGISTERS): New macro. + (sparc32_pseudo_register_name): New function. + (sparc32_register_name): Use sparc32_pseudo_register_name. + (sparc32_pseudo_register_type): New function. + (sparc32_register_type): Use sparc32_pseudo_register_type. + (sparc32_pseudo_register_read, sparc32_pseudo_register_write): Handle + pseudo register numbers. + * sparc64-tdep.c SPARC64_FPU_REGISTERS): New macro. + (SPARC64_CP0_REGISTERS): New macro. + (sparc64_pseudo_register_name): New function. + (sparc64_register_name): Use sparc64_pseudo_register_name. + (sparc64_pseudo_register_type): New function. + (sparc64_register_type): Use sparc64_pseudo_register_type. + (sparc64_pseudo_register_read, sparc64_pseudo_register_write): Handle + pseudo register numbers. + (sparc64_store_floating_fields, sparc64_extract_floating_fields, + sparc64_store_arguments): Handle pseudo register numbers. + 2017-01-13 Yao Qi * remote.c (REMOTE_DEBUG_MAX_CHAR): New macro. diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index fe8d547..81cbce2 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -296,20 +296,19 @@ sparc_structure_or_union_p (const struct type *type) } /* Register information. */ +#define SPARC32_FPU_REGISTERS \ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" +#define SPARC32_CP0_REGISTERS \ + "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" static const char *sparc32_register_names[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - - "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" + SPARC_CORE_REGISTERS, + SPARC32_FPU_REGISTERS, + SPARC32_CP0_REGISTERS }; /* Total number of registers. */ @@ -327,18 +326,30 @@ static const char *sparc32_pseudo_register_names[] = /* Total number of pseudo registers. */ #define SPARC32_NUM_PSEUDO_REGS ARRAY_SIZE (sparc32_pseudo_register_names) +/* Return the name of pseudo register REGNUM. */ + +static const char * +sparc32_pseudo_register_name (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum < SPARC32_NUM_PSEUDO_REGS) + return sparc32_pseudo_register_names[regnum]; + + internal_error (__FILE__, __LINE__, + _("sparc32_pseudo_register_name: bad register number %d"), + regnum); +} + /* Return the name of register REGNUM. */ static const char * sparc32_register_name (struct gdbarch *gdbarch, int regnum) { - if (regnum >= 0 && regnum < SPARC32_NUM_REGS) + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) return sparc32_register_names[regnum]; - if (regnum < SPARC32_NUM_REGS + SPARC32_NUM_PSEUDO_REGS) - return sparc32_pseudo_register_names[regnum - SPARC32_NUM_REGS]; - - return NULL; + return sparc32_pseudo_register_name (gdbarch, regnum); } /* Construct types for ISA-specific registers. */ @@ -399,6 +410,22 @@ sparc_fsr_type (struct gdbarch *gdbarch) } /* Return the GDB type object for the "standard" data type of data in + pseudo register REGNUM. */ + +static struct type * +sparc32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) + return builtin_type (gdbarch)->builtin_double; + + internal_error (__FILE__, __LINE__, + _("sparc32_pseudo_register_type: bad register number %d"), + regnum); +} + +/* Return the GDB type object for the "standard" data type of data in register REGNUM. */ static struct type * @@ -407,9 +434,6 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum) if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM) return builtin_type (gdbarch)->builtin_float; - if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM) - return builtin_type (gdbarch)->builtin_double; - if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) return builtin_type (gdbarch)->builtin_data_ptr; @@ -422,6 +446,9 @@ sparc32_register_type (struct gdbarch *gdbarch, int regnum) if (regnum == SPARC32_FSR_REGNUM) return sparc_fsr_type (gdbarch); + if (regnum >= gdbarch_num_regs (gdbarch)) + return sparc32_pseudo_register_type (gdbarch, regnum); + return builtin_type (gdbarch)->builtin_int32; } @@ -432,6 +459,7 @@ sparc32_pseudo_register_read (struct gdbarch *gdbarch, { enum register_status status; + regnum -= gdbarch_num_regs (gdbarch); gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); @@ -446,6 +474,7 @@ sparc32_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int regnum, const gdb_byte *buf) { + regnum -= gdbarch_num_regs (gdbarch); gdb_assert (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM); regnum = SPARC_F0_REGNUM + 2 * (regnum - SPARC32_D0_REGNUM); diff --git a/gdb/sparc-tdep.h b/gdb/sparc-tdep.h index ae0c354..4990873 100644 --- a/gdb/sparc-tdep.h +++ b/gdb/sparc-tdep.h @@ -20,6 +20,12 @@ #ifndef SPARC_TDEP_H #define SPARC_TDEP_H 1 +#define SPARC_CORE_REGISTERS \ + "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ + "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \ + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ + "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7" + struct frame_info; struct gdbarch; struct regcache; @@ -85,7 +91,7 @@ struct gdbarch_tdep enum sparc_regnum { - SPARC_G0_REGNUM, /* %g0 */ + SPARC_G0_REGNUM = 0, /* %g0 */ SPARC_G1_REGNUM, SPARC_G2_REGNUM, SPARC_G3_REGNUM, @@ -140,9 +146,12 @@ enum sparc32_regnum SPARC32_NPC_REGNUM, /* %npc */ SPARC32_FSR_REGNUM, /* %fsr */ SPARC32_CSR_REGNUM, /* %csr */ +}; - /* Pseudo registers. */ - SPARC32_D0_REGNUM, /* %d0 */ +/* Pseudo registers. */ +enum sparc32_pseudo_regnum +{ + SPARC32_D0_REGNUM = 0, /* %d0 */ SPARC32_D30_REGNUM /* %d30 */ = SPARC32_D0_REGNUM + 15 }; diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index f3e039d..3525098 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -226,28 +226,26 @@ sparc64_fprs_type (struct gdbarch *gdbarch) /* Register information. */ +#define SPARC64_FPU_REGISTERS \ + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62" +#define SPARC64_CP0_REGISTERS \ + "pc", "npc", \ + /* FIXME: Give "state" a name until we start using register groups. */ \ + "state", \ + "fsr", \ + "fprs", \ + "y" static const char *sparc64_register_names[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", - "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", - - "pc", "npc", - - /* FIXME: Give "state" a name until we start using register groups. */ - "state", - "fsr", - "fprs", - "y", + SPARC_CORE_REGISTERS, + SPARC64_FPU_REGISTERS, + SPARC64_CP0_REGISTERS }; /* Total number of registers. */ @@ -272,19 +270,56 @@ static const char *sparc64_pseudo_register_names[] = /* Total number of pseudo registers. */ #define SPARC64_NUM_PSEUDO_REGS ARRAY_SIZE (sparc64_pseudo_register_names) +/* Return the name of pseudo register REGNUM. */ + +static const char * +sparc64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum < SPARC64_NUM_PSEUDO_REGS) + return sparc64_pseudo_register_names[regnum]; + + internal_error (__FILE__, __LINE__, + _("sparc64_pseudo_register_name: bad register number %d"), + regnum); +} + /* Return the name of register REGNUM. */ static const char * sparc64_register_name (struct gdbarch *gdbarch, int regnum) { - if (regnum >= 0 && regnum < SPARC64_NUM_REGS) + if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)) return sparc64_register_names[regnum]; - if (regnum >= SPARC64_NUM_REGS - && regnum < SPARC64_NUM_REGS + SPARC64_NUM_PSEUDO_REGS) - return sparc64_pseudo_register_names[regnum - SPARC64_NUM_REGS]; + return sparc64_pseudo_register_name (gdbarch, regnum); +} + +/* Return the GDB type object for the "standard" data type of data in + pseudo register REGNUM. */ + +static struct type * +sparc64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) +{ + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum == SPARC64_CWP_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum == SPARC64_PSTATE_REGNUM) + return sparc64_pstate_type (gdbarch); + if (regnum == SPARC64_ASI_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum == SPARC64_CCR_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) + return builtin_type (gdbarch)->builtin_double; + if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) + return builtin_type (gdbarch)->builtin_long_double; - return NULL; + internal_error (__FILE__, __LINE__, + _("sparc64_pseudo_register_type: bad register number %d"), + regnum); } /* Return the GDB type object for the "standard" data type of data in @@ -294,7 +329,6 @@ static struct type * sparc64_register_type (struct gdbarch *gdbarch, int regnum) { /* Raw registers. */ - if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM) return builtin_type (gdbarch)->builtin_data_ptr; if (regnum >= SPARC_G0_REGNUM && regnum <= SPARC_I7_REGNUM) @@ -319,19 +353,8 @@ sparc64_register_type (struct gdbarch *gdbarch, int regnum) return builtin_type (gdbarch)->builtin_int64; /* Pseudo registers. */ - - if (regnum == SPARC64_CWP_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum == SPARC64_PSTATE_REGNUM) - return sparc64_pstate_type (gdbarch); - if (regnum == SPARC64_ASI_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum == SPARC64_CCR_REGNUM) - return builtin_type (gdbarch)->builtin_int64; - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D62_REGNUM) - return builtin_type (gdbarch)->builtin_double; - if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q60_REGNUM) - return builtin_type (gdbarch)->builtin_long_double; + if (regnum >= gdbarch_num_regs (gdbarch)) + return sparc64_pseudo_register_type (gdbarch, regnum); internal_error (__FILE__, __LINE__, _("invalid regnum")); } @@ -344,7 +367,7 @@ sparc64_pseudo_register_read (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum register_status status; - gdb_assert (regnum >= SPARC64_NUM_REGS); + regnum -= gdbarch_num_regs (gdbarch); if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) { @@ -421,7 +444,8 @@ sparc64_pseudo_register_write (struct gdbarch *gdbarch, int regnum, const gdb_byte *buf) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_assert (regnum >= SPARC64_NUM_REGS); + + regnum -= gdbarch_num_regs (gdbarch); if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D30_REGNUM) { @@ -638,6 +662,7 @@ static void sparc64_store_floating_fields (struct regcache *regcache, struct type *type, const gdb_byte *valbuf, int element, int bitpos) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); int len = TYPE_LENGTH (type); gdb_assert (element < 16); @@ -652,14 +677,15 @@ sparc64_store_floating_fields (struct regcache *regcache, struct type *type, gdb_assert (bitpos == 0); gdb_assert ((element % 2) == 0); - regnum = SPARC64_Q0_REGNUM + element / 2; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + element / 2; regcache_cooked_write (regcache, regnum, valbuf); } else if (len == 8) { gdb_assert (bitpos == 0 || bitpos == 64); - regnum = SPARC64_D0_REGNUM + element + bitpos / 64; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element + bitpos / 64; regcache_cooked_write (regcache, regnum, valbuf + (bitpos / 8)); } else @@ -712,6 +738,8 @@ static void sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, gdb_byte *valbuf, int bitpos) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + if (sparc64_floating_p (type)) { int len = TYPE_LENGTH (type); @@ -721,14 +749,15 @@ sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, { gdb_assert (bitpos == 0 || bitpos == 128); - regnum = SPARC64_Q0_REGNUM + bitpos / 128; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + + bitpos / 128; regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); } else if (len == 8) { gdb_assert (bitpos % 64 == 0 && bitpos >= 0 && bitpos < 256); - regnum = SPARC64_D0_REGNUM + bitpos / 64; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + bitpos / 64; regcache_cooked_read (regcache, regnum, valbuf + (bitpos / 8)); } else @@ -911,13 +940,13 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, /* Float Complex or double Complex arguments. */ if (element < 16) { - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + element; if (len == 16) { - if (regnum < SPARC64_D30_REGNUM) + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D30_REGNUM) regcache_cooked_write (regcache, regnum + 1, valbuf + 8); - if (regnum < SPARC64_D10_REGNUM) + if (regnum < gdbarch_num_regs (gdbarch) + SPARC64_D10_REGNUM) regcache_cooked_write (regcache, SPARC_O0_REGNUM + element + 1, valbuf + 8); @@ -932,12 +961,14 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, if (element % 2) element++; if (element < 16) - regnum = SPARC64_Q0_REGNUM + element / 2; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_Q0_REGNUM + + element / 2; } else if (len == 8) { if (element < 16) - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element; } else if (len == 4) { @@ -952,7 +983,8 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, valbuf = buf; len = 8; if (element < 16) - regnum = SPARC64_D0_REGNUM + element; + regnum = gdbarch_num_regs (gdbarch) + SPARC64_D0_REGNUM + + element; } } else @@ -969,19 +1001,24 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, /* If we're storing the value in a floating-point register, also store it in the corresponding %0 register(s). */ - if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) - { - gdb_assert (element < 6); - regnum = SPARC_O0_REGNUM + element; - regcache_cooked_write (regcache, regnum, valbuf); - } - else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) - { - gdb_assert (element < 5); - regnum = SPARC_O0_REGNUM + element; - regcache_cooked_write (regcache, regnum, valbuf); - regcache_cooked_write (regcache, regnum + 1, valbuf + 8); - } + if (regnum >= gdbarch_num_regs (gdbarch)) + { + regnum -= gdbarch_num_regs (gdbarch); + + if (regnum >= SPARC64_D0_REGNUM && regnum <= SPARC64_D10_REGNUM) + { + gdb_assert (element < 6); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + } + else if (regnum >= SPARC64_Q0_REGNUM && regnum <= SPARC64_Q8_REGNUM) + { + gdb_assert (element < 5); + regnum = SPARC_O0_REGNUM + element; + regcache_cooked_write (regcache, regnum, valbuf); + regcache_cooked_write (regcache, regnum + 1, valbuf + 8); + } + } } /* Always store the argument in memory. */ diff --git a/gdb/sparc64-tdep.h b/gdb/sparc64-tdep.h index 13d04b6..324778e 100644 --- a/gdb/sparc64-tdep.h +++ b/gdb/sparc64-tdep.h @@ -56,9 +56,12 @@ enum sparc64_regnum SPARC64_FSR_REGNUM, /* %fsr */ SPARC64_FPRS_REGNUM, /* %fprs */ SPARC64_Y_REGNUM, /* %y */ +}; - /* Pseudo registers. */ - SPARC64_CWP_REGNUM, /* %cwp */ +/* Pseudo registers. */ +enum sparc64_pseudo_regnum +{ + SPARC64_CWP_REGNUM = 0, /* %cwp */ SPARC64_PSTATE_REGNUM, /* %pstate */ SPARC64_ASI_REGNUM, /* %asi */ SPARC64_CCR_REGNUM, /* %ccr */ -- 2.7.4