target: e2k: HACK: Add stack for USD registers.

CPU must restore `USD` after calls but I don't know how it should be implemented.
This commit is contained in:
Denis Drakhnia 2020-12-11 00:47:15 +02:00 committed by Denis Drakhnia
parent 42776dbe37
commit 83e2503867
5 changed files with 24 additions and 1 deletions

View File

@ -122,6 +122,7 @@ void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
env->psp = regs->psp; env->psp = regs->psp;
env->usd_lo = regs->usd_lo; env->usd_lo = regs->usd_lo;
env->usd_hi = regs->usd_hi; env->usd_hi = regs->usd_hi;
env->sbr = regs->sbr;
e2k_break_save_state(env); e2k_break_save_state(env);
} }

View File

@ -23,7 +23,7 @@ struct target_pt_regs {
/* special registers */ /* special registers */
uint64_t wd; // Current window descriptor (WD) uint64_t wd; // Current window descriptor (WD)
uint32_t sbr; // User Stack Base Register (USBR/SBR) uint64_t sbr; // User Stack Base Register (USBR/SBR)
// SBR - contains the base (top) virtual address of the current User Stack area. // SBR - contains the base (top) virtual address of the current User Stack area.
// uint64_t tr; // current type register // uint64_t tr; // current type register

View File

@ -1642,6 +1642,8 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
abi_ulong stack_size = infop->start_stack - infop->stack_limit; abi_ulong stack_size = infop->start_stack - infop->stack_limit;
regs->ip = infop->entry; regs->ip = infop->entry;
regs->sbr = e2k_mmap(TARGET_PAGE_SIZE);
regs->usd_hi = stack_size << 32; regs->usd_hi = stack_size << 32;
regs->usd_lo = (0x1800UL << 48) | infop->start_stack; regs->usd_lo = (0x1800UL << 48) | infop->start_stack;

View File

@ -476,6 +476,7 @@ typedef struct CPUArchState {
uint64_t lsr; /* loop status register */ uint64_t lsr; /* loop status register */
uint64_t sbr;
uint64_t usd_lo; uint64_t usd_lo;
uint64_t usd_hi; uint64_t usd_hi;

View File

@ -44,8 +44,25 @@ static inline uint64_t stack_pop(CPUE2KState *env, E2KStackState *s)
#define ps_push(env, value) stack_push(env, &env->psp, (value)) #define ps_push(env, value) stack_push(env, &env->psp, (value))
#define ps_pop(env) stack_pop(env, &env->psp) #define ps_pop(env) stack_pop(env, &env->psp)
/* FIXME: I don't know how exactly it should works. */
static inline void sbr_push(CPUE2KState *env)
{
cpu_stq_le_data(env, env->sbr, env->usd_lo);
cpu_stq_le_data(env, env->sbr + 8, env->usd_hi);
env->sbr += 16;
}
static inline void sbr_pop(CPUE2KState *env)
{
env->sbr -= 16;
env->usd_hi = cpu_ldq_le_data(env, env->sbr + 8);
env->usd_lo = cpu_ldq_le_data(env, env->sbr);
}
static void proc_chain_save(CPUE2KState *env, int wbs) static void proc_chain_save(CPUE2KState *env, int wbs)
{ {
sbr_push(env);
env->pshtp.index += wbs * 2; env->pshtp.index += wbs * 2;
env->cr1.wbs = wbs; env->cr1.wbs = wbs;
@ -81,6 +98,8 @@ static inline void proc_chain_restore(CPUE2KState *env)
env->wd.fx = env->cr1.wfx; env->wd.fx = env->cr1.wfx;
env->pshtp.index -= wbs * 2; env->pshtp.index -= wbs * 2;
sbr_pop(env);
} }
static inline void ps_spill(CPUE2KState *env, bool force, bool force_fx) static inline void ps_spill(CPUE2KState *env, bool force, bool force_fx)