* archures.c: Update copyright.
[deliverable/binutils-gdb.git] / gdb / xtensa-tdep.c
index cce09f55060046f7dcd2a62d38f1e5970b6fadce..d52addfd7dc85ca71f40c58530d319822ad4e925 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the Xtensa port of GDB, the GNU debugger.
 
-   Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -78,7 +78,6 @@ static int xtensa_debug_level = 0;
 
 /* On Windowed ABI, we use a6 through a11 for passing arguments
    to a function called by GDB because CALL4 is used.  */
-#define ARGS_FIRST_REG         gdbarch_tdep (current_gdbarch)->a0_base + 6
 #define ARGS_NUM_REGS          6
 #define REGISTER_SIZE          4
 
@@ -89,21 +88,14 @@ static int xtensa_debug_level = 0;
 #define CALLINC(ps)            (((ps) & PS_CALLINC_MASK) >> PS_CALLINC_SHIFT)
 #define WINSIZE(ra)            (4 * (( (ra) >> 30) & 0x3))
 
-
-/* Convert a live Ax register number to the corresponding Areg number.  */
-#define AREG_NUMBER(r, wb) \
-  ((((r) - (gdbarch_tdep (current_gdbarch)->a0_base + 0) + (((wb) \
-  & ((gdbarch_tdep (current_gdbarch)->num_aregs - 1) >> 2)) << WB_SHIFT)) & \
-  (gdbarch_tdep (current_gdbarch)->num_aregs - 1)) \
-  + gdbarch_tdep (current_gdbarch)->ar_base)
-
 /* ABI-independent macros.  */
-#define ARG_NOF            (gdbarch_tdep (current_gdbarch)->call_abi \
-                     == CallAbiCall0Only ? C0_NARGS : (ARGS_NUM_REGS))
-#define ARG_1ST            (gdbarch_tdep (current_gdbarch)->call_abi \
-                     == CallAbiCall0Only \
-                   ? (gdbarch_tdep (current_gdbarch)->a0_base + 0) + C0_ARGS \
-                     : (ARGS_FIRST_REG))
+#define ARG_NOF(gdbarch) \
+  (gdbarch_tdep (gdbarch)->call_abi \
+   == CallAbiCall0Only ? C0_NARGS : (ARGS_NUM_REGS))
+#define ARG_1ST(gdbarch) \
+  (gdbarch_tdep (gdbarch)->call_abi  == CallAbiCall0Only \
+   ? (gdbarch_tdep (gdbarch)->a0_base + 0) + C0_ARGS \
+   : (gdbarch_tdep (gdbarch)->a0_base + 6))
 
 extern struct gdbarch_tdep *xtensa_config_tdep (struct gdbarch_info *);
 extern int xtensa_config_byte_order (struct gdbarch_info *);
@@ -112,8 +104,8 @@ extern int xtensa_config_byte_order (struct gdbarch_info *);
 /* XTENSA_IS_ENTRY tests whether the first byte of an instruction
    indicates that the instruction is an ENTRY instruction.  */
 
-#define XTENSA_IS_ENTRY(op1) \
-  ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) \
+#define XTENSA_IS_ENTRY(gdbarch, op1) \
+  ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) \
    ? ((op1) == 0x6c) : ((op1) == 0x36))
 
 #define XTENSA_ENTRY_LENGTH    3
@@ -125,6 +117,20 @@ extern int xtensa_config_byte_order (struct gdbarch_info *);
 #define PS_WOE                 (1<<18)
 #define PS_EXC                 (1<<4)
 
+/* Convert a live Ax register number to the corresponding Areg number.  */
+static int
+areg_number (struct gdbarch *gdbarch, int regnum, ULONGEST wb)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int areg;
+
+  areg = regnum - tdep->a0_base;
+  areg += (wb & ((tdep->num_aregs - 1) >> 2)) << WB_SHIFT;
+  areg &= tdep->num_aregs - 1;
+
+  return areg + tdep->ar_base;
+}
+
 static inline int
 windowing_enabled (CORE_ADDR ps)
 {
@@ -143,7 +149,7 @@ windowing_enabled (CORE_ADDR ps)
    method to call the inferior function.  */
 
 static int
-extract_call_winsize (CORE_ADDR pc)
+extract_call_winsize (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   int winsize = 4;
   int insn;
@@ -163,7 +169,7 @@ extract_call_winsize (CORE_ADDR pc)
        call{0,4,8,12}   0101 || {00,01,10,11} || OFFSET
        callx{0,4,8,12}  0000 || {00,01,10,11} || 11 || OFFSET.  */
 
-  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
+  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
     {
       if (((insn & 0xf) == 0x5) || ((insn & 0xcf) == 0xc0))
        winsize = (insn & 0x30) >> 2;   /* 0, 4, 8, 12.  */
@@ -181,12 +187,12 @@ extract_call_winsize (CORE_ADDR pc)
 
 /* Returns the name of a register.  */
 static const char *
-xtensa_register_name (int regnum)
+xtensa_register_name (struct gdbarch *gdbarch, int regnum)
 {
   /* Return the name stored in the register map.  */
-  if (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch)
-                             + gdbarch_num_pseudo_regs (current_gdbarch))
-    return gdbarch_tdep (current_gdbarch)->regmap[regnum].name;
+  if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
+                             + gdbarch_num_pseudo_regs (gdbarch))
+    return gdbarch_tdep (gdbarch)->regmap[regnum].name;
 
   internal_error (__FILE__, __LINE__, _("invalid register %d"), regnum);
   return 0;
@@ -297,18 +303,17 @@ xtensa_register_type (struct gdbarch *gdbarch, int regnum)
    to n for An.  So, we only have to add the base number for A0.  */
 
 static int
-xtensa_reg_to_regnum (int regnum)
+xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum)
 {
   int i;
 
   if (regnum >= 0 && regnum < 16)
-    return gdbarch_tdep (current_gdbarch)->a0_base + regnum;
+    return gdbarch_tdep (gdbarch)->a0_base + regnum;
 
   for (i = 0;
-       i < gdbarch_num_regs (current_gdbarch)
-          + gdbarch_num_pseudo_regs (current_gdbarch);
+       i < gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
        i++)
-    if (regnum == gdbarch_tdep (current_gdbarch)->regmap[i].target_number)
+    if (regnum == gdbarch_tdep (gdbarch)->regmap[i].target_number)
       return i;
 
   internal_error (__FILE__, __LINE__,
@@ -500,7 +505,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
                             gdb_byte *buffer)
 {
   DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n",
-             regnum, xtensa_register_name (regnum));
+             regnum, xtensa_register_name (gdbarch, regnum));
 
   if (regnum == gdbarch_num_regs (gdbarch)
                + gdbarch_num_pseudo_regs (gdbarch))
@@ -514,7 +519,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
       gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
 
       regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
-      regnum = AREG_NUMBER (regnum, extract_unsigned_integer (buf, 4));
+      regnum = areg_number (gdbarch, regnum, extract_unsigned_integer (buf, 4));
     }
 
   /* We can always read non-pseudo registers.  */
@@ -536,7 +541,7 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
          if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
            {
              warning (_("cannot read register %s"),
-                      xtensa_register_name (regnum));
+                      xtensa_register_name (gdbarch, regnum));
              return;
            }
        }
@@ -584,7 +589,7 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
                              const gdb_byte *buffer)
 {
   DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n",
-             regnum, xtensa_register_name (regnum));
+             regnum, xtensa_register_name (gdbarch, regnum));
 
   if (regnum == gdbarch_num_regs (gdbarch)
                + gdbarch_num_pseudo_regs (gdbarch))
@@ -600,7 +605,7 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
 
       regcache_raw_read (regcache,
                         gdbarch_tdep (gdbarch)->wb_regnum, buf);
-      regnum = AREG_NUMBER (regnum, extract_unsigned_integer (buf, 4));
+      regnum = areg_number (gdbarch, regnum, extract_unsigned_integer (buf, 4));
     }
 
   /* We can always write 'core' registers.
@@ -624,7 +629,7 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
          if ((flags & xtTargetFlagsNonVisibleRegs) == 0)
            {
              warning (_("cannot write register %s"),
-                      xtensa_register_name (regnum));
+                      xtensa_register_name (gdbarch, regnum));
              return;
            }
        }
@@ -848,7 +853,7 @@ xtensa_regset_from_core_section (struct gdbarch *core_arch,
 {
   DEBUGTRACE ("xtensa_regset_from_core_section "
              "(..., sect_name==\"%s\", sect_size==%x) \n",
-             sect_name, sect_size);
+             sect_name, (unsigned int) sect_size);
 
   if (strcmp (sect_name, ".reg") == 0
       && sect_size >= sizeof(xtensa_elf_gregset_t))
@@ -1061,7 +1066,7 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
       ps = frame_unwind_register_unsigned (next_frame, ps_regnum);
 
       op1 = read_memory_integer (pc, 1);
-      if (XTENSA_IS_ENTRY (op1))
+      if (XTENSA_IS_ENTRY (gdbarch, op1))
        {
          int callinc = CALLINC (ps);
          ra = frame_unwind_register_unsigned
@@ -1135,8 +1140,8 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
          else
            {
              /* Read caller's frame SP directly from the previous window.  */
-             int regnum = AREG_NUMBER
-                            (gdbarch_tdep (gdbarch)->a0_base + 1,
+             int regnum = areg_number
+                            (gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
                              cache->wd.wb);
 
              cache->prev_sp = xtensa_read_register (regnum);
@@ -1163,8 +1168,8 @@ xtensa_frame_this_id (struct frame_info *next_frame,
     xtensa_frame_cache (next_frame, this_cache);
   struct frame_id id;
 
-  DEBUGTRACE ("xtensa_frame_this_id (next 0x%08x, *this 0x%08x)\n",
-             (unsigned int) next_frame, (unsigned int) *this_cache);
+  DEBUGTRACE ("xtensa_frame_this_id (next 0x%lx, *this 0x%lx)\n",
+             (unsigned long) next_frame, (unsigned long) *this_cache);
 
   if (cache->prev_sp == 0)
     return;
@@ -1244,11 +1249,11 @@ xtensa_frame_prev_register (struct frame_info *next_frame,
   CORE_ADDR saved_reg = 0;
   int done = 1;
 
-  DEBUGTRACE ("xtensa_frame_prev_register (next 0x%08x, "
-             "*this 0x%08x, regnum %d (%s), ...)\n",
-             (unsigned int) next_frame,
-             *this_cache ? (unsigned int) *this_cache : 0, regnum,
-             xtensa_register_name (regnum));
+  DEBUGTRACE ("xtensa_frame_prev_register (next 0x%lx, "
+             "*this 0x%lx, regnum %d (%s), ...)\n",
+             (unsigned long) next_frame,
+             *this_cache ? (unsigned long) *this_cache : 0, regnum,
+             xtensa_register_name (gdbarch, regnum));
 
   if (regnum ==gdbarch_pc_regnum (gdbarch))
     saved_reg = cache->ra;
@@ -1290,7 +1295,7 @@ xtensa_frame_prev_register (struct frame_info *next_frame,
       /* Convert A-register numbers to AR-register numbers.  */
       if (regnum >= gdbarch_tdep (gdbarch)->a0_base + 0
           && regnum <= gdbarch_tdep (gdbarch)->a0_base + 15)
-       regnum = AREG_NUMBER (regnum, cache->wd.wb);
+       regnum = areg_number (gdbarch, regnum, cache->wd.wb);
 
       /* Check if AR-register has been saved to stack.  */
       if (regnum >= gdbarch_tdep (gdbarch)->ar_base
@@ -1417,7 +1422,7 @@ xtensa_extract_return_value (struct type *type,
     {
       /* First, we have to find the caller window in the register file.  */
       regcache_raw_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc);
-      callsize = extract_call_winsize (pc);
+      callsize = extract_call_winsize (gdbarch, pc);
 
       /* On Xtensa, we can return up to 4 words (or 2 for call12).  */
       if (len > (callsize > 8 ? 8 : 16))
@@ -1428,7 +1433,8 @@ xtensa_extract_return_value (struct type *type,
         register (A2) in the caller window.  */
       regcache_raw_read_unsigned
        (regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb);
-      areg = AREG_NUMBER(gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
+      areg = areg_number (gdbarch,
+                         gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
     }
   else
     {
@@ -1471,13 +1477,14 @@ xtensa_store_return_value (struct type *type,
       regcache_raw_read_unsigned 
        (regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb);
       regcache_raw_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc);
-      callsize = extract_call_winsize (pc);
+      callsize = extract_call_winsize (gdbarch, pc);
 
       if (len > (callsize > 8 ? 8 : 16))
        internal_error (__FILE__, __LINE__,
                        _("unimplemented for this length: %d"),
                        TYPE_LENGTH (type));
-      areg = AREG_NUMBER (gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
+      areg = areg_number (gdbarch,
+                         gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
 
       DEBUGTRACE ("[xtensa_store_return_value] callsize %d wb %d\n",
               callsize, (int) wb);
@@ -1582,8 +1589,8 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
         {
          struct value *arg = args[i];
          struct type *arg_type = check_typedef (value_type (arg));
-         fprintf_unfiltered (gdb_stdlog, "%2d: 0x%08x %3d ",
-                             i, (int) arg, TYPE_LENGTH (arg_type));
+         fprintf_unfiltered (gdb_stdlog, "%2d: 0x%lx %3d ",
+                             i, (unsigned long) arg, TYPE_LENGTH (arg_type));
          switch (TYPE_CODE (arg_type))
            {
            case TYPE_CODE_INT:
@@ -1596,8 +1603,8 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
              fprintf_unfiltered (gdb_stdlog, "%3d", TYPE_CODE (arg_type));
              break;
            }
-         fprintf_unfiltered (gdb_stdlog, " 0x%08x\n",
-                             (unsigned int) value_contents (arg));
+         fprintf_unfiltered (gdb_stdlog, " 0x%lx\n",
+                             (unsigned long) value_contents (arg));
        }
     }
 
@@ -1658,7 +1665,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
       size = (size + info->align - 1) & ~(info->align - 1);
       onstack_size = (onstack_size + info->align - 1) & ~(info->align - 1);
 
-      if (size + info->length > REGISTER_SIZE * ARG_NOF)
+      if (size + info->length > REGISTER_SIZE * ARG_NOF (gdbarch))
        {
          info->onstack = 1;
          info->u.offset = onstack_size;
@@ -1667,7 +1674,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
       else
        {
          info->onstack = 0;
-         info->u.regno = ARG_1ST + size / REGISTER_SIZE;
+         info->u.regno = ARG_1ST (gdbarch) + size / REGISTER_SIZE;
        }
       size += info->length;
     }
@@ -1688,7 +1695,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
   if (struct_return)
     {
       store_unsigned_integer (buf, REGISTER_SIZE, struct_addr);
-      regcache_cooked_write (regcache, ARG_1ST, buf);
+      regcache_cooked_write (regcache, ARG_1ST (gdbarch), buf);
     }
 
   for (i = 0; i < nargs; i++)
@@ -1788,7 +1795,8 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
 #define DENSITY_LITTLE_BREAKPOINT { 0x2d, 0xf0 }
 
 static const unsigned char *
-xtensa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
+xtensa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
+                          int *lenptr)
 {
   static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
   static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
@@ -1797,9 +1805,9 @@ xtensa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 
   DEBUGTRACE ("xtensa_breakpoint_from_pc (pc = 0x%08x)\n", (int) *pcptr);
 
-  if (gdbarch_tdep (current_gdbarch)->isa_use_density_instructions)
+  if (gdbarch_tdep (gdbarch)->isa_use_density_instructions)
     {
-      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
        {
          *lenptr = sizeof (density_big_breakpoint);
          return density_big_breakpoint;
@@ -1812,7 +1820,7 @@ xtensa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
     }
   else
     {
-      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
        {
          *lenptr = sizeof (big_breakpoint);
          return big_breakpoint;
@@ -2388,7 +2396,7 @@ call0_frame_cache (struct frame_info *next_frame,
 /* #define DONT_SKIP_PROLOGUE  */
 
 CORE_ADDR
-xtensa_skip_prologue (CORE_ADDR start_pc)
+xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 {
   struct symtab_and_line prologue_sal;
   CORE_ADDR body_pc;
This page took 0.033991 seconds and 4 git commands to generate.