This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

for reference: E500 Dwarf piece simplifier


This adds a Dwarf piece simplifier that recognizes piece lists that
refer to E500 vector registers.  It's based on the patch I posted to
the discussion here:

http://sources.redhat.com/ml/gdb/2004-08/msg00153.html

Since we're still discussing whether we want to take this piece-
simplification approach at all, rather than waiting for full scattered
value support in core GDB, this post isn't a request for approval,
although review is always welcome.  It's more to get the work out
there and let people see what a piece simplifier would look like.

This is all based on the dwarf2expr piece interface I posted here:

http://sources.redhat.com/ml/gdb-patches/2004-08/msg00351.html

2004-08-09  Jim Blandy  <jimb@redhat.com>

	* rs6000-tdep.c: #include "dwarf2expr.h".
	(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.

diff -crp -x '*~' -x '.#*' -x CVS gdb/rs6000-tdep.c gdb/rs6000-tdep.c
*** gdb/rs6000-tdep.c	2004-08-09 19:29:29.000000000 -0500
--- gdb/rs6000-tdep.c	2004-08-10 11:28:43.000000000 -0500
***************
*** 40,45 ****
--- 40,46 ----
  #include "sim-regno.h"
  #include "gdb/sim-ppc.h"
  #include "reggroups.h"
+ #include "dwarf2expr.h"
  
  #include "libbfd.h"		/* for bfd_default_set_arch_mach */
  #include "coff/internal.h"	/* for libcoff.h */
*************** e500_register_reggroup_p (struct gdbarch
*** 2005,2010 ****
--- 2006,2089 ----
    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)
*************** rs6000_gdbarch_init (struct gdbarch_info
*** 3172,3177 ****
--- 3251,3258 ----
          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:



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]