aboutsummaryrefslogtreecommitdiff
path: root/gdb/mips-tdep.c
diff options
context:
space:
mode:
authorHui Zhu <teawater@gmail.com>2010-12-28 16:00:13 +0000
committerHui Zhu <teawater@gmail.com>2010-12-28 16:00:13 +0000
commit175ff332d0cbd9e522a396be6a990d20fdd0ea07 (patch)
tree0d2a59ecdf58e2168c518d64a28b39c9508cf699 /gdb/mips-tdep.c
parentf32bf4a4c92412ee5bed6eb3c45cd2733d2465cc (diff)
downloadgdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.zip
gdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.tar.gz
gdb-175ff332d0cbd9e522a396be6a990d20fdd0ea07.tar.bz2
2010-12-28 Hui Zhu <teawater@gmail.com>
* gdbarch.sh (ax_pseudo_register_collect, ax_pseudo_register_push_stack): new callbacks. (agent_expr): Forward declare. * gdbarch.h, gdbarch.c: Regenerate. * ax-gdb.c (gen_expr): Remove pseudo-register check code. * ax-general.c (user-regs.h): New include. (ax_reg): Call gdbarch_ax_pseudo_register_push_stack. (ax_reg_mask): Call gdbarch_ax_pseudo_register_collect. * mips-tdep.c (ax.h): New include. (mips_ax_pseudo_register_collect, mips_ax_pseudo_register_push_stack): New functions. (mips_gdbarch_init): Set mips_ax_pseudo_register_collect and mips_ax_pseudo_register_push_stack.
Diffstat (limited to 'gdb/mips-tdep.c')
-rw-r--r--gdb/mips-tdep.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index e6df5f5..9b384ac 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -58,6 +58,7 @@
#include "dwarf2-frame.h"
#include "user-regs.h"
#include "valprint.h"
+#include "ax.h"
static const struct objfile_data *mips_pdr_data;
@@ -616,6 +617,48 @@ mips_pseudo_register_write (struct gdbarch *gdbarch,
internal_error (__FILE__, __LINE__, _("bad register size"));
}
+static int
+mips_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+
+ ax_reg_mask (ax, rawnum);
+
+ return 0;
+}
+
+static int
+mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+ if (register_size (gdbarch, rawnum) >= register_size (gdbarch, reg))
+ {
+ ax_reg (ax, rawnum);
+
+ if (register_size (gdbarch, rawnum) > register_size (gdbarch, reg))
+ {
+ if (!gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
+ || gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
+ {
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_lsh);
+ }
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_rsh_signed);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__, _("bad register size"));
+
+ return 0;
+}
+
/* Table to translate MIPS16 register field to actual register number. */
static int mips16_to_32_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };
@@ -5933,6 +5976,11 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
+ set_gdbarch_ax_pseudo_register_collect (gdbarch,
+ mips_ax_pseudo_register_collect);
+ set_gdbarch_ax_pseudo_register_push_stack
+ (gdbarch, mips_ax_pseudo_register_push_stack);
+
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);