* gdbarch.sh (GET_SAVED_REGISTER): Change to a predicate function.
* gdbarch.h, gdbarch.c: Regnerate.
* frame.h (frame_register): Declare.
* frame.c (frame_register): New function.
(get_saved_register): Test GET_SAVED_REGISTER_P before calling
GET_SAVED_REGISTER, otherwize call
generic_unwind_get_saved_register.
(frame_register_read): Use frame_register instead of
get_saved_register.
+2002-11-05 Andrew Cagney <ac131313@redhat.com>
+
+ * gdbarch.sh (GET_SAVED_REGISTER): Change to a predicate function.
+ * gdbarch.h, gdbarch.c: Regnerate.
+ * frame.h (frame_register): Declare.
+ * frame.c (frame_register): New function.
+ (get_saved_register): Test GET_SAVED_REGISTER_P before calling
+ GET_SAVED_REGISTER, otherwize call
+ generic_unwind_get_saved_register.
+ (frame_register_read): Use frame_register instead of
+ get_saved_register.
+
2002-11-05 Elena Zannoni <ezannoni@redhat.com>
* event-loop.c (start_event_loop): Add comment.
optimizedp, lvalp, addrp, realnump, bufferp);
}
+void
+frame_register (struct frame_info *frame, int regnum,
+ int *optimizedp, enum lval_type *lvalp,
+ CORE_ADDR *addrp, int *realnump, void *bufferp)
+{
+ /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates
+ that the value proper does not need to be fetched. */
+ gdb_assert (optimizedp != NULL);
+ gdb_assert (lvalp != NULL);
+ gdb_assert (addrp != NULL);
+ gdb_assert (realnump != NULL);
+ /* gdb_assert (bufferp != NULL); */
+
+ /* Ulgh! Old code that, for lval_register, sets ADDRP to the offset
+ of the register in the register cache. It should instead return
+ the REGNUM corresponding to that register. Translate the . */
+ if (GET_SAVED_REGISTER_P ())
+ {
+ GET_SAVED_REGISTER (bufferp, optimizedp, addrp, frame, regnum, lvalp);
+ /* Compute the REALNUM if the caller wants it. */
+ if (*lvalp == lval_register)
+ {
+ int regnum;
+ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+ {
+ if (*addrp == register_offset_hack (current_gdbarch, regnum))
+ {
+ *realnump = regnum;
+ return;
+ }
+ }
+ internal_error (__FILE__, __LINE__,
+ "Failed to compute the register number corresponding"
+ " to 0x%s", paddr_d (*addrp));
+ }
+ *realnump = -1;
+ return;
+ }
+
+ /* Reached the the bottom (youngest, inner most) of the frame chain
+ (youngest, inner most) frame, go direct to the hardware register
+ cache (do not pass go, do not try to cache the value, ...). The
+ unwound value would have been cached in frame->next but that
+ doesn't exist. This doesn't matter as the hardware register
+ cache is stopping any unnecessary accesses to the target. */
+
+ /* NOTE: cagney/2002-04-14: It would be nice if, instead of a
+ special case, there was always an inner frame dedicated to the
+ hardware registers. Unfortunatly, there is too much unwind code
+ around that looks up/down the frame chain while making the
+ assumption that each frame level is using the same unwind code. */
+
+ if (frame == NULL)
+ frame_register_unwind (NULL, regnum, optimizedp, lvalp, addrp, realnump,
+ bufferp);
+ else
+ frame_register_unwind (frame->next, regnum, optimizedp, lvalp, addrp,
+ realnump, bufferp);
+}
+
void
frame_unwind_signed_register (struct frame_info *frame, int regnum,
LONGEST *val)
int regnum,
enum lval_type *lval)
{
- GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval);
+ if (GET_SAVED_REGISTER_P ())
+ {
+ GET_SAVED_REGISTER (raw_buffer, optimized, addrp, frame, regnum, lval);
+ return;
+ }
+ generic_unwind_get_saved_register (raw_buffer, optimized, addrp, frame,
+ regnum, lval);
}
/* frame_register_read ()
int
frame_register_read (struct frame_info *frame, int regnum, void *myaddr)
{
- int optim;
- get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame,
- regnum, (enum lval_type *) NULL);
+ int optimized;
+ enum lval_type lval;
+ CORE_ADDR addr;
+ int realnum;
+ frame_register (frame, regnum, &optimized, &lval, &addr, &realnum, myaddr);
/* FIXME: cagney/2002-05-15: This test, is just bogus.
if (register_cached (regnum) < 0)
return 0; /* register value not available */
- return !optim;
+ return !optimized;
}
CORE_ADDR *addrp, int *realnump,
void *valuep);
+/* Return the value of the register in this FRAME. Convenience
+ function that is equivalent to frame_register_unwind
+ (get_next_frame (FRAME), ...). If VALUEP is NULL, don't
+ fetch/compute the value. */
+
+extern void frame_register (struct frame_info *frame, int regnum,
+ int *optimizedp, enum lval_type *lvalp,
+ CORE_ADDR *addrp, int *realnump,
+ void *valuep);
+
/* Unwind FRAME so that the value of register REGNUM, in the previous
frame is returned. Simplified versions of frame_register_unwind. */
/* NOTE: cagney/2002-09-13: Return void as one day these functions may
current_gdbarch->init_frame_pc_first = init_frame_pc_noop;
current_gdbarch->init_frame_pc = init_frame_pc_default;
current_gdbarch->coerce_float_to_double = default_coerce_float_to_double;
- current_gdbarch->get_saved_register = generic_unwind_get_saved_register;
current_gdbarch->register_convertible = generic_register_convertible_not;
current_gdbarch->convert_register_p = legacy_convert_register_p;
current_gdbarch->register_to_value = legacy_register_to_value;
/* Skip verify of init_frame_pc_first, invalid_p == 0 */
/* Skip verify of init_frame_pc, invalid_p == 0 */
/* Skip verify of coerce_float_to_double, invalid_p == 0 */
- /* Skip verify of get_saved_register, invalid_p == 0 */
+ /* Skip verify of get_saved_register, has predicate */
/* Skip verify of register_convertible, invalid_p == 0 */
/* Skip verify of register_convert_to_virtual, invalid_p == 0 */
/* Skip verify of register_convert_to_raw, invalid_p == 0 */
gdbarch->coerce_float_to_double = coerce_float_to_double;
}
+int
+gdbarch_get_saved_register_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->get_saved_register != 0;
+}
+
void
gdbarch_get_saved_register (struct gdbarch *gdbarch, char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval)
{
#endif
#endif
+#if defined (GET_SAVED_REGISTER)
+/* Legacy for systems yet to multi-arch GET_SAVED_REGISTER */
+#if !defined (GET_SAVED_REGISTER_P)
+#define GET_SAVED_REGISTER_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (GET_SAVED_REGISTER_P)
+#define GET_SAVED_REGISTER_P() (0)
+#endif
+
+extern int gdbarch_get_saved_register_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_SAVED_REGISTER_P)
+#error "Non multi-arch definition of GET_SAVED_REGISTER"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_SAVED_REGISTER_P)
+#define GET_SAVED_REGISTER_P() (gdbarch_get_saved_register_p (current_gdbarch))
+#endif
+
/* Default (function) for non- multi-arch platforms. */
#if (!GDB_MULTI_ARCH) && !defined (GET_SAVED_REGISTER)
-#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (generic_unwind_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval))
+#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) (internal_error (__FILE__, __LINE__, "GET_SAVED_REGISTER"), 0)
#endif
typedef void (gdbarch_get_saved_register_ftype) (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval);
v:2:BELIEVE_PCC_PROMOTION:int:believe_pcc_promotion:::::::
v:2:BELIEVE_PCC_PROMOTION_TYPE:int:believe_pcc_promotion_type:::::::
f:2:COERCE_FLOAT_TO_DOUBLE:int:coerce_float_to_double:struct type *formal, struct type *actual:formal, actual:::default_coerce_float_to_double::0
-f:2:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval:::generic_unwind_get_saved_register::0
+F:2:GET_SAVED_REGISTER:void:get_saved_register:char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval:raw_buffer, optimized, addrp, frame, regnum, lval
#
f:2:REGISTER_CONVERTIBLE:int:register_convertible:int nr:nr:::generic_register_convertible_not::0
f:2:REGISTER_CONVERT_TO_VIRTUAL:void:register_convert_to_virtual:int regnum, struct type *type, char *from, char *to:regnum, type, from, to:::0::0