*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / alpha-tdep.c
index 9e69eda07146ead837c8f1726703083b76bd67d6..d75aebc3451d0f456d4e3b18f6ff06fe66baee7d 100644 (file)
@@ -24,6 +24,7 @@
 #include "frame.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
+#include "dwarf2-frame.h"
 #include "inferior.h"
 #include "symtab.h"
 #include "value.h"
 #include "arch-utils.h"
 #include "osabi.h"
 #include "block.h"
+#include "infcall.h"
 
 #include "elf-bfd.h"
 
 #include "alpha-tdep.h"
 
 \f
+/* Return the name of the REGNO register.
+
+   An empty name corresponds to a register number that used to
+   be used for a virtual register. That virtual register has
+   been removed, but the index is still reserved to maintain
+   compatibility with existing remote alpha targets.  */
+
 static const char *
 alpha_register_name (int regno)
 {
@@ -71,23 +80,19 @@ alpha_register_name (int regno)
 static int
 alpha_cannot_fetch_register (int regno)
 {
-  return regno == ALPHA_ZERO_REGNUM;
+  return (regno == ALPHA_ZERO_REGNUM
+          || strlen (alpha_register_name (regno)) == 0);
 }
 
 static int
 alpha_cannot_store_register (int regno)
 {
-  return regno == ALPHA_ZERO_REGNUM;
-}
-
-static int
-alpha_register_convertible (int regno)
-{
-  return (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31);
+  return (regno == ALPHA_ZERO_REGNUM
+          || strlen (alpha_register_name (regno)) == 0);
 }
 
 static struct type *
-alpha_register_virtual_type (int regno)
+alpha_register_type (struct gdbarch *gdbarch, int regno)
 {
   if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM)
     return builtin_type_void_data_ptr;
@@ -96,7 +101,7 @@ alpha_register_virtual_type (int regno)
 
   /* Don't need to worry about little vs big endian until 
      some jerk tries to port to alpha-unicosmk.  */
-  if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 31)
+  if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31)
     return builtin_type_ieee_double_little;
 
   return builtin_type_int64;
@@ -113,10 +118,18 @@ alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   if (REGISTER_NAME (regnum) == NULL || *REGISTER_NAME (regnum) == '\0')
     return 0;
 
-  /* Since we implement no pseudo registers, save/restore is equal to all. */
-  if (group == all_reggroup
-      || group == save_reggroup
-      || group == restore_reggroup)
+  if (group == all_reggroup)
+    return 1;
+
+  /* Zero should not be saved or restored.  Technically it is a general
+     register (just as $f31 would be a float if we represented it), but
+     there's no point displaying it during "info regs", so leave it out
+     of all groups except for "all".  */
+  if (regnum == ALPHA_ZERO_REGNUM)
+    return 0;
+
+  /* All other registers are saved and restored.  */
+  if (group == save_reggroup || group == restore_reggroup)
     return 1;
 
   /* All other groups are non-overlapping.  */
@@ -141,16 +154,47 @@ alpha_register_byte (int regno)
   return (regno * 8);
 }
 
-static int
-alpha_register_raw_size (int regno)
+/* The following represents exactly the conversion performed by
+   the LDS instruction.  This applies to both single-precision
+   floating point and 32-bit integers.  */
+
+static void
+alpha_lds (void *out, const void *in)
 {
-  return 8;
+  ULONGEST mem     = extract_unsigned_integer (in, 4);
+  ULONGEST frac    = (mem >>  0) & 0x7fffff;
+  ULONGEST sign    = (mem >> 31) & 1;
+  ULONGEST exp_msb = (mem >> 30) & 1;
+  ULONGEST exp_low = (mem >> 23) & 0x7f;
+  ULONGEST exp, reg;
+
+  exp = (exp_msb << 10) | exp_low;
+  if (exp_msb)
+    {
+      if (exp_low == 0x7f)
+       exp = 0x7ff;
+    }
+  else
+    {
+      if (exp_low != 0x00)
+       exp |= 0x380;
+    }
+
+  reg = (sign << 63) | (exp << 52) | (frac << 29);
+  store_unsigned_integer (out, 8, reg);
 }
 
-static int
-alpha_register_virtual_size (int regno)
+/* Similarly, this represents exactly the conversion performed by
+   the STS instruction.  */
+
+static void
+alpha_sts (void *out, const void *in)
 {
-  return 8;
+  ULONGEST reg, mem;
+
+  reg = extract_unsigned_integer (in, 8);
+  mem = ((reg >> 32) & 0xc0000000) | ((reg >> 29) & 0x3fffffff);
+  store_unsigned_integer (out, 4, mem);
 }
 
 /* The alpha needs a conversion between register and memory format if the
@@ -159,67 +203,48 @@ alpha_register_virtual_size (int regno)
    bytes or less, as the representation of integers in floating point
    registers is different. */
 
-static void
-alpha_convert_flt_dbl (void *out, const void *in)
-{
-  DOUBLEST d = extract_typed_floating (in, builtin_type_ieee_single_little);
-  store_typed_floating (out, builtin_type_ieee_double_little, d);
-}
-
-static void
-alpha_convert_dbl_flt (void *out, const void *in)
+static int
+alpha_convert_register_p (int regno, struct type *type)
 {
-  DOUBLEST d = extract_typed_floating (in, builtin_type_ieee_double_little);
-  store_typed_floating (out, builtin_type_ieee_single_little, d);
+  return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
 }
 
 static void
-alpha_register_convert_to_virtual (int regnum, struct type *valtype,
-                                  char *raw_buffer, char *virtual_buffer)
+alpha_register_to_value (struct frame_info *frame, int regnum,
+                        struct type *valtype, void *out)
 {
-  if (TYPE_LENGTH (valtype) >= ALPHA_REGISTER_SIZE)
+  char in[MAX_REGISTER_SIZE];
+  frame_register_read (frame, regnum, in);
+  switch (TYPE_LENGTH (valtype))
     {
-      memcpy (virtual_buffer, raw_buffer, ALPHA_REGISTER_SIZE);
-      return;
-    }
-
-  /* Note that everything below is less than 8 bytes long.  */
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    alpha_convert_dbl_flt (virtual_buffer, raw_buffer);
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT)
-    {
-      ULONGEST l;
-      l = extract_unsigned_integer (raw_buffer, ALPHA_REGISTER_SIZE);
-      l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
-      store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
+    case 4:
+      alpha_sts (out, in);
+      break;
+    case 8:
+      memcpy (out, in, 8);
+      break;
+    default:
+      error (_("Cannot retrieve value from floating point register"));
     }
-  else
-    error ("Cannot retrieve value from floating point register");
 }
 
 static void
-alpha_register_convert_to_raw (struct type *valtype, int regnum,
-                              char *virtual_buffer, char *raw_buffer)
+alpha_value_to_register (struct frame_info *frame, int regnum,
+                        struct type *valtype, const void *in)
 {
-  if (TYPE_LENGTH (valtype) >= ALPHA_REGISTER_SIZE)
+  char out[MAX_REGISTER_SIZE];
+  switch (TYPE_LENGTH (valtype))
     {
-      memcpy (raw_buffer, virtual_buffer, ALPHA_REGISTER_SIZE);
-      return;
-    }
-
-  /* Note that everything below is less than 8 bytes long.  */
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    alpha_convert_flt_dbl (raw_buffer, virtual_buffer);
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT)
-    {
-      ULONGEST l = unpack_long (valtype, virtual_buffer);
-      l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
-      store_unsigned_integer (raw_buffer, ALPHA_REGISTER_SIZE, l);
+    case 4:
+      alpha_lds (out, in);
+      break;
+    case 8:
+      memcpy (out, in, 8);
+      break;
+    default:
+      error (_("Cannot store value in floating point register"));
     }
-  else
-    error ("Cannot store value in floating point register");
+  put_frame_register (frame, regnum, out);
 }
 
 \f
@@ -236,7 +261,7 @@ alpha_register_convert_to_raw (struct type *valtype, int regnum,
    structure to be returned is passed as a hidden first argument.  */
 
 static CORE_ADDR
-alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                       struct regcache *regcache, CORE_ADDR bp_addr,
                       int nargs, struct value **args, CORE_ADDR sp,
                       int struct_return, CORE_ADDR struct_addr)
@@ -251,9 +276,10 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
     };
   struct alpha_arg *alpha_args
     = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
-  register struct alpha_arg *m_arg;
+  struct alpha_arg *m_arg;
   char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS];
   int required_arg_regs;
+  CORE_ADDR func_addr = find_function_addr (function, NULL);
 
   /* The ABI places the address of the called function in T12.  */
   regcache_cooked_write_signed (regcache, ALPHA_T12_REGNUM, func_addr);
@@ -266,7 +292,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   for (i = 0, m_arg = alpha_args; i < nargs; i++, m_arg++)
     {
       struct value *arg = args[i];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+      struct type *arg_type = check_typedef (value_type (arg));
 
       /* Cast argument to long if necessary as the compiler does it too.  */
       switch (TYPE_CODE (arg_type))
@@ -425,7 +451,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
        {
        case 4:
          regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
-         alpha_convert_dbl_flt (valbuf, raw_buffer);
+         alpha_sts (valbuf, raw_buffer);
          break;
 
        case 8:
@@ -438,7 +464,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
          break;
 
        default:
-         internal_error (__FILE__, __LINE__, "unknown floating point width");
+         internal_error (__FILE__, __LINE__, _("unknown floating point width"));
        }
       break;
 
@@ -462,7 +488,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
          break;
 
        default:
-         internal_error (__FILE__, __LINE__, "unknown floating point width");
+         internal_error (__FILE__, __LINE__, _("unknown floating point width"));
        }
       break;
 
@@ -502,9 +528,9 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
       switch (length)
        {
        case 4:
-         alpha_convert_flt_dbl (raw_buffer, valbuf);
-         valbuf = raw_buffer;
-         /* FALLTHRU */
+         alpha_lds (raw_buffer, valbuf);
+         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, raw_buffer);
+         break;
 
        case 8:
          regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
@@ -514,10 +540,10 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
          /* FIXME: 128-bit long doubles are returned like structures:
             by writing into indirect storage provided by the caller
             as the first argument.  */
-         error ("Cannot set a 128-bit long double return value.");
+         error (_("Cannot set a 128-bit long double return value."));
 
        default:
-         internal_error (__FILE__, __LINE__, "unknown floating point width");
+         internal_error (__FILE__, __LINE__, _("unknown floating point width"));
        }
       break;
 
@@ -539,10 +565,10 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
          /* FIXME: 128-bit long doubles are returned like structures:
             by writing into indirect storage provided by the caller
             as the first argument.  */
-         error ("Cannot set a 128-bit long double return value.");
+         error (_("Cannot set a 128-bit long double return value."));
 
        default:
-         internal_error (__FILE__, __LINE__, "unknown floating point width");
+         internal_error (__FILE__, __LINE__, _("unknown floating point width"));
        }
       break;
 
@@ -558,13 +584,6 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
     }
 }
 
-static int
-alpha_use_struct_convention (int gcc_p, struct type *type)
-{
-  /* Structures are returned by ref in extra arg0.  */
-  return 1;
-}
-
 \f
 static const unsigned char *
 alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
@@ -606,7 +625,7 @@ alpha_read_insn (CORE_ADDR pc)
   char buf[4];
   int status;
 
-  status = read_memory_nobpt (pc, buf, 4);
+  status = deprecated_read_memory_nobpt (pc, buf, 4);
   if (status)
     memory_error (status, pc);
   return extract_unsigned_integer (buf, 4);
@@ -733,24 +752,20 @@ alpha_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
   return info;
 }
 
-/* Return the address of REGNO in a sigtramp frame.  Since this is all
-   arithmetic, it doesn't seem worthwhile to cache it.  */
-
-#ifndef SIGFRAME_PC_OFF
-#define SIGFRAME_PC_OFF                (2 * 8)
-#define SIGFRAME_REGSAVE_OFF   (4 * 8)
-#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
-#endif
+/* Return the address of REGNUM in a sigtramp frame.  Since this is
+   all arithmetic, it doesn't seem worthwhile to cache it.  */
 
 static CORE_ADDR
-alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, unsigned int regno)
+alpha_sigtramp_register_address (CORE_ADDR sigcontext_addr, int regnum)
 { 
-  if (regno < 32)
-    return sigcontext_addr + SIGFRAME_REGSAVE_OFF + regno * 8;
-  if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
-    return sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + regno * 8;
-  if (regno == PC_REGNUM)
-    return sigcontext_addr + SIGFRAME_PC_OFF; 
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (regnum >= 0 && regnum < 32)
+    return sigcontext_addr + tdep->sc_regs_offset + regnum * 8;
+  else if (regnum >= ALPHA_FP0_REGNUM && regnum < ALPHA_FP0_REGNUM + 32)
+    return sigcontext_addr + tdep->sc_fpregs_offset + regnum * 8;
+  else if (regnum == ALPHA_PC_REGNUM)
+    return sigcontext_addr + tdep->sc_pc_offset; 
 
   return 0;
 }
@@ -792,7 +807,8 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
   /* The stack address is trivially read from the sigcontext.  */
   stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr,
                                                ALPHA_SP_REGNUM);
-  stack_addr = read_memory_unsigned_integer (stack_addr, ALPHA_REGISTER_SIZE);
+  stack_addr = get_frame_memory_unsigned (next_frame, stack_addr,
+                                         ALPHA_REGISTER_SIZE);
 
   *this_id = frame_id_build (stack_addr, code_addr);
 }
@@ -821,7 +837,7 @@ alpha_sigtramp_frame_prev_register (struct frame_info *next_frame,
          *addrp = addr;
          *realnump = -1;
          if (bufferp != NULL)
-           read_memory (addr, bufferp, ALPHA_REGISTER_SIZE);
+           get_frame_memory (next_frame, addr, bufferp, ALPHA_REGISTER_SIZE);
          return;
        }
     }
@@ -841,18 +857,25 @@ static const struct frame_unwind alpha_sigtramp_frame_unwind = {
 };
 
 static const struct frame_unwind *
-alpha_sigtramp_frame_p (CORE_ADDR pc)
+alpha_sigtramp_frame_sniffer (struct frame_info *next_frame)
 {
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
   char *name;
 
-  /* We shouldn't even bother to try if the OSABI didn't register
-     a sigcontext_addr handler.  */
-  if (!gdbarch_tdep (current_gdbarch)->sigcontext_addr)
+  /* NOTE: cagney/2004-04-30: Do not copy/clone this code.  Instead
+     look at tramp-frame.h and other simplier per-architecture
+     sigtramp unwinders.  */
+
+  /* We shouldn't even bother to try if the OSABI didn't register a
+     sigcontext_addr handler or pc_in_sigtramp hander.  */
+  if (gdbarch_tdep (current_gdbarch)->sigcontext_addr == NULL)
+    return NULL;
+  if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp == NULL)
     return NULL;
 
   /* Otherwise we should be in a signal frame.  */
   find_pc_partial_function (pc, &name, NULL, NULL);
-  if (PC_IN_SIGTRAMP (pc, name))
+  if (gdbarch_tdep (current_gdbarch)->pc_in_sigtramp (pc, name))
     return &alpha_sigtramp_frame_unwind;
 
   return NULL;
@@ -932,20 +955,21 @@ alpha_heuristic_proc_start (CORE_ADDR pc)
       static int blurb_printed = 0;
 
       if (fence == tdep->vm_min_address)
-       warning ("Hit beginning of text section without finding");
+       warning (_("Hit beginning of text section without finding \
+enclosing function for address 0x%s"), paddr_nz (orig_pc));
       else
-       warning ("Hit heuristic-fence-post without finding");
-      warning ("enclosing function for address 0x%s", paddr_nz (orig_pc));
+       warning (_("Hit heuristic-fence-post without finding \
+enclosing function for address 0x%s"), paddr_nz (orig_pc));
 
       if (!blurb_printed)
        {
-         printf_filtered ("\
+         printf_filtered (_("\
 This warning occurs if you are debugging a function without any symbols\n\
 (for example, in a stripped executable).  In that case, you may wish to\n\
 increase the size of the search with the `set heuristic-fence-post' command.\n\
 \n\
 Otherwise, you told GDB there was a function where there isn't one, or\n\
-(more likely) you have encountered a bug in GDB.\n");
+(more likely) you have encountered a bug in GDB.\n"));
          blurb_printed = 1;
        }
     }
@@ -1011,6 +1035,16 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
            {
              reg = (word & 0x03e00000) >> 21;
 
+              /* Ignore this instruction if we have already encountered
+                 an instruction saving the same register earlier in the
+                 function code.  The current instruction does not tell
+                 us where the original value upon function entry is saved.
+                 All it says is that the function we are scanning reused
+                 that register for some computation of its own, and is now
+                 saving its result.  */
+              if (info->saved_regs[reg])
+                continue;
+
              if (reg == 31)
                continue;
 
@@ -1118,11 +1152,6 @@ alpha_heuristic_frame_this_id (struct frame_info *next_frame,
   struct alpha_heuristic_unwind_cache *info
     = alpha_heuristic_frame_unwind_cache (next_frame, this_prologue_cache, 0);
 
-  /* This is meant to halt the backtrace at "_start".  Make sure we
-     don't halt it at a generic dummy frame. */
-  if (inside_entry_file (info->start_pc))
-    return;
-
   *this_id = frame_id_build (info->vfp, info->start_pc);
 }
 
@@ -1153,7 +1182,7 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
       *addrp = info->saved_regs[regnum];
       *realnump = -1;
       if (bufferp != NULL)
-       read_memory (*addrp, bufferp, ALPHA_REGISTER_SIZE);
+       get_frame_memory (next_frame, *addrp, bufferp, ALPHA_REGISTER_SIZE);
       return;
     }
 
@@ -1171,8 +1200,8 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
     }
 
   /* Otherwise assume the next frame has the same register value.  */
-  frame_register (next_frame, regnum, optimizedp, lvalp, addrp,
-                 realnump, bufferp);
+  frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp,
+                         realnump, bufferp);
 }
 
 static const struct frame_unwind alpha_heuristic_frame_unwind = {
@@ -1182,7 +1211,7 @@ static const struct frame_unwind alpha_heuristic_frame_unwind = {
 };
 
 static const struct frame_unwind *
-alpha_heuristic_frame_p (CORE_ADDR pc)
+alpha_heuristic_frame_sniffer (struct frame_info *next_frame)
 {
   return &alpha_heuristic_frame_unwind;
 }
@@ -1214,30 +1243,6 @@ reinit_frame_cache_sfunc (char *args, int from_tty, struct cmd_list_element *c)
 }
 
 \f
-/* ALPHA stack frames are almost impenetrable.  When execution stops,
-   we basically have to look at symbol information for the function
-   that we stopped in, which tells us *which* register (if any) is
-   the base of the frame pointer, and what offset from that register
-   the frame itself is at.  
-
-   This presents a problem when trying to examine a stack in memory
-   (that isn't executing at the moment), using the "frame" command.  We
-   don't have a PC, nor do we have any registers except SP.
-
-   This routine takes two arguments, SP and PC, and tries to make the
-   cached frames look as if these two arguments defined a frame on the
-   cache.  This allows the rest of info frame to extract the important
-   arguments without difficulty.  */
-
-struct frame_info *
-alpha_setup_arbitrary_frame (int argc, CORE_ADDR *argv)
-{
-  if (argc != 2)
-    error ("ALPHA frame specifications require two arguments: sp and pc");
-
-  return create_new_frame (argv[0], argv[1]);
-}
-
 /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
    dummy frame.  The frame ID's base needs to match the TOS value
    saved by save_dummy_frame_tos(), and the PC match the dummy frame's
@@ -1259,6 +1264,75 @@ alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return pc;
 }
 
+\f
+/* Helper routines for alpha*-nat.c files to move register sets to and
+   from core files.  The UNIQUE pointer is allowed to be NULL, as most
+   targets don't supply this value in their core files.  */
+
+void
+alpha_supply_int_regs (int regno, const void *r0_r30,
+                      const void *pc, const void *unique)
+{
+  int i;
+
+  for (i = 0; i < 31; ++i)
+    if (regno == i || regno == -1)
+      regcache_raw_supply (current_regcache, i, (const char *)r0_r30 + i*8);
+
+  if (regno == ALPHA_ZERO_REGNUM || regno == -1)
+    regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL);
+
+  if (regno == ALPHA_PC_REGNUM || regno == -1)
+    regcache_raw_supply (current_regcache, ALPHA_PC_REGNUM, pc);
+
+  if (regno == ALPHA_UNIQUE_REGNUM || regno == -1)
+    regcache_raw_supply (current_regcache, ALPHA_UNIQUE_REGNUM, unique);
+}
+
+void
+alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique)
+{
+  int i;
+
+  for (i = 0; i < 31; ++i)
+    if (regno == i || regno == -1)
+      regcache_raw_collect (current_regcache, i, (char *)r0_r30 + i*8);
+
+  if (regno == ALPHA_PC_REGNUM || regno == -1)
+    regcache_raw_collect (current_regcache, ALPHA_PC_REGNUM, pc);
+
+  if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1))
+    regcache_raw_collect (current_regcache, ALPHA_UNIQUE_REGNUM, unique);
+}
+
+void
+alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr)
+{
+  int i;
+
+  for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
+    if (regno == i || regno == -1)
+      regcache_raw_supply (current_regcache, i,
+                          (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+    regcache_raw_supply (current_regcache, ALPHA_FPCR_REGNUM, fpcr);
+}
+
+void
+alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr)
+{
+  int i;
+
+  for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; ++i)
+    if (regno == i || regno == -1)
+      regcache_raw_collect (current_regcache, i,
+                           (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+    regcache_raw_collect (current_regcache, ALPHA_FPCR_REGNUM, fpcr);
+}
+
 \f
 /* 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
@@ -1276,7 +1350,7 @@ alpha_next_pc (CORE_ADDR pc)
   int offset;
   LONGEST rav;
 
-  insn = read_memory_unsigned_integer (pc, sizeof (insn));
+  insn = alpha_read_insn (pc);
 
   /* Opcode is top 6 bits. */
   op = (insn >> 26) & 0x3f;
@@ -1403,10 +1477,13 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Lowest text address.  This is used by heuristic_proc_start()
      to decide when to stop looking.  */
-  tdep->vm_min_address = (CORE_ADDR) 0x120000000;
+  tdep->vm_min_address = (CORE_ADDR) 0x120000000LL;
 
   tdep->dynamic_sigtramp_offset = NULL;
   tdep->sigcontext_addr = NULL;
+  tdep->sc_pc_offset = 2 * 8;
+  tdep->sc_regs_offset = 4 * 8;
+  tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8;
 
   tdep->jb_pc = -1;    /* longjmp support not enabled by default  */
 
@@ -1427,18 +1504,15 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_fp0_regnum (gdbarch, ALPHA_FP0_REGNUM);
 
   set_gdbarch_register_name (gdbarch, alpha_register_name);
-  set_gdbarch_register_byte (gdbarch, alpha_register_byte);
-  set_gdbarch_register_raw_size (gdbarch, alpha_register_raw_size);
-  set_gdbarch_register_virtual_size (gdbarch, alpha_register_virtual_size);
-  set_gdbarch_register_virtual_type (gdbarch, alpha_register_virtual_type);
+  set_gdbarch_deprecated_register_byte (gdbarch, alpha_register_byte);
+  set_gdbarch_register_type (gdbarch, alpha_register_type);
 
   set_gdbarch_cannot_fetch_register (gdbarch, alpha_cannot_fetch_register);
   set_gdbarch_cannot_store_register (gdbarch, alpha_cannot_store_register);
 
-  set_gdbarch_register_convertible (gdbarch, alpha_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch,
-                                           alpha_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch, alpha_register_convert_to_raw);
+  set_gdbarch_convert_register_p (gdbarch, alpha_convert_register_p);
+  set_gdbarch_register_to_value (gdbarch, alpha_register_to_value);
+  set_gdbarch_value_to_register (gdbarch, alpha_value_to_register);
 
   set_gdbarch_register_reggroup_p (gdbarch, alpha_register_reggroup_p);
 
@@ -1449,22 +1523,17 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_print_insn (gdbarch, print_insn_alpha);
 
   /* Call info.  */
-  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
-  set_gdbarch_frameless_function_invocation (gdbarch,
-                                    generic_frameless_function_invocation_not);
 
-  set_gdbarch_use_struct_convention (gdbarch, alpha_use_struct_convention);
+  set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention);
   set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value);
   set_gdbarch_store_return_value (gdbarch, alpha_store_return_value);
-  set_gdbarch_extract_struct_value_address (gdbarch,
-                                           alpha_extract_struct_value_address);
+  set_gdbarch_deprecated_extract_struct_value_address (gdbarch, alpha_extract_struct_value_address);
 
   /* Settings for calling functions in the inferior.  */
   set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call);
 
   /* Methods for saving / extracting a dummy frame's ID.  */
   set_gdbarch_unwind_dummy_id (gdbarch, alpha_unwind_dummy_id);
-  set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
 
   /* Return the unwound PC value.  */
   set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc);
@@ -1475,9 +1544,6 @@ 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_function_start_offset (gdbarch, 0);
-  set_gdbarch_frame_args_skip (gdbarch, 0);
-
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
@@ -1487,14 +1553,23 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   if (tdep->jb_pc >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
 
-  frame_unwind_append_predicate (gdbarch, alpha_sigtramp_frame_p);
-  frame_unwind_append_predicate (gdbarch, alpha_heuristic_frame_p);
+  frame_unwind_append_sniffer (gdbarch, alpha_sigtramp_frame_sniffer);
+  frame_unwind_append_sniffer (gdbarch, alpha_heuristic_frame_sniffer);
 
   frame_base_set_default (gdbarch, &alpha_heuristic_frame_base);
 
   return gdbarch;
 }
 
+void
+alpha_dwarf2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
+  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
+}
+
+extern initialize_file_ftype _initialize_alpha_tdep; /* -Wmissing-prototypes */
+
 void
 _initialize_alpha_tdep (void)
 {
@@ -1507,16 +1582,20 @@ _initialize_alpha_tdep (void)
   /* We really would like to have both "0" and "unlimited" work, but
      command.c doesn't deal with that.  So make it a var_zinteger
      because the user can always use "999999" or some such for unlimited.  */
-  c = add_set_cmd ("heuristic-fence-post", class_support, var_zinteger,
-                  (char *) &heuristic_fence_post,
-                  "\
-Set the distance searched for the start of a function.\n\
-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.",
-                  &setlist);
   /* We need to throw away the frame cache when we set this, since it
      might change our ability to get backtraces.  */
-  set_cmd_sfunc (c, reinit_frame_cache_sfunc);
-  add_show_from_set (c, &showlist);
+  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."),
+                           _("\
+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."),
+                           _("\
+The distance searched for the start of a function is \"%d\"."),
+                           reinit_frame_cache_sfunc, NULL,
+                           &setlist, &showlist);
 }
This page took 0.031683 seconds and 4 git commands to generate.