diff options
author | Jim Blandy <jimb@codesourcery.com> | 2004-09-07 16:16:01 +0000 |
---|---|---|
committer | Jim Blandy <jimb@codesourcery.com> | 2004-09-07 16:16:01 +0000 |
commit | d5e4480e10392e731e45755d60b604722234be82 (patch) | |
tree | 5a770bfcb29abd621f7deaf968de095278e10918 /gdb/rs6000-tdep.c | |
parent | 40dd33a331138de88780ebfd6f08fd1030ecf773 (diff) | |
download | gdb-cvs/master-UNNAMED-BRANCH.tar.gz |
* rs6000-tdep.c: #include "dwarf2expr.h".master-UNNAMED-BRANCHcvs/master-UNNAMED-BRANCH
(dwarf_piece_is_ev_upper_reg, dwarf_piece_is_gpr)
(e500_dwarf_simplify_register_pieces): New functions.
(rs6000_gdbarch_init): If the architecture is E500, register
e500_dwarf_simplify_register_pieces.
* Makefile.in (rs6000-tdep.o): Update dependencies.
* gdbarch.sh (dwarf_simplify_register_pieces): New method.
Add forward declaration for 'struct dwarf_expr_piece'.
* gdbarch.c, gdbarch.h: Regenerated.
* dwarf2loc.c (dwarf2_evaluate_loc_desc): Try to simplify
multi-piece expression results before giving up.
* arch-utils.c (dwarf_never_simplify_pieces): New function.
* arch-utils.h (struct dwarf_expr_piece): Forward decl for struct
type, used in ...
(dwarf_never_simplify_pieces): New declaration.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 871e9b4d0fd..9bfcaec39b5 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -40,6 +40,7 @@ #include "sim-regno.h" #include "gdb/sim-ppc.h" #include "reggroups.h" +#include "dwarf2expr.h" #include "dwarf2-frame.h" #include "libbfd.h" /* for bfd_default_set_arch_mach */ @@ -2006,6 +2007,84 @@ e500_register_reggroup_p (struct gdbarch *gdbarch, return default_register_reggroup_p (gdbarch, regnum, group); } +/* Return true if PIECE is a SPE upper-half register for ARCH. + Remember that pieces use the Dwarf register numbering. */ +static int +dwarf_piece_is_ev_upper_reg (struct gdbarch *arch, + struct dwarf_expr_piece *piece) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + + return (piece->in_reg + && 1200 <= piece->value + && piece->value < 1200 + ppc_num_gprs + && piece->size == register_size (arch, + (piece->value - 1200 + + tdep->ppc_ev0_upper_regnum))); +} + +/* Return true if PIECE is a full GPR in ARCH. + Remember that pieces use the Dwarf register numbering. */ +static int +dwarf_piece_is_gpr (struct gdbarch *arch, + struct dwarf_expr_piece *piece) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (arch); + + return (piece->in_reg + && 0 <= piece->value + && piece->value < ppc_num_gprs + && (piece->size + == register_size (arch, piece->value + tdep->ppc_gp0_regnum))); +} + +static int +e500_dwarf_simplify_register_pieces (struct gdbarch *gdbarch, + int num_pieces, + struct dwarf_expr_piece *pieces) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (num_pieces == 2) + { + int low, high; + + /* Pieces are listed in order of increasing addresses, so the + endianness affects the order of the most- and least- + significant halves. */ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + high = 0, low = 1; + else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) + low = 0, high = 1; + else + internal_error (__FILE__, __LINE__, + "fetch_register: unexpected byte order: %d", + gdbarch_byte_order (gdbarch)); + + /* An SPE vector register is the concatenation of an "upper + half" register with a GPR, each four bytes long. */ + if (dwarf_piece_is_ev_upper_reg (gdbarch, &pieces[high]) + && dwarf_piece_is_gpr (gdbarch, &pieces[low]) + && (pieces[high].value - 1200 == pieces[low].value)) + /* Return the corresponding 64-bit 'ev' pseudo-register. */ + return tdep->ppc_ev0_regnum + pieces[low].value; + + /* long long values are sometimes placed in pairs of consecutive + registers. The lower-addressed end of the value is always + assigned the lower-numbered register, so we don't need to + worry about endianness here. */ + else if (dwarf_piece_is_gpr (gdbarch, &pieces[0]) + && dwarf_piece_is_gpr (gdbarch, &pieces[1]) + && pieces[0].value + 1 == pieces[1].value) + return tdep->ppc_gp0_regnum + pieces[0].value; + + else + return -1; + } + else + return -1; +} + /* Convert a DBX STABS register number to a GDB register number. */ static int rs6000_stab_reg_to_regnum (int num) @@ -3177,6 +3256,8 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write); set_gdbarch_register_reggroup_p (gdbarch, e500_register_reggroup_p); + set_gdbarch_dwarf_simplify_register_pieces + (gdbarch, e500_dwarf_simplify_register_pieces); break; case bfd_mach_ppc64: |