#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include "linux-nat.h"
#include "gdb_assert.h"
#include "gdb_string.h"
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/procfs.h>
#include "gregset.h"
#include "m32r-tdep.h"
#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
static int regmap[] = {
4, 5, 6, 7, 0, 1, 2, 8,
9, 10, 11, 12, 13, 24, 25, 23,
19, 19, 26, 23, 22, 20, 16, 15
};
#define PSW_REGMAP 19
#define BBPSW_REGMAP 21
#define SPU_REGMAP 23
#define SPI_REGMAP 26
#define GETREGS_SUPPLIES(regno) (0 <= (regno) && (regno) <= M32R_LINUX_NUM_REGS)
void
supply_gregset (elf_gregset_t * gregsetp)
{
elf_greg_t *regp = (elf_greg_t *) gregsetp;
int i;
unsigned long psw, bbpsw;
psw = *(regp + PSW_REGMAP);
bbpsw = *(regp + BBPSW_REGMAP);
for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
{
switch (i)
{
case PSW_REGNUM:
*(regp + regmap[i]) =
((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
break;
case CBR_REGNUM:
*(regp + regmap[i]) = ((psw >> 8) & 1);
break;
}
if (i != M32R_SP_REGNUM)
regcache_raw_supply (current_regcache, i, regp + regmap[i]);
else if (psw & 0x8000)
regcache_raw_supply (current_regcache, i, regp + SPU_REGMAP);
else
regcache_raw_supply (current_regcache, i, regp + SPI_REGMAP);
}
}
static void
fetch_regs (int tid)
{
elf_gregset_t regs;
if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
perror_with_name (_("Couldn't get registers"));
supply_gregset (®s);
}
void
fill_gregset (elf_gregset_t * gregsetp, int regno)
{
elf_greg_t *regp = (elf_greg_t *) gregsetp;
int i;
unsigned long psw, bbpsw, tmp;
psw = *(regp + PSW_REGMAP);
bbpsw = *(regp + BBPSW_REGMAP);
for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
{
if (regno != -1 && regno != i)
continue;
if (i == CBR_REGNUM || i == PSW_REGNUM)
continue;
if (i == SPU_REGNUM || i == SPI_REGNUM)
continue;
if (i != M32R_SP_REGNUM)
regcache_raw_collect (current_regcache, i, regp + regmap[i]);
else if (psw & 0x8000)
regcache_raw_collect (current_regcache, i, regp + SPU_REGMAP);
else
regcache_raw_collect (current_regcache, i, regp + SPI_REGMAP);
}
}
static void
store_regs (int tid, int regno)
{
elf_gregset_t regs;
if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0)
perror_with_name (_("Couldn't get registers"));
fill_gregset (®s, regno);
if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0)
perror_with_name (_("Couldn't write registers"));
}
void
supply_fpregset (gdb_fpregset_t *fpregs)
{
}
void
fill_fpregset (gdb_fpregset_t *fpregs, int regno)
{
}
void
fetch_inferior_registers (int regno)
{
int tid;
tid = TIDGET (inferior_ptid);
if (tid == 0)
tid = PIDGET (inferior_ptid);
if (regno == -1 || GETREGS_SUPPLIES (regno))
{
fetch_regs (tid);
return;
}
internal_error (__FILE__, __LINE__,
_("Got request for bad register number %d."), regno);
}
void
store_inferior_registers (int regno)
{
int tid;
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid);
if (regno == -1 || GETREGS_SUPPLIES (regno))
{
store_regs (tid, regno);
return;
}
internal_error (__FILE__, __LINE__,
_("Got request to store bad register number %d."), regno);
}