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:
parent
221e394aa4
commit
98689b2504
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue