2004-02-09 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / alpha-tdep.c
index 53c9f63d192fd50857a68c169c2e53cad7c01738..44b85d1c300bfa3ff082b0e3a1f41d8d0ea5ff95 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"
@@ -80,17 +81,20 @@ 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);
-}
-
 static struct type *
-alpha_register_virtual_type (int regno)
+alpha_register_type (struct gdbarch *gdbarch, int regno)
 {
-  return ((regno >= FP0_REGNUM && regno < (FP0_REGNUM+31))
-         ? builtin_type_double : builtin_type_long);
+  if (regno == ALPHA_SP_REGNUM || regno == ALPHA_GP_REGNUM)
+    return builtin_type_void_data_ptr;
+  if (regno == ALPHA_PC_REGNUM)
+    return builtin_type_void_func_ptr;
+
+  /* Don't need to worry about little vs big endian until 
+     some jerk tries to port to alpha-unicosmk.  */
+  if (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31)
+    return builtin_type_ieee_double_little;
+
+  return builtin_type_int64;
 }
 
 /* Is REGNUM a member of REGGROUP?  */
@@ -104,10 +108,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.  */
@@ -144,65 +156,97 @@ alpha_register_virtual_size (int regno)
   return 8;
 }
 
-/* The alpha needs a conversion between register and memory format if the
-   register is a floating point register and memory format is float, as the
-   register format must be double or memory format is an integer with 4
-   bytes or less, as the representation of integers in floating point
-   registers is different. */
+/* 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_register_convert_to_virtual (int regnum, struct type *valtype,
-                                  char *raw_buffer, char *virtual_buffer)
+alpha_lds (void *out, const void *in)
 {
-  if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
+  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)
     {
-      memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
-      return;
+      if (exp_low == 0x7f)
+       exp = 0x7ff;
     }
-
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    {
-      double d = deprecated_extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
-      deprecated_store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
-    }
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+  else
     {
-      ULONGEST l;
-      l = extract_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum));
-      l = ((l >> 32) & 0xc0000000) | ((l >> 29) & 0x3fffffff);
-      store_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype), l);
+      if (exp_low != 0x00)
+       exp |= 0x380;
     }
-  else
-    error ("Cannot retrieve value from floating point register");
+
+  reg = (sign << 63) | (exp << 52) | (frac << 29);
+  store_unsigned_integer (out, 8, reg);
 }
 
+/* Similarly, this represents exactly the conversion performed by
+   the STS instruction.  */
+
 static void
-alpha_register_convert_to_raw (struct type *valtype, int regnum,
-                              char *virtual_buffer, char *raw_buffer)
+alpha_sts (void *out, const void *in)
 {
-  if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum))
-    {
-      memcpy (raw_buffer, virtual_buffer, REGISTER_RAW_SIZE (regnum));
-      return;
-    }
+  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
+   register is a floating point register and memory format is float, as the
+   register format must be double or memory format is an integer with 4
+   bytes or less, as the representation of integers in floating point
+   registers is different. */
 
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+static int
+alpha_convert_register_p (int regno, struct type *type)
+{
+  return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31);
+}
+
+static void
+alpha_register_to_value (struct frame_info *frame, int regnum,
+                        struct type *valtype, void *out)
+{
+  char in[MAX_REGISTER_SIZE];
+  frame_register_read (frame, regnum, in);
+  switch (TYPE_LENGTH (valtype))
     {
-      double d = deprecated_extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
-      deprecated_store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
+    case 4:
+      alpha_sts (out, in);
+      break;
+    case 8:
+      memcpy (out, in, 8);
+      break;
+    default:
+      error ("Cannot retrieve value from floating point register");
     }
-  else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
+}
+
+static void
+alpha_value_to_register (struct frame_info *frame, int regnum,
+                        struct type *valtype, const void *in)
+{
+  char out[MAX_REGISTER_SIZE];
+  switch (TYPE_LENGTH (valtype))
     {
-      ULONGEST l;
-      if (TYPE_UNSIGNED (valtype))
-       l = extract_unsigned_integer (virtual_buffer, TYPE_LENGTH (valtype));
-      else
-       l = extract_signed_integer (virtual_buffer, TYPE_LENGTH (valtype));
-      l = ((l & 0xc0000000) << 32) | ((l & 0x3fffffff) << 29);
-      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), 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
@@ -234,7 +278,7 @@ 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;
 
@@ -259,19 +303,27 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
        case TYPE_CODE_CHAR:
        case TYPE_CODE_RANGE:
        case TYPE_CODE_ENUM:
-         if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+         if (TYPE_LENGTH (arg_type) == 4)
+           {
+             /* 32-bit values must be sign-extended to 64 bits
+                even if the base data type is unsigned.  */
+             arg_type = builtin_type_int32;
+             arg = value_cast (arg_type, arg);
+           }
+         if (TYPE_LENGTH (arg_type) < ALPHA_REGISTER_SIZE)
            {
-             arg_type = builtin_type_long;
+             arg_type = builtin_type_int64;
              arg = value_cast (arg_type, arg);
            }
          break;
+
        case TYPE_CODE_FLT:
          /* "float" arguments loaded in registers must be passed in
             register format, aka "double".  */
          if (accumulate_size < sizeof (arg_reg_buffer)
              && TYPE_LENGTH (arg_type) == 4)
            {
-             arg_type = builtin_type_double;
+             arg_type = builtin_type_ieee_double_little;
              arg = value_cast (arg_type, arg);
            }
          /* Tru64 5.1 has a 128-bit long double, and passes this by
@@ -289,6 +341,28 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
              arg = value_from_pointer (arg_type, sp);
            }
          break;
+
+       case TYPE_CODE_COMPLEX:
+         /* ??? The ABI says that complex values are passed as two
+            separate scalar values.  This distinction only matters
+            for complex float.  However, GCC does not implement this.  */
+
+         /* Tru64 5.1 has a 128-bit long double, and passes this by
+            invisible reference.  */
+         if (TYPE_LENGTH (arg_type) == 32)
+           {
+             /* Allocate aligned storage.  */
+             sp = (sp & -16) - 16;
+
+             /* Write the real data into the stack.  */
+             write_memory (sp, VALUE_CONTENTS (arg), 32);
+
+             /* Construct the indirection.  */
+             arg_type = lookup_pointer_type (arg_type);
+             arg = value_from_pointer (arg_type, sp);
+           }
+         break;
+
        default:
          break;
        }
@@ -360,63 +434,155 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
   return sp;
 }
 
-/* Given a return value in `regbuf' with a type `valtype', 
-   extract and copy its value into `valbuf'.  */
+/* Extract from REGCACHE the value about to be returned from a function
+   and copy it into VALBUF.  */
 
 static void
-alpha_extract_return_value (struct type *valtype,
-                           char regbuf[ALPHA_REGISTER_BYTES], char *valbuf)
+alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
+                           void *valbuf)
 {
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
-    alpha_register_convert_to_virtual (FP0_REGNUM, valtype,
-                                      regbuf + REGISTER_BYTE (FP0_REGNUM),
-                                      valbuf);
-  else
-    memcpy (valbuf, regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
-            TYPE_LENGTH (valtype));
-}
-
-/* Given a return value in `regbuf' with a type `valtype', 
-   write its value into the appropriate register.  */
-
-static void
-alpha_store_return_value (struct type *valtype, char *valbuf)
-{
-  char raw_buffer[ALPHA_REGISTER_SIZE];
-  int regnum = ALPHA_V0_REGNUM;
   int length = TYPE_LENGTH (valtype);
+  char raw_buffer[ALPHA_REGISTER_SIZE];
+  ULONGEST l;
 
-  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+  switch (TYPE_CODE (valtype))
     {
-      regnum = FP0_REGNUM;
-      length = ALPHA_REGISTER_SIZE;
-      alpha_register_convert_to_raw (valtype, regnum, valbuf, raw_buffer);
-    }
-  else
-    memcpy (raw_buffer, valbuf, length);
+    case TYPE_CODE_FLT:
+      switch (length)
+       {
+       case 4:
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, raw_buffer);
+         alpha_sts (valbuf, raw_buffer);
+         break;
+
+       case 8:
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+         break;
+
+       case 16:
+         regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
+         read_memory (l, valbuf, 16);
+         break;
 
-  deprecated_write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
+       default:
+         internal_error (__FILE__, __LINE__, "unknown floating point width");
+       }
+      break;
+
+    case TYPE_CODE_COMPLEX:
+      switch (length)
+       {
+       case 8:
+         /* ??? This isn't correct wrt the ABI, but it's what GCC does.  */
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+         break;
+
+       case 16:
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1,
+                               (char *)valbuf + 8);
+         break;
+
+       case 32:
+         regcache_cooked_read_signed (regcache, ALPHA_V0_REGNUM, &l);
+         read_memory (l, valbuf, 32);
+         break;
+
+       default:
+         internal_error (__FILE__, __LINE__, "unknown floating point width");
+       }
+      break;
+
+    default:
+      /* Assume everything else degenerates to an integer.  */
+      regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &l);
+      store_unsigned_integer (valbuf, length, l);
+      break;
+    }
 }
 
-static int
-alpha_use_struct_convention (int gcc_p, struct type *type)
+/* Extract from REGCACHE the address of a structure about to be returned
+   from a function.  */
+
+static CORE_ADDR
+alpha_extract_struct_value_address (struct regcache *regcache)
 {
-  /* Structures are returned by ref in extra arg0.  */
-  return 1;
+  ULONGEST addr;
+  regcache_cooked_read_unsigned (regcache, ALPHA_V0_REGNUM, &addr);
+  return addr;
 }
 
+/* Insert the given value into REGCACHE as if it was being 
+   returned by a function.  */
+
 static void
-alpha_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+alpha_store_return_value (struct type *valtype, struct regcache *regcache,
+                         const void *valbuf)
 {
-  /* Store the address of the place in which to copy the structure the
-     subroutine will return.  Handled by alpha_push_arguments.  */
-}
+  int length = TYPE_LENGTH (valtype);
+  char raw_buffer[ALPHA_REGISTER_SIZE];
+  ULONGEST l;
 
-static CORE_ADDR
-alpha_extract_struct_value_address (char *regbuf)
-{
-  return (extract_unsigned_integer (regbuf + REGISTER_BYTE (ALPHA_V0_REGNUM),
-                                   REGISTER_RAW_SIZE (ALPHA_V0_REGNUM)));
+  switch (TYPE_CODE (valtype))
+    {
+    case TYPE_CODE_FLT:
+      switch (length)
+       {
+       case 4:
+         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);
+         break;
+
+       case 16:
+         /* 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.");
+
+       default:
+         internal_error (__FILE__, __LINE__, "unknown floating point width");
+       }
+      break;
+
+    case TYPE_CODE_COMPLEX:
+      switch (length)
+       {
+       case 8:
+         /* ??? This isn't correct wrt the ABI, but it's what GCC does.  */
+         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
+         break;
+
+       case 16:
+         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
+         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1,
+                                (const char *)valbuf + 8);
+         break;
+
+       case 32:
+         /* 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.");
+
+       default:
+         internal_error (__FILE__, __LINE__, "unknown floating point width");
+       }
+      break;
+
+    default:
+      /* Assume everything else degenerates to an integer.  */
+      /* 32-bit values must be sign-extended to 64 bits
+        even if the base data type is unsigned.  */
+      if (length == 4)
+       valtype = builtin_type_int32;
+      l = unpack_long (valtype, valbuf);
+      regcache_cooked_write_unsigned (regcache, ALPHA_V0_REGNUM, l);
+      break;
+    }
 }
 
 \f
@@ -587,24 +753,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;
 }
@@ -646,7 +808,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);
 }
@@ -675,7 +838,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;
        }
     }
@@ -695,8 +858,9 @@ 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
@@ -972,11 +1136,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);
 }
 
@@ -1007,7 +1166,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;
     }
 
@@ -1036,7 +1195,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;
 }
@@ -1113,6 +1272,73 @@ 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)
+      supply_register (i, (const char *)r0_r30 + i*8);
+
+  if (regno == ALPHA_ZERO_REGNUM || regno == -1)
+    supply_register (ALPHA_ZERO_REGNUM, NULL);
+
+  if (regno == ALPHA_PC_REGNUM || regno == -1)
+    supply_register (ALPHA_PC_REGNUM, pc);
+
+  if (regno == ALPHA_UNIQUE_REGNUM || regno == -1)
+    supply_register (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_collect (i, (char *)r0_r30 + i*8);
+
+  if (regno == ALPHA_PC_REGNUM || regno == -1)
+    regcache_collect (ALPHA_PC_REGNUM, pc);
+
+  if (unique && (regno == ALPHA_UNIQUE_REGNUM || regno == -1))
+    regcache_collect (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)
+      supply_register (i, (const char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+    supply_register (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_collect (i, (char *)f0_f30 + (i - ALPHA_FP0_REGNUM) * 8);
+
+  if (regno == ALPHA_FPCR_REGNUM || regno == -1)
+    regcache_collect (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
@@ -1130,7 +1356,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;
@@ -1261,6 +1487,9 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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  */
 
@@ -1281,18 +1510,17 @@ 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_deprecated_register_raw_size (gdbarch, alpha_register_raw_size);
+  set_gdbarch_deprecated_register_virtual_size (gdbarch, alpha_register_virtual_size);
+  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);
 
@@ -1303,23 +1531,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_extract_return_value (gdbarch, alpha_extract_return_value);
-  set_gdbarch_deprecated_store_struct_return (gdbarch, alpha_store_struct_return);
-  set_gdbarch_deprecated_store_return_value (gdbarch, alpha_store_return_value);
-  set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
-                                           alpha_extract_struct_value_address);
+  set_gdbarch_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_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);
@@ -1330,9 +1552,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);
 
@@ -1342,14 +1561,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)
 {
This page took 0.046721 seconds and 4 git commands to generate.