Add "make pdf" and "make install-pdf", from Brooks Moses
[deliverable/binutils-gdb.git] / gdb / alpha-tdep.c
index 960b0514907182c5468393fdf39db596e04ffe2c..83e95a1a1f2b52a77331c165f091a60d00a51e4c 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
 
-   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -73,7 +73,7 @@ alpha_register_name (int regno)
 
   if (regno < 0)
     return NULL;
-  if (regno >= (sizeof(register_names) / sizeof(*register_names)))
+  if (regno >= ARRAY_SIZE(register_names))
     return NULL;
   return register_names[regno];
 }
@@ -103,7 +103,7 @@ alpha_register_type (struct gdbarch *gdbarch, int regno)
   /* 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_ieee_double;
 
   return builtin_type_int64;
 }
@@ -149,12 +149,6 @@ alpha_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
     return group == general_reggroup;
 }
 
-static int
-alpha_register_byte (int regno)
-{
-  return (regno * 8);
-}
-
 /* The following represents exactly the conversion performed by
    the LDS instruction.  This applies to both single-precision
    floating point and 32-bit integers.  */
@@ -214,7 +208,8 @@ static void
 alpha_register_to_value (struct frame_info *frame, int regnum,
                         struct type *valtype, gdb_byte *out)
 {
-  char in[MAX_REGISTER_SIZE];
+  gdb_byte in[MAX_REGISTER_SIZE];
+
   frame_register_read (frame, regnum, in);
   switch (TYPE_LENGTH (valtype))
     {
@@ -233,7 +228,8 @@ static void
 alpha_value_to_register (struct frame_info *frame, int regnum,
                         struct type *valtype, const gdb_byte *in)
 {
-  char out[MAX_REGISTER_SIZE];
+  gdb_byte out[MAX_REGISTER_SIZE];
+
   switch (TYPE_LENGTH (valtype))
     {
     case 4:
@@ -271,14 +267,14 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int accumulate_size = struct_return ? 8 : 0;
   struct alpha_arg
     {
-      char *contents;
+      gdb_byte *contents;
       int len;
       int offset;
     };
   struct alpha_arg *alpha_args
     = (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg));
   struct alpha_arg *m_arg;
-  char arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS];
+  gdb_byte arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS];
   int required_arg_regs;
   CORE_ADDR func_addr = find_function_addr (function, NULL);
 
@@ -323,7 +319,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          if (accumulate_size < sizeof (arg_reg_buffer)
              && TYPE_LENGTH (arg_type) == 4)
            {
-             arg_type = builtin_type_ieee_double_little;
+             arg_type = builtin_type_ieee_double;
              arg = value_cast (arg_type, arg);
            }
          /* Tru64 5.1 has a 128-bit long double, and passes this by
@@ -391,7 +387,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   /* `Push' arguments on the stack.  */
   for (i = nargs; m_arg--, --i >= 0;)
     {
-      char *contents = m_arg->contents;
+      gdb_byte *contents = m_arg->contents;
       int offset = m_arg->offset;
       int len = m_arg->len;
 
@@ -442,7 +438,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
                            gdb_byte *valbuf)
 {
   int length = TYPE_LENGTH (valtype);
-  char raw_buffer[ALPHA_REGISTER_SIZE];
+  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
   ULONGEST l;
 
   switch (TYPE_CODE (valtype))
@@ -479,8 +475,7 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
 
        case 16:
          regcache_cooked_read (regcache, ALPHA_FP0_REGNUM, valbuf);
-         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM+1,
-                               (char *)valbuf + 8);
+         regcache_cooked_read (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8);
          break;
 
        case 32:
@@ -501,17 +496,6 @@ alpha_extract_return_value (struct type *valtype, struct regcache *regcache,
     }
 }
 
-/* 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)
-{
-  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.  */
 
@@ -520,7 +504,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
                          const gdb_byte *valbuf)
 {
   int length = TYPE_LENGTH (valtype);
-  char raw_buffer[ALPHA_REGISTER_SIZE];
+  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
   ULONGEST l;
 
   switch (TYPE_CODE (valtype))
@@ -558,8 +542,7 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
 
        case 16:
          regcache_cooked_write (regcache, ALPHA_FP0_REGNUM, valbuf);
-         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM+1,
-                                (const char *)valbuf + 8);
+         regcache_cooked_write (regcache, ALPHA_FP0_REGNUM + 1, valbuf + 8);
          break;
 
        case 32:
@@ -585,15 +568,49 @@ alpha_store_return_value (struct type *valtype, struct regcache *regcache,
     }
 }
 
+static enum return_value_convention
+alpha_return_value (struct gdbarch *gdbarch, struct type *type,
+                   struct regcache *regcache, gdb_byte *readbuf,
+                   const gdb_byte *writebuf)
+{
+  enum type_code code = TYPE_CODE (type);
+
+  if ((code == TYPE_CODE_STRUCT
+       || code == TYPE_CODE_UNION
+       || code == TYPE_CODE_ARRAY)
+      && gdbarch_tdep (gdbarch)->return_in_memory (type))
+    {
+      if (readbuf)
+       {
+         ULONGEST addr;
+         regcache_raw_read_unsigned (regcache, ALPHA_V0_REGNUM, &addr);
+         read_memory (addr, readbuf, TYPE_LENGTH (type));
+       }
+
+      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+    }
+
+  if (readbuf)
+    alpha_extract_return_value (type, regcache, readbuf);
+  if (writebuf)
+    alpha_store_return_value (type, regcache, writebuf);
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+static int
+alpha_return_in_memory_always (struct type *type)
+{
+  return 1;
+}
 \f
-static const unsigned char *
-alpha_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+static const gdb_byte *
+alpha_breakpoint_from_pc (CORE_ADDR *pc, int *len)
 {
-  static const unsigned char alpha_breakpoint[] =
-    { 0x80, 0, 0, 0 }; /* call_pal bpt */
+  static const gdb_byte break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */
 
-  *lenptr = sizeof(alpha_breakpoint);
-  return (alpha_breakpoint);
+  *len = sizeof(break_insn);
+  return break_insn;
 }
 
 \f
@@ -623,13 +640,13 @@ alpha_after_prologue (CORE_ADDR pc)
 unsigned int
 alpha_read_insn (CORE_ADDR pc)
 {
-  char buf[4];
+  gdb_byte buf[ALPHA_INSN_SIZE];
   int status;
 
-  status = deprecated_read_memory_nobpt (pc, buf, 4);
+  status = read_memory_nobpt (pc, buf, sizeof (buf));
   if (status)
     memory_error (status, pc);
-  return extract_unsigned_integer (buf, 4);
+  return extract_unsigned_integer (buf, sizeof (buf));
 }
 
 /* To skip prologues, I use this predicate.  Returns either PC itself
@@ -645,7 +662,7 @@ alpha_skip_prologue (CORE_ADDR pc)
   unsigned long inst;
   int offset;
   CORE_ADDR post_prologue_pc;
-  char buf[4];
+  gdb_byte buf[ALPHA_INSN_SIZE];
 
   /* Silently return the unaltered pc upon memory errors.
      This could happen on OSF/1 if decode_line_1 tries to skip the
@@ -654,7 +671,7 @@ alpha_skip_prologue (CORE_ADDR pc)
      Reading target memory is slow over serial lines, so we perform
      this check only if the target has shared libraries (which all
      Alpha targets do).  */
-  if (target_read_memory (pc, buf, 4))
+  if (target_read_memory (pc, buf, sizeof (buf)))
     return pc;
 
   /* See if we can determine the end of the prologue via the symbol table.
@@ -671,7 +688,7 @@ alpha_skip_prologue (CORE_ADDR pc)
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (offset = 0; offset < 100; offset += 4)
+  for (offset = 0; offset < 100; offset += ALPHA_INSN_SIZE)
     {
       inst = alpha_read_insn (pc + offset);
 
@@ -710,7 +727,7 @@ alpha_get_longjmp_target (CORE_ADDR *pc)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   CORE_ADDR jb_addr;
-  char raw_buffer[ALPHA_REGISTER_SIZE];
+  gdb_byte raw_buffer[ALPHA_REGISTER_SIZE];
 
   jb_addr = read_register (ALPHA_A0_REGNUM);
 
@@ -803,7 +820,7 @@ alpha_sigtramp_frame_this_id (struct frame_info *next_frame,
        code_addr = 0;
     }
   else
-    code_addr = frame_func_unwind (next_frame);
+    code_addr = frame_func_unwind (next_frame, SIGTRAMP_FRAME);
 
   /* The stack address is trivially read from the sigcontext.  */
   stack_addr = alpha_sigtramp_register_address (info->sigcontext_addr,
@@ -847,8 +864,12 @@ alpha_sigtramp_frame_prev_register (struct frame_info *next_frame,
      current description of it in alpha_sigtramp_frame_unwind_cache
      doesn't include it.  Too bad.  Fall back on whatever's in the
      outer frame.  */
-  frame_register (next_frame, regnum, optimizedp, lvalp, addrp,
-                 realnump, bufferp);
+  *optimizedp = 0;
+  *lvalp = lval_register;
+  *addrp = 0;
+  *realnump = regnum;
+  if (bufferp)
+    frame_unwind_register (next_frame, *realnump, bufferp);
 }
 
 static const struct frame_unwind alpha_sigtramp_frame_unwind = {
@@ -929,7 +950,7 @@ alpha_heuristic_proc_start (CORE_ADDR pc)
   /* Search back for previous return; also stop at a 0, which might be
      seen for instance before the start of a code section.  Don't include
      nops, since this usually indicates padding between functions.  */
-  for (pc -= 4; pc >= fence; pc -= 4)
+  for (pc -= ALPHA_INSN_SIZE; pc >= fence; pc -= ALPHA_INSN_SIZE)
     {
       unsigned int insn = alpha_read_insn (pc);
       switch (insn)
@@ -1011,7 +1032,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
       if (start_pc + 200 < limit_pc)
        limit_pc = start_pc + 200;
 
-      for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4)
+      for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += ALPHA_INSN_SIZE)
        {
          unsigned int word = alpha_read_insn (cur_pc);
 
@@ -1120,7 +1141,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *next_frame,
                  break;
                }
 
-             cur_pc += 4;
+             cur_pc += ALPHA_INSN_SIZE;
            }
        }
     }
@@ -1201,8 +1222,12 @@ alpha_heuristic_frame_prev_register (struct frame_info *next_frame,
     }
 
   /* Otherwise assume the next frame has the same register value.  */
-  frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp,
-                         realnump, bufferp);
+  *optimizedp = 0;
+  *lvalp = lval_register;
+  *addrp = 0;
+  *realnump = regnum;
+  if (bufferp)
+    frame_unwind_register (next_frame, *realnump, bufferp);
 }
 
 static const struct frame_unwind alpha_heuristic_frame_unwind = {
@@ -1274,11 +1299,12 @@ void
 alpha_supply_int_regs (int regno, const void *r0_r30,
                       const void *pc, const void *unique)
 {
+  const gdb_byte *regs = r0_r30;
   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);
+      regcache_raw_supply (current_regcache, i, regs + i * 8);
 
   if (regno == ALPHA_ZERO_REGNUM || regno == -1)
     regcache_raw_supply (current_regcache, ALPHA_ZERO_REGNUM, NULL);
@@ -1293,11 +1319,12 @@ alpha_supply_int_regs (int regno, const void *r0_r30,
 void
 alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique)
 {
+  gdb_byte *regs = r0_r30;
   int i;
 
   for (i = 0; i < 31; ++i)
     if (regno == i || regno == -1)
-      regcache_raw_collect (current_regcache, i, (char *)r0_r30 + i*8);
+      regcache_raw_collect (current_regcache, i, regs + i * 8);
 
   if (regno == ALPHA_PC_REGNUM || regno == -1)
     regcache_raw_collect (current_regcache, ALPHA_PC_REGNUM, pc);
@@ -1309,12 +1336,13 @@ alpha_fill_int_regs (int regno, void *r0_r30, void *pc, void *unique)
 void
 alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr)
 {
+  const gdb_byte *regs = f0_f30;
   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);
+                          regs + (i - ALPHA_FP0_REGNUM) * 8);
 
   if (regno == ALPHA_FPCR_REGNUM || regno == -1)
     regcache_raw_supply (current_regcache, ALPHA_FPCR_REGNUM, fpcr);
@@ -1323,12 +1351,13 @@ alpha_supply_fp_regs (int regno, const void *f0_f30, const void *fpcr)
 void
 alpha_fill_fp_regs (int regno, void *f0_f30, void *fpcr)
 {
+  gdb_byte *regs = f0_f30;
   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);
+                           regs + (i - ALPHA_FP0_REGNUM) * 8);
 
   if (regno == ALPHA_FPCR_REGNUM || regno == -1)
     regcache_raw_collect (current_regcache, ALPHA_FPCR_REGNUM, fpcr);
@@ -1375,7 +1404,7 @@ alpha_next_pc (CORE_ADDR pc)
   int regno;
   int offset;
   LONGEST rav;
-  char reg[8];
+  gdb_byte reg[ALPHA_REGISTER_SIZE];
 
   insn = alpha_read_insn (pc);
 
@@ -1400,8 +1429,8 @@ alpha_next_pc (CORE_ADDR pc)
           offset = (insn & 0x001fffff);
          if (offset & 0x00100000)
            offset  |= 0xffe00000;
-         offset *= 4;
-         return (pc + 4 + offset);
+         offset *= ALPHA_INSN_SIZE;
+         return (pc + ALPHA_INSN_SIZE + offset);
        }
 
       /* Need to determine if branch is taken; read RA.  */
@@ -1418,7 +1447,7 @@ alpha_next_pc (CORE_ADDR pc)
        }
       
       regcache_cooked_read (current_regcache, regno, reg);
-      rav = extract_signed_integer (reg, 8);
+      rav = extract_signed_integer (reg, ALPHA_REGISTER_SIZE);
 
       switch (op)
        {
@@ -1486,15 +1515,13 @@ alpha_next_pc (CORE_ADDR pc)
 
   /* Not a branch or branch not taken; target PC is:
      pc + 4  */
-  return (pc + 4);
+  return (pc + ALPHA_INSN_SIZE);
 }
 
 void
 alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
 {
   static CORE_ADDR next_pc;
-  typedef char binsn_quantum[BREAKPOINT_MAX];
-  static binsn_quantum break_mem;
   CORE_ADDR pc;
 
   if (insert_breakpoints_p)
@@ -1502,11 +1529,11 @@ alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p)
       pc = read_pc ();
       next_pc = alpha_next_pc (pc);
 
-      target_insert_breakpoint (next_pc, break_mem);
+      insert_single_step_breakpoint (next_pc);
     }
   else
     {
-      target_remove_breakpoint (next_pc, break_mem);
+      remove_single_step_breakpoints ();
       write_pc (next_pc);
     }
 }
@@ -1553,6 +1580,8 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   tdep->jb_pc = -1;    /* longjmp support not enabled by default  */
 
+  tdep->return_in_memory = alpha_return_in_memory_always;
+
   /* Type sizes */
   set_gdbarch_short_bit (gdbarch, 16);
   set_gdbarch_int_bit (gdbarch, 32);
@@ -1570,7 +1599,6 @@ 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_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);
@@ -1590,10 +1618,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Call info.  */
 
-  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_deprecated_extract_struct_value_address (gdbarch, alpha_extract_struct_value_address);
+  set_gdbarch_return_value (gdbarch, alpha_return_value);
 
   /* Settings for calling functions in the inferior.  */
   set_gdbarch_push_dummy_call (gdbarch, alpha_push_dummy_call);
@@ -1608,7 +1633,7 @@ alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
   set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
-  set_gdbarch_decr_pc_after_break (gdbarch, 4);
+  set_gdbarch_decr_pc_after_break (gdbarch, ALPHA_INSN_SIZE);
   set_gdbarch_cannot_step_breakpoint (gdbarch, 1);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
This page took 0.030163 seconds and 4 git commands to generate.