2011-03-08 Maxim Grigoriev <maxim2405@gmail.com>

* xtensa-tdep.c (TX_PS): New.
	(windowing_enabled): Update to count for Call0 ABI.
	(xtensa_hextochar): New.
	(xtensa_init_reggroups): Make algorithm generic.
	(xtensa_frame_cache): Use TX_PS on Tiny Xtensa.
This commit is contained in:
Maxim Grigoriev 2011-03-09 00:55:09 +00:00
parent 221e394aa4
commit 98689b2504
2 changed files with 52 additions and 24 deletions

View File

@ -1,6 +1,14 @@
2011-03-08 Maxim Grigoriev <maxim2405@gmail.com>
* xtensa-tdep.h (XTENSA_MAX_COPROCESSOR) Update.
* xtensa-tdep.c (TX_PS): New.
(windowing_enabled): Update to count for Call0 ABI.
(xtensa_hextochar): New.
(xtensa_init_reggroups): Make algorithm generic.
(xtensa_frame_cache): Use TX_PS on Tiny Xtensa.
2011-03-08 Maxim Grigoriev <maxim2405@gmail.com>
* xtensa-tdep.h (XTENSA_MAX_COPROCESSOR): Update.
2011-03-08 Michael Snyder <msnyder@vmware.com>

View File

@ -91,6 +91,11 @@ static int xtensa_debug_level = 0;
#define CALLINC(ps) (((ps) & PS_CALLINC_MASK) >> PS_CALLINC_SHIFT)
#define WINSIZE(ra) (4 * (( (ra) >> 30) & 0x3))
/* On TX, hardware can be configured without Exception Option.
There is no PS register in this case. Inside XT-GDB, let us treat
it as a virtual read-only register always holding the same value. */
#define TX_PS 0x20
/* ABI-independent macros. */
#define ARG_NOF(gdbarch) \
(gdbarch_tdep (gdbarch)->call_abi \
@ -116,6 +121,16 @@ static int xtensa_debug_level = 0;
#define PS_WOE (1<<18)
#define PS_EXC (1<<4)
static inline int
windowing_enabled (struct gdbarch *gdbarch, unsigned int ps)
{
/* If we know CALL0 ABI is set explicitly, say it is Call0. */
if (gdbarch_tdep (gdbarch)->call_abi == CallAbiCall0Only)
return 0;
return ((ps & PS_EXC) == 0 && (ps & PS_WOE) != 0);
}
/* Convert a live A-register number to the corresponding AR-register
number. */
static int
@ -146,12 +161,6 @@ areg_number (struct gdbarch *gdbarch, int ar_regnum, unsigned int wb)
return (areg > 15) ? -1 : areg;
}
static inline int
windowing_enabled (CORE_ADDR ps)
{
return ((ps & PS_EXC) == 0 && (ps & PS_WOE) != 0);
}
/* Return the window size of the previous call to the function from which we
have just returned.
@ -692,6 +701,13 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
_("invalid register number %d"), regnum);
}
static inline char xtensa_hextochar (int xdigit)
{
static char hex[]="0123456789abcdef";
return hex[xdigit & 0x0f];
}
static struct reggroup *xtensa_ar_reggroup;
static struct reggroup *xtensa_user_reggroup;
static struct reggroup *xtensa_vectra_reggroup;
@ -700,18 +716,18 @@ static struct reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
static void
xtensa_init_reggroups (void)
{
int i;
char cpname[] = "cp0";
xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP);
xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP);
xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP);
xtensa_cp[0] = reggroup_new ("cp0", USER_REGGROUP);
xtensa_cp[1] = reggroup_new ("cp1", USER_REGGROUP);
xtensa_cp[2] = reggroup_new ("cp2", USER_REGGROUP);
xtensa_cp[3] = reggroup_new ("cp3", USER_REGGROUP);
xtensa_cp[4] = reggroup_new ("cp4", USER_REGGROUP);
xtensa_cp[5] = reggroup_new ("cp5", USER_REGGROUP);
xtensa_cp[6] = reggroup_new ("cp6", USER_REGGROUP);
xtensa_cp[7] = reggroup_new ("cp7", USER_REGGROUP);
for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
{
cpname[2] = xtensa_hextochar (i);
xtensa_cp[i] = reggroup_new (cpname, USER_REGGROUP);
}
}
static void
@ -1187,23 +1203,26 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int fp_regnum;
char op1;
int windowed;
int windowed, ps_regnum;
if (*this_cache)
return *this_cache;
ps = get_frame_register_unsigned (this_frame, gdbarch_ps_regnum (gdbarch));
windowed = windowing_enabled (ps);
pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
ps_regnum = gdbarch_ps_regnum (gdbarch);
ps = (ps_regnum >= 0)
? get_frame_register_unsigned (this_frame, ps_regnum) : TX_PS;
windowed = windowing_enabled (gdbarch, 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));
if (windowed)
{
char op1;
/* Get WINDOWBASE, WINDOWSTART, and PS registers. */
wb = get_frame_register_unsigned (this_frame,
gdbarch_tdep (gdbarch)->wb_regnum);
@ -1228,7 +1247,7 @@ xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
just about to execute ENTRY. SP hasn't been set yet.
We can assume any frame size, because it does not
matter, and, let's fake frame base in cache. */
cache->base = cache->prev_sp + 16;
cache->base = cache->prev_sp - 16;
cache->pc = pc;
cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff);
@ -1820,9 +1839,10 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch,
if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
{
ULONGEST val;
ra = (bp_addr & 0x3fffffff) | 0x40000000;
regcache_raw_read (regcache, gdbarch_ps_regnum (gdbarch), buf);
ps = extract_unsigned_integer (buf, 4, byte_order) & ~0x00030000;
regcache_raw_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch), &val);
ps = (unsigned long) val & ~0x00030000;
regcache_cooked_write_unsigned
(regcache, gdbarch_tdep (gdbarch)->a0_base + 4, ra);
regcache_cooked_write_unsigned (regcache,