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> 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> 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 CALLINC(ps) (((ps) & PS_CALLINC_MASK) >> PS_CALLINC_SHIFT)
#define WINSIZE(ra) (4 * (( (ra) >> 30) & 0x3)) #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. */ /* ABI-independent macros. */
#define ARG_NOF(gdbarch) \ #define ARG_NOF(gdbarch) \
(gdbarch_tdep (gdbarch)->call_abi \ (gdbarch_tdep (gdbarch)->call_abi \
@ -116,6 +121,16 @@ static int xtensa_debug_level = 0;
#define PS_WOE (1<<18) #define PS_WOE (1<<18)
#define PS_EXC (1<<4) #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 /* Convert a live A-register number to the corresponding AR-register
number. */ number. */
static int static int
@ -146,12 +161,6 @@ areg_number (struct gdbarch *gdbarch, int ar_regnum, unsigned int wb)
return (areg > 15) ? -1 : areg; 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 /* Return the window size of the previous call to the function from which we
have just returned. have just returned.
@ -692,6 +701,13 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
_("invalid register number %d"), regnum); _("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_ar_reggroup;
static struct reggroup *xtensa_user_reggroup; static struct reggroup *xtensa_user_reggroup;
static struct reggroup *xtensa_vectra_reggroup; static struct reggroup *xtensa_vectra_reggroup;
@ -700,18 +716,18 @@ static struct reggroup *xtensa_cp[XTENSA_MAX_COPROCESSOR];
static void static void
xtensa_init_reggroups (void) xtensa_init_reggroups (void)
{ {
int i;
char cpname[] = "cp0";
xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP); xtensa_ar_reggroup = reggroup_new ("ar", USER_REGGROUP);
xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP); xtensa_user_reggroup = reggroup_new ("user", USER_REGGROUP);
xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP); xtensa_vectra_reggroup = reggroup_new ("vectra", USER_REGGROUP);
xtensa_cp[0] = reggroup_new ("cp0", USER_REGGROUP); for (i = 0; i < XTENSA_MAX_COPROCESSOR; i++)
xtensa_cp[1] = reggroup_new ("cp1", USER_REGGROUP); {
xtensa_cp[2] = reggroup_new ("cp2", USER_REGGROUP); cpname[2] = xtensa_hextochar (i);
xtensa_cp[3] = reggroup_new ("cp3", USER_REGGROUP); xtensa_cp[i] = reggroup_new (cpname, 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);
} }
static void 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); struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int fp_regnum; unsigned int fp_regnum;
char op1; int windowed, ps_regnum;
int windowed;
if (*this_cache) if (*this_cache)
return *this_cache; return *this_cache;
ps = get_frame_register_unsigned (this_frame, gdbarch_ps_regnum (gdbarch)); pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
windowed = windowing_enabled (ps); 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. */ /* Get pristine xtensa-frame. */
cache = xtensa_alloc_frame_cache (windowed); cache = xtensa_alloc_frame_cache (windowed);
*this_cache = cache; *this_cache = cache;
pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
if (windowed) if (windowed)
{ {
char op1;
/* Get WINDOWBASE, WINDOWSTART, and PS registers. */ /* Get WINDOWBASE, WINDOWSTART, and PS registers. */
wb = get_frame_register_unsigned (this_frame, wb = get_frame_register_unsigned (this_frame,
gdbarch_tdep (gdbarch)->wb_regnum); 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. just about to execute ENTRY. SP hasn't been set yet.
We can assume any frame size, because it does not We can assume any frame size, because it does not
matter, and, let's fake frame base in cache. */ 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->pc = pc;
cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff); 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) if (gdbarch_tdep (gdbarch)->call_abi != CallAbiCall0Only)
{ {
ULONGEST val;
ra = (bp_addr & 0x3fffffff) | 0x40000000; ra = (bp_addr & 0x3fffffff) | 0x40000000;
regcache_raw_read (regcache, gdbarch_ps_regnum (gdbarch), buf); regcache_raw_read_unsigned (regcache, gdbarch_ps_regnum (gdbarch), &val);
ps = extract_unsigned_integer (buf, 4, byte_order) & ~0x00030000; ps = (unsigned long) val & ~0x00030000;
regcache_cooked_write_unsigned regcache_cooked_write_unsigned
(regcache, gdbarch_tdep (gdbarch)->a0_base + 4, ra); (regcache, gdbarch_tdep (gdbarch)->a0_base + 4, ra);
regcache_cooked_write_unsigned (regcache, regcache_cooked_write_unsigned (regcache,