* sparc-linux-tdep.c (sparc32_linux_init_abi): Append
[deliverable/binutils-gdb.git] / gdb / alpha-tdep.c
index 142bc32da85cd1afb752cc16065da7903a4d2133..960b0514907182c5468393fdf39db596e04ffe2c 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
 
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
    2002, 2003, 2005 Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "doublest.h"
@@ -212,7 +212,7 @@ alpha_convert_register_p (int regno, struct type *type)
 
 static void
 alpha_register_to_value (struct frame_info *frame, int regnum,
-                        struct type *valtype, void *out)
+                        struct type *valtype, gdb_byte *out)
 {
   char in[MAX_REGISTER_SIZE];
   frame_register_read (frame, regnum, in);
@@ -231,7 +231,7 @@ alpha_register_to_value (struct frame_info *frame, int regnum,
 
 static void
 alpha_value_to_register (struct frame_info *frame, int regnum,
-                        struct type *valtype, const void *in)
+                        struct type *valtype, const gdb_byte *in)
 {
   char out[MAX_REGISTER_SIZE];
   switch (TYPE_LENGTH (valtype))
@@ -439,7 +439,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 static void
 alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
-                           void *valbuf)
+                           gdb_byte *valbuf)
 {
   int length = TYPE_LENGTH (valtype);
   char raw_buffer[ALPHA_REGISTER_SIZE];
@@ -517,7 +517,7 @@ alpha_extract_struct_value_address (struct regcache *regcache)
 
 static void
 alpha_store_return_value (struct type *valtype, struct regcache *regcache,
-                         const void *valbuf)
+                         const gdb_byte *valbuf)
 {
   int length = TYPE_LENGTH (valtype);
   char raw_buffer[ALPHA_REGISTER_SIZE];
@@ -821,7 +821,7 @@ alpha_sigtramp_frame_prev_register (struct frame_info *next_frame,
                                    void **this_prologue_cache,
                                    int regnum, int *optimizedp,
                                    enum lval_type *lvalp, CORE_ADDR *addrp,
-                                   int *realnump, void *bufferp)
+                                   int *realnump, gdb_byte *bufferp)
 {
   struct alpha_sigtramp_unwind_cache *info
     = alpha_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
@@ -1163,7 +1163,7 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
                                     void **this_prologue_cache,
                                     int regnum, int *optimizedp,
                                     enum lval_type *lvalp, CORE_ADDR *addrp,
-                                    int *realnump, void *bufferp)
+                                    int *realnump, gdb_byte *bufferp)
 {
   struct alpha_heuristic_unwind_cache *info
     = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
@@ -1335,6 +1335,30 @@ alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr)
 }
 
 \f
+
+/* Return nonzero if the G_floating register value in REG is equal to
+   zero for FP control instructions.  */
+   
+static int
+fp_register_zero_p (LONGEST reg)
+{
+  /* Check that all bits except the sign bit are zero.  */
+  const LONGEST zero_mask = ((LONGEST) 1 << 63) ^ -1;
+
+  return ((reg & zero_mask) == 0);
+}
+
+/* Return the value of the sign bit for the G_floating register
+   value held in REG.  */
+
+static int
+fp_register_sign_bit (LONGEST reg)
+{
+  const LONGEST sign_mask = (LONGEST) 1 << 63;
+
+  return ((reg & sign_mask) != 0);
+}
+
 /* alpha_software_single_step() is called just before we want to resume
    the inferior, if we want to single-step it but there is no hardware
    or kernel single-step support (NetBSD on Alpha, for example).  We find
@@ -1348,8 +1372,10 @@ alpha_next_pc (CORE_ADDR pc)
 {
   unsigned int insn;
   unsigned int op;
+  int regno;
   int offset;
   LONGEST rav;
+  char reg[8];
 
   insn = alpha_read_insn (pc);
 
@@ -1379,7 +1405,21 @@ alpha_next_pc (CORE_ADDR pc)
        }
 
       /* Need to determine if branch is taken; read RA.  */
-      rav = (LONGEST) read_register ((insn >> 21) & 0x1f);
+      regno = (insn >> 21) & 0x1f;
+      switch (op)
+        {
+          case 0x31:              /* FBEQ */
+          case 0x36:              /* FBGE */
+          case 0x37:              /* FBGT */
+          case 0x33:              /* FBLE */
+          case 0x32:              /* FBLT */
+          case 0x35:              /* FBNE */
+            regno += FP0_REGNUM;
+       }
+      
+      regcache_cooked_read (current_regcache, regno, reg);
+      rav = extract_signed_integer (reg, 8);
+
       switch (op)
        {
        case 0x38:              /* BLBC */
@@ -1415,7 +1455,32 @@ alpha_next_pc (CORE_ADDR pc)
            goto branch_taken;
          break;
 
-       /* ??? Missing floating-point branches.  */
+        /* Floating point branches.  */
+        
+        case 0x31:              /* FBEQ */
+          if (fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
+        case 0x36:              /* FBGE */
+          if (fp_register_sign_bit (rav) == 0 || fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
+        case 0x37:              /* FBGT */
+          if (fp_register_sign_bit (rav) == 0 && ! fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
+        case 0x33:              /* FBLE */
+          if (fp_register_sign_bit (rav) == 1 || fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
+        case 0x32:              /* FBLT */
+          if (fp_register_sign_bit (rav) == 1 && ! fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
+        case 0x35:              /* FBNE */
+          if (! fp_register_zero_p (rav))
+            goto branch_taken;
+          break;
        }
     }
 
@@ -1544,6 +1609,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
   set_gdbarch_decr_pc_after_break (gdbarch, 4);
+  set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
@@ -1586,16 +1652,13 @@ _initialize_alpha_tdep (void)
   /* We need to throw away the frame cache when we set this, since it
      might change our ability to get backtraces.  */
   add_setshow_zinteger_cmd ("heuristic-fence-post", class_support,
-                           &heuristic_fence_post,
-                           _("\
-Set the distance searched for the start of a function."),
-                           _("\
-Show the distance searched for the start of a function."),
-                           _("\
+                           &heuristic_fence_post, _("\
+Set the distance searched for the start of a function."), _("\
+Show the distance searched for the start of a function."), _("\
 If you are debugging a stripped executable, GDB needs to search through the\n\
 program for the start of a function.  This command sets the distance of the\n\
 search.  The only need to set it is when debugging a stripped executable."),
-                           NULL, /* PRINT: The distance searched for the start of a function is \"%d\".  */
-                           reinit_frame_cache_sfunc, NULL,
+                           reinit_frame_cache_sfunc,
+                           NULL, /* FIXME: i18n: The distance searched for the start of a function is \"%d\".  */
                            &setlist, &showlist);
 }
This page took 0.025956 seconds and 4 git commands to generate.