/* Target-dependent code for the Xtensa port of GDB, the GNU debugger.
- Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GDB.
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
+ 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)
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
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;
}
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)
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;
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)
{
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))
(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;
}
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. */
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);
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)
{
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;
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. */
}
/* 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:
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. */
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);
}
}
/* 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;
}
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. */