* configure.tgt: Mark v850 as multi-arched.
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index 3806be2956855027ce057a5af49bec7ffce221f5..3890fc2f77315ab5ea05b30b3f4e1466f5da82c8 100644 (file)
@@ -1,6 +1,7 @@
 /* Target-dependent code for the HP PA architecture, for GDB.
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
    University of Utah (pa-gdb-bugs@cs.utah.edu).
@@ -28,6 +29,7 @@
 #include "inferior.h"
 #include "value.h"
 #include "regcache.h"
+#include "completer.h"
 
 /* For argument passing to the inferior */
 #include "symtab.h"
@@ -631,7 +633,8 @@ pc_in_interrupt_handler (CORE_ADDR pc)
      its frame isn't a pure interrupt frame.  Deal with this.  */
   msym_us = lookup_minimal_symbol_by_pc (pc);
 
-  return u->HP_UX_interrupt_marker && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us));
+  return (u->HP_UX_interrupt_marker
+         && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)));
 }
 
 /* Called when no unwind descriptor was found for PC.  Returns 1 if it
@@ -746,8 +749,10 @@ find_proc_framesize (CORE_ADDR pc)
 
   /* If Save_SP is set, and we're not in an interrupt or signal caller,
      then we have a frame pointer.  Use it.  */
-  if (u->Save_SP && !pc_in_interrupt_handler (pc)
-      && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
+  if (u->Save_SP
+      && !pc_in_interrupt_handler (pc)
+      && msym_us
+      && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
     return -1;
 
   return u->Total_frame_size << 3;
@@ -1815,7 +1820,8 @@ hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
         target.  */
       bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
 
-      offset[i] = cum_bytes_reserved + lengths[i];
+      offset[i] = (cum_bytes_reserved
+                  + (lengths[i] > 4 ? bytes_reserved : lengths[i]));
 
       /* If the argument is a double word argument, then it needs to be
         double word aligned.  */
@@ -2484,7 +2490,7 @@ pa_do_registers_info (int regnum, int fpregs)
   /* Make a copy of gdb's save area (may cause actual
      reads from the target). */
   for (i = 0; i < NUM_REGS; i++)
-    read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
+    frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_print_registers (raw_regs, regnum, fpregs);
@@ -2528,7 +2534,7 @@ pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
   /* Make a copy of gdb's save area (may cause actual
      reads from the target). */
   for (i = 0; i < NUM_REGS; i++)
-    read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
+    frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_strcat_registers (raw_regs, regnum, fpregs, stream);
@@ -2780,7 +2786,7 @@ pa_print_fp_reg (int i)
   char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2798,7 +2804,7 @@ pa_print_fp_reg (int i)
   if ((i % 2) == 0)
     {
       /* Get the data in raw format for the 2nd half.  */
-      read_relative_register_raw_bytes (i + 1, raw_buffer);
+      frame_register_read (selected_frame, i + 1, raw_buffer);
 
       /* Copy it into the appropriate part of the virtual buffer.  */
       memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buffer,
@@ -2826,7 +2832,7 @@ pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
   print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), stream);
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2837,7 +2843,7 @@ pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
       char raw_buf[MAX_REGISTER_RAW_SIZE];
 
       /* Get the data in raw format for the 2nd half.  */
-      read_relative_register_raw_bytes (i + 1, raw_buf);
+      frame_register_read (selected_frame, i + 1, raw_buf);
 
       /* Copy it into the appropriate part of the virtual buffer.  */
       memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buf, REGISTER_RAW_SIZE (i));
@@ -4459,7 +4465,7 @@ child_get_current_exception_event (void)
   if (level != 0)
     return (struct exception_event_record *) NULL;
 
-  select_frame (fi, -1);
+  select_frame (fi);
 
   /* Read in the arguments */
   /* __d_eh_notify_callback() is called with 3 arguments:
@@ -4485,11 +4491,11 @@ child_get_current_exception_event (void)
   if (level != 0)
     return (struct exception_event_record *) NULL;
 
-  select_frame (fi, -1);
+  select_frame (fi);
   throw_addr = fi->pc;
 
   /* Go back to original (top) frame */
-  select_frame (curr_frame, -1);
+  select_frame (curr_frame);
 
   current_ex_event.kind = (enum exception_event_kind) event_kind;
   current_ex_event.throw_sal = find_pc_line (throw_addr, 1);
@@ -4674,9 +4680,94 @@ hppa_skip_permanent_breakpoint (void)
 void
 _initialize_hppa_tdep (void)
 {
+  struct cmd_list_element *c;
+  void break_at_finish_command (char *arg, int from_tty);
+  void tbreak_at_finish_command (char *arg, int from_tty);
+  void break_at_finish_at_depth_command (char *arg, int from_tty);
+
   tm_print_insn = print_insn_hppa;
 
   add_cmd ("unwind", class_maintenance, unwind_command,
           "Print unwind table entry at given address.",
           &maintenanceprintlist);
+
+  deprecate_cmd (add_com ("xbreak", class_breakpoint, 
+                         break_at_finish_command,
+                         concat ("Set breakpoint at procedure exit. \n\
+Argument may be function name, or \"*\" and an address.\n\
+If function is specified, break at end of code for that function.\n\
+If an address is specified, break at the end of the function that contains \n\
+that exact address.\n",
+                  "With no arg, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL)), NULL);
+  deprecate_cmd (add_com_alias ("xb", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbr", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbre", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbrea", "xbreak", class_breakpoint, 1), NULL);
+
+  deprecate_cmd (c = add_com ("txbreak", class_breakpoint, 
+                             tbreak_at_finish_command,
+"Set temporary breakpoint at procedure exit.  Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+  set_cmd_completer (c, location_completer);
+  
+  if (xdb_commands)
+    deprecate_cmd (add_com ("bx", class_breakpoint, 
+                           break_at_finish_at_depth_command,
+"Set breakpoint at procedure exit.  Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+}
+
+/* Copy the function value from VALBUF into the proper location
+   for a function return.
+
+   Called only in the context of the "return" command.  */
+
+void
+hppa_store_return_value (struct type *type, char *valbuf)
+{
+  /* For software floating point, the return value goes into the
+     integer registers.  But we do not have any flag to key this on,
+     so we always store the value into the integer registers.
+
+     If its a float value, then we also store it into the floating
+     point registers.  */
+  write_register_bytes (REGISTER_BYTE (28)
+                       + (TYPE_LENGTH (type) > 4
+                          ? (8 - TYPE_LENGTH (type))
+                          : (4 - TYPE_LENGTH (type))),
+                       valbuf,
+                       TYPE_LENGTH (type));
+  if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+    write_register_bytes (REGISTER_BYTE (FP4_REGNUM),
+                         valbuf,
+                         TYPE_LENGTH (type));
+}
+
+/* Copy the function's return value into VALBUF.
+
+   This function is called only in the context of "target function calls",
+   ie. when the debugger forces a function to be called in the child, and
+   when the debugger forces a fucntion to return prematurely via the
+   "return" command.  */
+
+void
+hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+  if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+    memcpy (valbuf,
+           (char *)regbuf + REGISTER_BYTE (FP4_REGNUM),
+           TYPE_LENGTH (type));
+  else
+    memcpy (valbuf,
+           ((char *)regbuf
+            + REGISTER_BYTE (28)
+            + (TYPE_LENGTH (type) > 4
+               ? (8 - TYPE_LENGTH (type))
+               : (4 - TYPE_LENGTH (type)))),
+           TYPE_LENGTH (type));
 }
This page took 0.028012 seconds and 4 git commands to generate.