summaryrefslogtreecommitdiff
path: root/gdb/amd64-tdep.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2010-03-02 13:14:28 +0000
committerH.J. Lu <hjl.tools@gmail.com>2010-03-02 13:14:28 +0000
commit9d625812f24608f99fd99e8591ef3c80d729f9b5 (patch)
tree575270167ff452bd1f4d42c4a7a43034d79fff78 /gdb/amd64-tdep.c
parent3a18ddeea30dea5222f274e287ccc699c0446590 (diff)
downloadgdb-9d625812f24608f99fd99e8591ef3c80d729f9b5.tar.gz
Support x86 pseudo byte, word and dword registers.
gdb/ 2010-03-02 H.J. Lu <hongjiu.lu@intel.com> * amd64-tdep.c (amd64_byte_names): New. (amd64_word_names): Likewise. (amd64_dword_names): Likewise. (amd64_pseudo_register_name): Likewise. (amd64_pseudo_register_read): Likewise. (amd64_pseudo_register_write): Likewise. (amd64_init_abi): Set num_byte_regs, num_word_regs, num_dword_regs and num_mmx_regs. Call set_gdbarch_pseudo_register_read, set_gdbarch_pseudo_register_write and set_tdesc_pseudo_register_name. Don't call set_gdbarch_num_pseudo_regs. Don't set mm0_regnum. * i386-tdep.c (i386_num_mmx_regs): Removed. (i386_num_pseudo_regs): Likewise. (i386_byte_names): New. (i386_word_names): Likewise. (i386_byte_regnum_p): Likewise. (i386_word_regnum_p): Likewise. (i386_mmx_regnum_p): Updated. (i386_pseudo_register_name): Make it global. Handle byte and word pseudo-registers. (i386_pseudo_register_read): Likewise. (i386_pseudo_register_write): Likewise. (i386_pseudo_register_type): Handle byte, word and dword pseudo-registers (i386_register_reggroup_p): Don't include pseudo registers, except for MXX, in any register groups. Don't include pseudo byte, word, dword registers in general_reggroup. (i386_gdbarch_init): Set num_byte_regs, num_word_regs, num_dword_regs, al_regnum, ax_regnum and eax_regnum. Put MMX pseudo-registers after word pseudo-registers. Call set_gdbarch_num_pseudo_regs after calling gdbarch_init_osabi. * i386-tdep.h (gdbarch_tdep): Add num_mmx_regs, num_byte_regs, al_regnum, num_word_regs, ax_regnum, num_dword_regs and eax_regnum. (i386_byte_regnum_p): New. (i386_word_regnum_p): Likewise. (i386_dword_regnum_p): Likewise. (i386_pseudo_register_name): Likewise. (i386_pseudo_register_read): Likewise. (i386_pseudo_register_write): Likewise. gdb/testsuite/ 2010-03-02 H.J. Lu <hongjiu.lu@intel.com> * gdb.arch/amd64-byte.exp: New. * gdb.arch/amd64-dword.exp: Likewise. * gdb.arch/amd64-pseudo.c: Likewise. * gdb.arch/amd64-word.exp: Likewise. * gdb.arch/i386-byte.exp: Likewise. * gdb.arch/i386-pseudo.c: Likewise. * gdb.arch/i386-word.exp: Likewise.
Diffstat (limited to 'gdb/amd64-tdep.c')
-rw-r--r--gdb/amd64-tdep.c118
1 files changed, 114 insertions, 4 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 0ec60c1b22c..8c41a8a92e5 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -210,6 +210,107 @@ amd64_arch_reg_to_regnum (int reg)
return amd64_arch_regmap[reg];
}
+/* Register names for byte pseudo-registers. */
+
+static const char *amd64_byte_names[] =
+{
+ "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
+ "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
+};
+
+/* Register names for word pseudo-registers. */
+
+static const char *amd64_word_names[] =
+{
+ "ax", "bx", "cx", "dx", "si", "di", "bp", "sp",
+ "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+
+/* Register names for dword pseudo-registers. */
+
+static const char *amd64_dword_names[] =
+{
+ "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+
+/* Return the name of register REGNUM. */
+
+static const char *
+amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ if (i386_byte_regnum_p (gdbarch, regnum))
+ return amd64_byte_names[regnum - tdep->al_regnum];
+ else if (i386_word_regnum_p (gdbarch, regnum))
+ return amd64_word_names[regnum - tdep->ax_regnum];
+ else if (i386_dword_regnum_p (gdbarch, regnum))
+ return amd64_dword_names[regnum - tdep->eax_regnum];
+ else
+ return i386_pseudo_register_name (gdbarch, regnum);
+}
+
+static void
+amd64_pseudo_register_read (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum, gdb_byte *buf)
+{
+ gdb_byte raw_buf[MAX_REGISTER_SIZE];
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (i386_byte_regnum_p (gdbarch, regnum))
+ {
+ int gpnum = regnum - tdep->al_regnum;
+
+ /* Extract (always little endian). */
+ regcache_raw_read (regcache, gpnum, raw_buf);
+ memcpy (buf, raw_buf, 1);
+ }
+ else if (i386_dword_regnum_p (gdbarch, regnum))
+ {
+ int gpnum = regnum - tdep->eax_regnum;
+ /* Extract (always little endian). */
+ regcache_raw_read (regcache, gpnum, raw_buf);
+ memcpy (buf, raw_buf, 4);
+ }
+ else
+ i386_pseudo_register_read (gdbarch, regcache, regnum, buf);
+}
+
+static void
+amd64_pseudo_register_write (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum, const gdb_byte *buf)
+{
+ gdb_byte raw_buf[MAX_REGISTER_SIZE];
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (i386_byte_regnum_p (gdbarch, regnum))
+ {
+ int gpnum = regnum - tdep->al_regnum;
+
+ /* Read ... */
+ regcache_raw_read (regcache, gpnum, raw_buf);
+ /* ... Modify ... (always little endian). */
+ memcpy (raw_buf, buf, 1);
+ /* ... Write. */
+ regcache_raw_write (regcache, gpnum, raw_buf);
+ }
+ else if (i386_dword_regnum_p (gdbarch, regnum))
+ {
+ int gpnum = regnum - tdep->eax_regnum;
+
+ /* Read ... */
+ regcache_raw_read (regcache, gpnum, raw_buf);
+ /* ... Modify ... (always little endian). */
+ memcpy (raw_buf, buf, 4);
+ /* ... Write. */
+ regcache_raw_write (regcache, gpnum, raw_buf);
+ }
+ else
+ i386_pseudo_register_write (gdbarch, regcache, regnum, buf);
+}
+
/* Return the union class of CLASS1 and CLASS2. See the psABI for
@@ -2127,6 +2228,19 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
tdep->register_names = amd64_register_names;
+ tdep->num_byte_regs = 16;
+ tdep->num_word_regs = 16;
+ tdep->num_dword_regs = 16;
+ /* Avoid wiring in the MMX registers for now. */
+ tdep->num_mmx_regs = 0;
+
+ set_gdbarch_pseudo_register_read (gdbarch,
+ amd64_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch,
+ amd64_pseudo_register_write);
+
+ set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name);
+
/* AMD64 has an FPU and 16 SSE registers. */
tdep->st0_regnum = AMD64_ST0_REGNUM;
tdep->num_xmm_regs = 16;
@@ -2178,10 +2292,6 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_prologue (gdbarch, amd64_skip_prologue);
- /* Avoid wiring in the MMX registers for now. */
- set_gdbarch_num_pseudo_regs (gdbarch, 0);
- tdep->mm0_regnum = -1;
-
tdep->record_regmap = amd64_record_regmap;
set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);