target: e2k: Return aligned pointer from getsp.
This commit is contained in:
parent
83e2503867
commit
381868f71a
|
@ -120,8 +120,8 @@ void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
|
|||
env->ip = regs->ip;
|
||||
env->pcsp = regs->pcsp;
|
||||
env->psp = regs->psp;
|
||||
env->usd_lo = regs->usd_lo;
|
||||
env->usd_hi = regs->usd_hi;
|
||||
env->usd.lo = regs->usd_lo;
|
||||
env->usd.hi = regs->usd_hi;
|
||||
env->sbr = regs->sbr;
|
||||
|
||||
e2k_break_save_state(env);
|
||||
|
|
|
@ -7,9 +7,11 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
|
|||
unsigned flags)
|
||||
{
|
||||
if (newsp) {
|
||||
uint64_t size = 0x20000UL;
|
||||
env->usd_hi = size << 32;
|
||||
env->usd_lo = (0x1800UL << 48) | newsp;
|
||||
// FIXME: what size must be?
|
||||
env->usd.size = 0x20000;
|
||||
env->usd.base = newsp;
|
||||
env->usd.read = 1;
|
||||
env->usd.write = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +36,7 @@ static inline target_ulong cpu_get_tls(CPUE2KState *env)
|
|||
|
||||
static inline abi_ulong get_sp_from_cpustate(CPUE2KState *env)
|
||||
{
|
||||
return extract64(env->usd_lo, 0, 48);
|
||||
return env->usd.base;
|
||||
}
|
||||
|
||||
#endif /* E2K_TARGET_CPU_H */
|
||||
|
|
|
@ -164,8 +164,8 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
qemu_fprintf(f, " pcsp_hi = 0x%016lx\n", e2k_state_pcsp_hi(env));
|
||||
qemu_fprintf(f, " psp_lo = 0x%016lx\n", e2k_state_psp_lo(env));
|
||||
qemu_fprintf(f, " psp_hi = 0x%016lx\n", e2k_state_psp_hi(env));
|
||||
qemu_fprintf(f, " usd_lo = 0x%016lx\n", env->usd_lo);
|
||||
qemu_fprintf(f, " usd_hi = 0x%016lx\n", env->usd_hi);
|
||||
qemu_fprintf(f, " usd_lo = 0x%016lx\n", env->usd.lo);
|
||||
qemu_fprintf(f, " usd_hi = 0x%016lx\n", env->usd.hi);
|
||||
qemu_fprintf(f, " lsr = 0x%016lx\n", env->lsr);
|
||||
cpu_dump_state_br(env, f, flags);
|
||||
|
||||
|
|
|
@ -452,6 +452,26 @@ typedef union {
|
|||
} E2KCtpr;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
uint64_t lo;
|
||||
struct {
|
||||
uint64_t base: 48;
|
||||
uint64_t unused1: 10;
|
||||
uint64_t protected: 1;
|
||||
uint64_t read: 1;
|
||||
uint64_t write: 1;
|
||||
uint64_t unsued2: 3;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint64_t hi;
|
||||
struct {
|
||||
uint64_t curptr: 32;
|
||||
uint64_t size: 32;
|
||||
};
|
||||
};
|
||||
} E2KUserStackDesc;
|
||||
|
||||
typedef struct CPUArchState {
|
||||
/* register file */
|
||||
uint64_t regs[E2K_REG_COUNT]; /* registers */
|
||||
|
@ -460,6 +480,14 @@ typedef struct CPUArchState {
|
|||
uint64_t *rptr; /* pointer to regs */
|
||||
uint64_t *tptr; /* pointer to tags */
|
||||
|
||||
union {
|
||||
uint64_t pregs; /* predicate file */
|
||||
uint64_t cr0_lo;
|
||||
};
|
||||
union {
|
||||
target_ulong ip; /* instruction address */
|
||||
uint64_t cr0_hi;
|
||||
};
|
||||
E2KCr1State cr1;
|
||||
|
||||
/* Procedure chain info = cr0_lo, cr0_hi, cr1_lo, cr1_hi */
|
||||
|
@ -477,21 +505,11 @@ typedef struct CPUArchState {
|
|||
uint64_t lsr; /* loop status register */
|
||||
|
||||
uint64_t sbr;
|
||||
uint64_t usd_lo;
|
||||
uint64_t usd_hi;
|
||||
E2KUserStackDesc usd;
|
||||
|
||||
/* control registers */
|
||||
E2KCtpr ctprs[3]; // Control Transfer Preparation Register (CTPR)
|
||||
target_ulong ct_cond;
|
||||
|
||||
union {
|
||||
uint64_t pregs; /* predicate file */
|
||||
uint64_t cr0_lo;
|
||||
};
|
||||
union {
|
||||
target_ulong ip; /* instruction address */
|
||||
uint64_t cr0_hi;
|
||||
};
|
||||
|
||||
target_ulong nip; /* next instruction address */
|
||||
|
||||
|
|
|
@ -55,8 +55,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||
case 44: return gdb_get_reg64(mem_buf, 0); // fpcr
|
||||
case 45: return gdb_get_reg64(mem_buf, 0); // fpsr
|
||||
case 46: return gdb_get_reg64(mem_buf, 0); // usbr
|
||||
case 47: return gdb_get_reg64(mem_buf, env->usd_lo); // usd_lo
|
||||
case 48: return gdb_get_reg64(mem_buf, env->usd_hi); // usd_hi
|
||||
case 47: return gdb_get_reg64(mem_buf, env->usd.lo); // usd_lo
|
||||
case 48: return gdb_get_reg64(mem_buf, env->usd.hi); // usd_hi
|
||||
case 49: return gdb_get_reg64(mem_buf, e2k_state_psp_lo(env)); // psp_lo
|
||||
case 50: return gdb_get_reg64(mem_buf, e2k_state_psp_hi(env)); // psp_hi
|
||||
case 51: return gdb_get_reg64(mem_buf, e2k_state_pshtp(env)); // pshtp
|
||||
|
|
|
@ -47,16 +47,16 @@ static inline uint64_t stack_pop(CPUE2KState *env, E2KStackState *s)
|
|||
/* 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);
|
||||
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);
|
||||
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)
|
||||
|
|
|
@ -34,9 +34,9 @@ static uint64_t* state_reg_ptr(CPUE2KState *env, int idx)
|
|||
{
|
||||
switch (idx) {
|
||||
/* FIXME: user cannot write */
|
||||
case 0x2c: return &env->usd_hi; /* %usd.hi */
|
||||
case 0x2c: return &env->usd.hi; /* %usd.hi */
|
||||
/* FIXME: user cannot write */
|
||||
case 0x2d: return &env->usd_lo; /* %usd.lo */
|
||||
case 0x2d: return &env->usd.lo; /* %usd.lo */
|
||||
case 0x51: return &env->ip; /* %cr1.hi */
|
||||
case 0x53: return &env->pregs; /* %cr1.lo */
|
||||
case 0x80: return &env->upsr; /* %upsr */
|
||||
|
@ -108,14 +108,17 @@ void helper_state_reg_write_i32(CPUE2KState *env, int idx, uint32_t val)
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t helper_getsp(CPUE2KState *env, uint32_t src2) {
|
||||
uint64_t base = GET_FIELD(env->usd_lo, USD_LO_BASE_OFF, USD_LO_BASE_LEN);
|
||||
uint64_t helper_getsp(CPUE2KState *env, uint32_t src2)
|
||||
{
|
||||
int32_t s2 = src2 & ~0xf;
|
||||
uint32_t size = s2 >= 0 ? s2 : -s2;
|
||||
|
||||
base += (int32_t) src2;
|
||||
if (size > env->usd.size) {
|
||||
helper_raise_exception(env, E2K_EXCP_MAPERR);
|
||||
}
|
||||
|
||||
/* TODO: stack overflow */
|
||||
env->usd_lo = SET_FIELD(env->usd_lo, base, USD_LO_BASE_OFF,
|
||||
USD_LO_BASE_LEN);
|
||||
env->usd.base += s2;
|
||||
env->usd.size -= size;
|
||||
|
||||
return base;
|
||||
return env->usd.base;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue