OSDN Git Service

Re-sync to pf3gnuchains3x.
[pf3gnuchains/pf3gnuchains4x.git] / gdb / avr-tdep.c
index ba6e8cb..6340c21 100644 (file)
@@ -89,10 +89,6 @@ enum
   AVR_NUM_REGS = 32 + 1 /*SREG*/ + 1 /*SP*/ + 1 /*PC*/,
   AVR_NUM_REG_BYTES = 32 + 1 /*SREG*/ + 2 /*SP*/ + 4 /*PC*/,
 
-  /* Pseudo registers.  */
-  AVR_PSEUDO_PC_REGNUM = 35,
-  AVR_NUM_PSEUDO_REGS = 1,
-
   AVR_PC_REG_INDEX = 35,       /* index into array of registers */
 
   AVR_MAX_PROLOGUE_SIZE = 64,  /* bytes */
@@ -185,13 +181,6 @@ struct gdbarch_tdep
   /* Number of bytes stored to the stack by call instructions.
      2 bytes for avr1-5, 3 bytes for avr6.  */
   int call_length;
-
-  /* Type for void.  */
-  struct type *void_type;
-  /* Type for a function returning void.  */
-  struct type *func_void_type;
-  /* Type for a pointer to a function.  Used for the type of PC.  */
-  struct type *pc_type;
 };
 
 /* Lookup the name of a register given it's number. */
@@ -204,8 +193,7 @@ avr_register_name (struct gdbarch *gdbarch, int regnum)
     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
-    "SREG", "SP", "PC2",
-    "pc"
+    "SREG", "SP", "PC"
   };
   if (regnum < 0)
     return NULL;
@@ -222,11 +210,10 @@ avr_register_type (struct gdbarch *gdbarch, int reg_nr)
 {
   if (reg_nr == AVR_PC_REGNUM)
     return builtin_type (gdbarch)->builtin_uint32;
-  if (reg_nr == AVR_PSEUDO_PC_REGNUM)
-    return gdbarch_tdep (gdbarch)->pc_type;
   if (reg_nr == AVR_SP_REGNUM)
     return builtin_type (gdbarch)->builtin_data_ptr;
-  return builtin_type (gdbarch)->builtin_uint8;
+  else
+    return builtin_type (gdbarch)->builtin_uint8;
 }
 
 /* Instruction address checks and convertions. */
@@ -253,10 +240,6 @@ avr_convert_iaddr_to_raw (CORE_ADDR x)
 static CORE_ADDR
 avr_make_saddr (CORE_ADDR x)
 {
-  /* Return 0 for NULL.  */
-  if (x == 0)
-    return 0;
-
   return ((x) | AVR_SMEM_START);
 }
 
@@ -331,15 +314,6 @@ avr_pointer_to_address (struct gdbarch *gdbarch,
 }
 
 static CORE_ADDR
-avr_integer_to_address (struct gdbarch *gdbarch,
-                       struct type *type, const gdb_byte *buf)
-{
-  ULONGEST addr = unpack_long (type, buf);
-
-  return avr_make_saddr (addr);
-}
-
-static CORE_ADDR
 avr_read_pc (struct regcache *regcache)
 {
   ULONGEST pc;
@@ -351,43 +325,7 @@ static void
 avr_write_pc (struct regcache *regcache, CORE_ADDR val)
 {
   regcache_cooked_write_unsigned (regcache, AVR_PC_REGNUM,
-                                  avr_convert_iaddr_to_raw (val));
-}
-
-static void
-avr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-                          int regnum, gdb_byte *buf)
-{
-  ULONGEST val;
-
-  switch (regnum)
-    {
-    case AVR_PSEUDO_PC_REGNUM:
-      regcache_raw_read_unsigned (regcache, AVR_PC_REGNUM, &val);
-      val >>= 1;
-      store_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch), val);
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, _("invalid regnum"));
-    }
-}
-
-static void
-avr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
-                           int regnum, const gdb_byte *buf)
-{
-  ULONGEST val;
-
-  switch (regnum)
-    {
-    case AVR_PSEUDO_PC_REGNUM:
-      val = extract_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch));
-      val <<= 1;
-      regcache_raw_write_unsigned (regcache, AVR_PC_REGNUM, val);
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, _("invalid regnum"));
-    }
+                                 avr_convert_iaddr_to_raw (val));
 }
 
 /* Function: avr_scan_prologue
@@ -712,25 +650,6 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
      fprintf_unfiltered (gdb_stderr,
                          _("Hit end of prologue while scanning pushes\n"));
 
-  /* Handle static small stack allocation using rcall or push.  */
-
-  while (scan_stage == 1 && vpc < len)
-    {
-      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
-      if (insn == 0xd000)      /* rcall .+0 */
-        {
-          info->size += gdbarch_tdep (gdbarch)->call_length;
-          vpc += 2;
-        }
-      else if (insn == 0x920f)  /* push r0 */
-        {
-          info->size += 1;
-          vpc += 2;
-        }
-      else
-        break;
-    }
-
   /* Second stage of the prologue scanning.
      Scan:
      in r28,__SP_L__
@@ -784,21 +703,18 @@ avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
       };
 
       insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
+      vpc += 2;
       if ((insn & 0xff30) == 0x9720)   /* sbiw r28,XXX */
-        {
-          locals_size = (insn & 0xf) | ((insn & 0xc0) >> 2);
-          vpc += 2;
-        }
+       locals_size = (insn & 0xf) | ((insn & 0xc0) >> 2);
       else if ((insn & 0xf0f0) == 0x50c0)      /* subi r28,lo8(XX) */
        {
          locals_size = (insn & 0xf) | ((insn & 0xf00) >> 4);
-         vpc += 2;
          insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
          vpc += 2;
-         locals_size += ((insn & 0xf) | ((insn & 0xf00) >> 4)) << 8;
+         locals_size += ((insn & 0xf) | ((insn & 0xf00) >> 4) << 8);
        }
       else
-        return pc_beg + vpc;
+       return pc_beg + vpc;
 
       /* Scan the last part of the prologue. May not be present for interrupt
          or signal handler functions, which is why we set the prologue type
@@ -847,39 +763,40 @@ static CORE_ADDR
 avr_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr, func_end;
-  CORE_ADDR post_prologue_pc;
+  CORE_ADDR prologue_end = pc;
 
   /* See what the symbol table says */
 
-  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
-    return pc;
+  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    {
+      struct symtab_and_line sal;
+      struct avr_unwind_cache info = {0};
+      struct trad_frame_saved_reg saved_regs[AVR_NUM_REGS];
+
+      info.saved_regs = saved_regs;
 
-  post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr);
-  if (post_prologue_pc != 0)
-    return max (pc, post_prologue_pc);
+      /* Need to run the prologue scanner to figure out if the function has a
+         prologue and possibly skip over moving arguments passed via registers
+         to other registers.  */
 
-  {
-    CORE_ADDR prologue_end = pc;
-    struct avr_unwind_cache info = {0};
-    struct trad_frame_saved_reg saved_regs[AVR_NUM_REGS];
+      prologue_end = avr_scan_prologue (gdbarch, func_addr, func_end, &info);
 
-    info.saved_regs = saved_regs;
-    
-    /* Need to run the prologue scanner to figure out if the function has a
-       prologue and possibly skip over moving arguments passed via registers
-       to other registers.  */
-    
-    prologue_end = avr_scan_prologue (gdbarch, func_addr, func_end, &info);
-    
-    if (info.prologue_type != AVR_PROLOGUE_NONE)
-      return prologue_end;
-  }
+      if (info.prologue_type == AVR_PROLOGUE_NONE)
+        return pc;
+      else
+        {
+          sal = find_pc_line (func_addr, 0);
+
+          if (sal.line != 0 && sal.end < func_end)
+            return sal.end;
+        }
+    }
 
   /* Either we didn't find the start of this function (nothing we can do),
      or there's no line info, or the line after the prologue is after
      the end of the function (there probably isn't a prologue). */
 
-  return pc;
+  return prologue_end;
 }
 
 /* Not all avr devices support the BREAK insn. Those that don't should treat
@@ -894,6 +811,40 @@ avr_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR * pcptr, int *lenptr)
     return avr_break_insn;
 }
 
+/* Given a return value in `regcache' with a type `type', 
+   extract and copy its value into `valbuf'.
+
+   Return values are always passed via registers r25:r24:...  */
+
+static void
+avr_extract_return_value (struct type *type, struct regcache *regcache,
+                          gdb_byte *valbuf)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  ULONGEST r24, r25;
+  ULONGEST c;
+  int len;
+  if (TYPE_LENGTH (type) == 1)
+    {
+      regcache_cooked_read_unsigned (regcache, 24, &c);
+      store_unsigned_integer (valbuf, 1, byte_order, c);
+    }
+  else
+    {
+      int i;
+      /* The MSB of the return value is always in r25, calculate which
+         register holds the LSB.  */
+      int lsb_reg = 25 - TYPE_LENGTH (type) + 1;
+
+      for (i=0; i< TYPE_LENGTH (type); i++)
+        {
+          regcache_cooked_read (regcache, lsb_reg + i,
+                                (bfd_byte *) valbuf + i);
+        }
+    }
+}
+
 /* Determine, for architecture GDBARCH, how a return value of TYPE
    should be returned.  If it is supposed to be returned in registers,
    and READBUF is non-zero, read the appropriate value from REGCACHE,
@@ -905,40 +856,30 @@ avr_return_value (struct gdbarch *gdbarch, struct type *func_type,
                  struct type *valtype, struct regcache *regcache,
                  gdb_byte *readbuf, const gdb_byte *writebuf)
 {
-  int i;
-  /* Single byte are returned in r24.
-     Otherwise, the MSB of the return value is always in r25, calculate which
-     register holds the LSB.  */
-  int lsb_reg;
-
-  if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
-       || TYPE_CODE (valtype) == TYPE_CODE_UNION
-       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
-      && TYPE_LENGTH (valtype) > 8)
-    return RETURN_VALUE_STRUCT_CONVENTION;
-
-  if (TYPE_LENGTH (valtype) <= 2)
-    lsb_reg = 24;
-  else if (TYPE_LENGTH (valtype) <= 4)
-    lsb_reg = 22;
-  else if (TYPE_LENGTH (valtype) <= 8)
-    lsb_reg = 18;
-  else
-    gdb_assert (0);
+  int struct_return = ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
+                       || TYPE_CODE (valtype) == TYPE_CODE_UNION
+                       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
+                      && !(TYPE_LENGTH (valtype) == 1
+                           || TYPE_LENGTH (valtype) == 2
+                           || TYPE_LENGTH (valtype) == 4
+                           || TYPE_LENGTH (valtype) == 8));
 
   if (writebuf != NULL)
     {
-      for (i = 0; i < TYPE_LENGTH (valtype); i++)
-        regcache_cooked_write (regcache, lsb_reg + i, writebuf + i);
+      gdb_assert (!struct_return);
+      error (_("Cannot store return value."));
     }
 
   if (readbuf != NULL)
     {
-      for (i = 0; i < TYPE_LENGTH (valtype); i++)
-        regcache_cooked_read (regcache, lsb_reg + i, readbuf + i);
+      gdb_assert (!struct_return);
+      avr_extract_return_value (valtype, regcache, readbuf);
     }
 
-  return RETURN_VALUE_REGISTER_CONVENTION;
+  if (struct_return)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else
+    return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
 
@@ -1085,9 +1026,9 @@ avr_frame_prev_register (struct frame_info *this_frame,
   struct avr_unwind_cache *info
     = avr_frame_unwind_cache (this_frame, this_prologue_cache);
 
-  if (regnum == AVR_PC_REGNUM || regnum == AVR_PSEUDO_PC_REGNUM)
+  if (regnum == AVR_PC_REGNUM)
     {
-      if (trad_frame_addr_p (info->saved_regs, AVR_PC_REGNUM))
+      if (trad_frame_addr_p (info->saved_regs, regnum))
         {
          /* Reading the return PC from the PC register is slightly
             abnormal.  register_size(AVR_PC_REGNUM) says it is 4 bytes,
@@ -1107,18 +1048,14 @@ avr_frame_prev_register (struct frame_info *this_frame,
          struct gdbarch *gdbarch = get_frame_arch (this_frame);
          struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-         read_memory (info->saved_regs[AVR_PC_REGNUM].addr,
-                       buf, tdep->call_length);
+         read_memory (info->saved_regs[regnum].addr, buf, tdep->call_length);
 
          /* Extract the PC read from memory as a big-endian.  */
          pc = 0;
          for (i = 0; i < tdep->call_length; i++)
            pc = (pc << 8) | buf[i];
 
-          if (regnum == AVR_PC_REGNUM)
-            pc <<= 1;
-
-         return frame_unwind_got_constant (this_frame, regnum, pc);
+         return frame_unwind_got_constant (this_frame, regnum, pc << 1);
         }
 
       return frame_unwind_got_optimized (this_frame, regnum);
@@ -1250,13 +1187,15 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int regnum = AVR_ARGN_REGNUM;
   struct stack_item *si = NULL;
 
+#if 0
+  /* FIXME: TRoth/2003-06-18: Not sure what to do when returning a struct. */
   if (struct_return)
     {
-      regcache_cooked_write_unsigned (regcache, regnum--,
-                                      struct_addr & 0xff);
-      regcache_cooked_write_unsigned (regcache, regnum--,
-                                      (struct_addr >> 8) & 0xff);
+      fprintf_unfiltered (gdb_stderr, "struct_return: 0x%lx\n", struct_addr);
+      regcache_cooked_write_unsigned (regcache, argreg--, struct_addr & 0xff);
+      regcache_cooked_write_unsigned (regcache, argreg--, (struct_addr >>8) & 0xff);
     }
+#endif
 
   for (i = 0; i < nargs; i++)
     {
@@ -1324,21 +1263,6 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   return sp + call_length;
 }
 
-/* Unfortunately dwarf2 register for SP is 32.  */
-
-static int
-avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
-{
-  if (reg >= 0 && reg < 32)
-    return reg;
-  if (reg == 32)
-    return AVR_SP_REGNUM;
-
-  warning (_("Unmapped DWARF Register #%d encountered."), reg);
-
-  return -1;
-}
-
 /* Initialize the gdbarch structure for the AVR's. */
 
 static struct gdbarch *
@@ -1380,14 +1304,6 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   
   tdep->call_length = call_length;
 
-  /* Create a type for PC.  We can't use builtin types here, as they may not
-     be defined.  */
-  tdep->void_type = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
-  tdep->func_void_type = make_function_type (tdep->void_type, NULL);
-  tdep->pc_type = arch_type (gdbarch, TYPE_CODE_PTR, 4, NULL);
-  TYPE_TARGET_TYPE (tdep->pc_type) = tdep->func_void_type;
-  TYPE_UNSIGNED (tdep->pc_type) = 1;
-
   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
@@ -1414,20 +1330,13 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_name (gdbarch, avr_register_name);
   set_gdbarch_register_type (gdbarch, avr_register_type);
 
-  set_gdbarch_num_pseudo_regs (gdbarch, AVR_NUM_PSEUDO_REGS);
-  set_gdbarch_pseudo_register_read (gdbarch, avr_pseudo_register_read);
-  set_gdbarch_pseudo_register_write (gdbarch, avr_pseudo_register_write);
-
   set_gdbarch_return_value (gdbarch, avr_return_value);
   set_gdbarch_print_insn (gdbarch, print_insn_avr);
 
   set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call);
 
-  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, avr_dwarf_reg_to_regnum);
-
   set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
   set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
-  set_gdbarch_integer_to_address (gdbarch, avr_integer_to_address);
 
   set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);