2008-11-12 Tristan Gingold <gingold@adacore.com>
[binutils-gdb.git] / gdb / xtensa-tdep.c
index a6181dad27ed8f1191054cf6aba6cd36216549db..e70710acd23758c4822ed64881e9aad8a650254b 100644 (file)
@@ -211,15 +211,6 @@ xtensa_register_name (struct gdbarch *gdbarch, int regnum)
   return 0;
 }
 
-static unsigned long
-xtensa_read_register (int regnum)
-{
-  ULONGEST value;
-
-  regcache_raw_read_unsigned (get_current_regcache (), regnum, &value);
-  return (unsigned long) value;
-}
-
 /* Return the type of a register.  Create a new type, if necessary.  */
 
 static struct ctype_cache
@@ -238,11 +229,11 @@ xtensa_register_type (struct gdbarch *gdbarch, int regnum)
                    + gdbarch_tdep (gdbarch)->num_aregs)
       || (regnum >= gdbarch_tdep (gdbarch)->a0_base
       && regnum < gdbarch_tdep (gdbarch)->a0_base + 16))
-    return builtin_type_int;
+    return builtin_type (gdbarch)->builtin_int;
 
   if (regnum == gdbarch_pc_regnum (gdbarch)
       || regnum == gdbarch_tdep (gdbarch)->a0_base + 1)
-    return lookup_pointer_type (builtin_type_void);
+    return builtin_type (gdbarch)->builtin_data_ptr;
 
   /* Return the stored type for all other registers.  */
   else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
@@ -959,7 +950,7 @@ typedef struct xtensa_frame_cache
   CORE_ADDR base;      /* Stack pointer of this frame.  */
   CORE_ADDR pc;                /* PC at the entry point to the function.  */
   CORE_ADDR ra;                /* The raw return address (without CALLINC).  */
-  CORE_ADDR ps;                /* The PS register of the previous frame.  */
+  CORE_ADDR ps;                /* The PS register of this frame.  */
   CORE_ADDR prev_sp;   /* Stack Pointer of the previous frame.  */
   int call0;           /* It's a call0 framework (else windowed).  */
   union
@@ -1024,15 +1015,16 @@ static CORE_ADDR
 xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   gdb_byte buf[8];
+  CORE_ADDR pc;
 
   DEBUGTRACE ("xtensa_unwind_pc (next_frame = %p)\n", next_frame);
 
   frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
+  pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
 
-  DEBUGINFO ("[xtensa_unwind_pc] pc = 0x%08x\n", (unsigned int)
-            extract_typed_address (buf, builtin_type_void_func_ptr));
+  DEBUGINFO ("[xtensa_unwind_pc] pc = 0x%08x\n", (unsigned int) pc);
 
-  return extract_typed_address (buf, builtin_type_void_func_ptr);
+  return pc;
 }
 
 
@@ -1178,7 +1170,7 @@ done:
 static void
 call0_frame_cache (struct frame_info *this_frame,
                   xtensa_frame_cache_t *cache,
-                  CORE_ADDR pc);
+                  CORE_ADDR pc, CORE_ADDR litbase);
 
 static struct xtensa_frame_cache *
 xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
@@ -1186,7 +1178,6 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
   xtensa_frame_cache_t *cache;
   CORE_ADDR ra, wb, ws, pc, sp, ps;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  unsigned int ps_regnum = gdbarch_ps_regnum (gdbarch);
   unsigned int fp_regnum;
   char op1;
   int  windowed;
@@ -1194,14 +1185,14 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (*this_cache)
     return *this_cache;
 
-  windowed = windowing_enabled (xtensa_read_register (ps_regnum));
+  ps = get_frame_register_unsigned (this_frame, gdbarch_ps_regnum (gdbarch));
+  windowed = windowing_enabled (ps);
 
   /* Get pristine xtensa-frame.  */
   cache = xtensa_alloc_frame_cache (windowed);
   *this_cache = cache;
 
-  pc = get_frame_register_unsigned (this_frame,
-                                   gdbarch_pc_regnum (gdbarch));
+  pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
 
   if (windowed)
     {
@@ -1210,7 +1201,6 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
                                        gdbarch_tdep (gdbarch)->wb_regnum);
       ws = get_frame_register_unsigned (this_frame,
                                        gdbarch_tdep (gdbarch)->ws_regnum);
-      ps = get_frame_register_unsigned (this_frame, ps_regnum);
 
       op1 = read_memory_integer (pc, 1);
       if (XTENSA_IS_ENTRY (gdbarch, op1))
@@ -1303,13 +1293,17 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
                             (gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
                              cache->wd.wb);
 
-             cache->prev_sp = xtensa_read_register (regnum);
+             cache->prev_sp = get_frame_register_unsigned (this_frame, regnum);
            }
        }
     }
   else /* Call0 framework.  */
     {
-      call0_frame_cache (this_frame, cache, pc);
+      unsigned int litbase_regnum = gdbarch_tdep (gdbarch)->litbase_regnum;
+      CORE_ADDR litbase = (litbase_regnum == -1)
+       ? 0 : get_frame_register_unsigned (this_frame, litbase_regnum);
+
+      call0_frame_cache (this_frame, cache, pc, litbase);
       fp_regnum = cache->c0.fp_regnum;
     }
 
@@ -1684,9 +1678,10 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
        case TYPE_CODE_ENUM:
 
          /* Cast argument to long if necessary as the mask does it too.  */
-         if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+         if (TYPE_LENGTH (arg_type)
+             < TYPE_LENGTH (builtin_type (gdbarch)->builtin_long))
            {
-             arg_type = builtin_type_long;
+             arg_type = builtin_type (gdbarch)->builtin_long;
              arg = value_cast (arg_type, arg);
            }
          /* Aligment is equal to the type length for the basic types.  */
@@ -1696,15 +1691,16 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
        case TYPE_CODE_FLT:
 
          /* Align doubles correctly.  */
-         if (TYPE_LENGTH (arg_type) == TYPE_LENGTH (builtin_type_double))
-           info->align = TYPE_LENGTH (builtin_type_double);
+         if (TYPE_LENGTH (arg_type)
+             == TYPE_LENGTH (builtin_type (gdbarch)->builtin_double))
+           info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_double);
          else
-           info->align = TYPE_LENGTH (builtin_type_long);
+           info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
          break;
 
        case TYPE_CODE_STRUCT:
        default:
-         info->align = TYPE_LENGTH (builtin_type_long);
+         info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
          break;
        }
       info->length = TYPE_LENGTH (arg_type);
@@ -1981,9 +1977,9 @@ call0_classify_opcode (xtensa_isa isa, xtensa_opcode opc)
 static void
 call0_track_op (xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
                xtensa_insn_kind opclass, int nods, unsigned odv[],
-               CORE_ADDR pc, int spreg)
+               CORE_ADDR pc, CORE_ADDR litbase, int spreg)
 {
-  unsigned litbase, litaddr, litval;
+  unsigned litaddr, litval;
 
   switch (opclass)
     {
@@ -2033,10 +2029,6 @@ call0_track_op (xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
     case c0opc_l32r:
       /* 2 operands: dst, literal offset.  */
       gdb_assert (nods == 2);
-      /* litbase = xtensa_get_litbase (pc); can be also used.  */
-      litbase = (gdbarch_tdep (current_gdbarch)->litbase_regnum == -1)
-       ? 0 : xtensa_read_register
-               (gdbarch_tdep (current_gdbarch)->litbase_regnum);
       litaddr = litbase & 1
                  ? (litbase & ~1) + (signed)odv[1]
                  : (pc + 3  + (signed)odv[1]) & ~3;
@@ -2093,7 +2085,7 @@ call0_track_op (xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
       because they begin with default assumptions that analysis may change.  */
 
 static CORE_ADDR
-call0_analyze_prologue (CORE_ADDR start, CORE_ADDR pc,
+call0_analyze_prologue (CORE_ADDR start, CORE_ADDR pc, CORE_ADDR litbase,
                        int nregs, xtensa_c0reg_t rt[], int *call0)
 {
   CORE_ADDR ia;                    /* Current insn address in prologue.  */
@@ -2285,7 +2277,7 @@ call0_analyze_prologue (CORE_ADDR start, CORE_ADDR pc,
            }
 
          /* Track register movement and modification for this operation.  */
-         call0_track_op (rt, rtmp, opclass, nods, odv, ia, 1);
+         call0_track_op (rt, rtmp, opclass, nods, odv, ia, litbase, 1);
        }
     }
 done:
@@ -2300,7 +2292,7 @@ done:
 
 static void
 call0_frame_cache (struct frame_info *this_frame,
-                  xtensa_frame_cache_t *cache, CORE_ADDR pc)
+                  xtensa_frame_cache_t *cache, CORE_ADDR pc, CORE_ADDR litbase)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR start_pc;          /* The beginning of the function.  */
@@ -2313,7 +2305,7 @@ call0_frame_cache (struct frame_info *this_frame,
 
   if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
     {
-      body_pc = call0_analyze_prologue (start_pc, pc, C0_NREGS,
+      body_pc = call0_analyze_prologue (start_pc, pc, litbase, C0_NREGS,
                                        &cache->c0.c0_rt[0],
                                        &cache->call0);
     }
@@ -2487,7 +2479,7 @@ xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
     }
 
   /* No debug line info.  Analyze prologue for Call0 or simply skip ENTRY.  */
-  body_pc = call0_analyze_prologue(start_pc, 0, 0, NULL, NULL);
+  body_pc = call0_analyze_prologue(start_pc, 0, 0, 0, NULL, NULL);
   return body_pc != 0 ? body_pc : start_pc;
 }
 
@@ -2650,9 +2642,8 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_pc_regnum (gdbarch, tdep->pc_regnum);
   set_gdbarch_ps_regnum (gdbarch, tdep->ps_regnum);
 
-  /* Renumber registers for known formats (stab, dwarf, and dwarf2).  */
+  /* Renumber registers for known formats (stabs and dwarf2).  */
   set_gdbarch_stab_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
-  set_gdbarch_dwarf_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
 
   /* We provide our own function to get register information.  */