target: e2k: Reorg cr1.

This commit is contained in:
Denis Drakhnia 2020-11-26 21:14:40 +02:00 committed by Denis Drakhnia
parent 5601f6e45a
commit 2ec66c49c5
4 changed files with 92 additions and 66 deletions

View File

@ -45,11 +45,8 @@ static void e2k_cpu_reset(DeviceState *dev)
memset(env, 0, offsetof(CPUE2KState, end_reset_fields));
env->wptr = &env->wregs[0];
// FIXME: testing
env->cr1_lo = 0x4dUL << 56; // FIXME: some flags for testing
env->cr1_lo = SET_FIELD(env->cr1_lo, 4, CR1_LO_WPSZ_OFF, CR1_LO_WPSZ_LEN);
env->cr1_lo = SET_FIELD(env->cr1_lo, 4, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);
env->cr1.wpsz = 4;
env->cr1.wbs = 4;
env->wd.base = 0;
env->wd.size = 8;
env->wd.psize = 8;
@ -58,6 +55,8 @@ static void e2k_cpu_reset(DeviceState *dev)
env->bn.cur = 0;
/* Based predicate window must not be zero. */
env->bp.size = 1;
// FIXME: testing
env->idr = 0x3a207; // mimic 8c
}
@ -98,14 +97,6 @@ static const struct e2k_def_t e2k_defs[] = {
}
};
static inline void cpu_dump_state_wd(CPUE2KState *env, FILE *f, int flags)
{
int wbs = GET_FIELD(env->cr1_lo, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);
int wsz = GET_FIELD(env->cr1_lo, CR1_LO_WPSZ_OFF, CR1_LO_WPSZ_LEN);
qemu_fprintf(f, "wbs = %d, wsz = %d\n", wbs, wsz);
}
static inline void cpu_dump_state_br(CPUE2KState *env, FILE *f, int flags)
{
uint32_t br = e2k_state_br(env);
@ -128,8 +119,8 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
qemu_fprintf(f, "cr0_lo/pf = 0x%016lx\n", env->cr0_lo);
qemu_fprintf(f, "cr0_hi/ip = 0x%016lx\n", env->cr0_hi);
qemu_fprintf(f, " cr1_lo = 0x%016lx\n", env->cr1_lo);
qemu_fprintf(f, " cr1_hi = 0x%016lx\n", env->cr1_hi);
qemu_fprintf(f, " cr1_lo = 0x%016lx\n", e2k_state_cr1_lo(env));
qemu_fprintf(f, " cr1_hi = 0x%016lx\n", e2k_state_cr1_hi(env));
qemu_fprintf(f, " pcsp_lo = 0x%016lx\n", e2k_state_pcsp_lo(env));
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));
@ -137,7 +128,6 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
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_wd(env, f, flags);
cpu_dump_state_br(env, f, flags);
for (i = 0; i < WREGS_SIZE; i++) {

View File

@ -252,7 +252,7 @@ typedef struct {
uint8_t wbs;
uint8_t psr;
bool wdbl;
} E2KControlReg1State;
} E2KCr1State;
typedef struct {
void *base;
@ -282,6 +282,8 @@ typedef struct CPUArchState {
uint64_t wregs[WREGS_SIZE]; /* window registers */
uint64_t *wptr;
E2KCr1State cr1;
/* Procedure chain info = cr0_lo, cr0_hi, cr1_lo, cr1_hi */
E2KPcsState pcsp;
uint64_t pcshtp;
@ -304,19 +306,12 @@ typedef struct CPUArchState {
target_ulong ct_cond;
union {
struct {
union {
uint64_t pf; /* predicate file */
uint64_t cr0_lo;
};
union {
target_ulong ip; /* instruction address */
uint64_t cr0_hi;
};
uint64_t cr1_lo;
uint64_t cr1_hi;
};
uint64_t proc_chain[4];
uint64_t pf; /* predicate file */
uint64_t cr0_lo;
};
union {
target_ulong ip; /* instruction address */
uint64_t cr0_hi;
};
target_ulong nip; /* next instruction address */
@ -461,35 +456,56 @@ static inline void e2k_state_br_set(CPUE2KState *env, uint32_t br)
bp->cur = extract32(br, BR_PCUR_OFF, BR_PCUR_LEN);
}
static inline int e2k_state_cr1_wbs_get(CPUE2KState *env)
static inline uint64_t e2k_state_cr1_lo(CPUE2KState *env)
{
return GET_FIELD(env->cr1_lo, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);
E2KCr1State *cr1 = &env->cr1;
uint64_t ret = 0;
ret = deposit64(ret, CR1_LO_TR_OFF, CR1_LO_TR_LEN, cr1->tr);
ret = deposit64(ret, CR1_LO_EIN_OFF, CR1_LO_EIN_LEN, cr1->ein);
ret = deposit64(ret, CR1_LO_SS_OFF, 1, cr1->ss);
ret = deposit64(ret, CR1_LO_WFX_OFF, 1, cr1->wfx);
ret = deposit64(ret, CR1_LO_WPSZ_OFF, CR1_LO_WPSZ_LEN, cr1->wpsz);
ret = deposit64(ret, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN, cr1->wbs);
ret = deposit64(ret, CR1_LO_CUIR_OFF, CR1_LO_CUIR_LEN, cr1->cuir);
ret = deposit64(ret, CR1_LO_PSR_OFF, CR1_LO_PSR_LEN, cr1->psr);
return ret;
}
static inline void e2k_state_cr1_wbs_set(CPUE2KState *env, int wbs)
static inline void e2k_state_cr1_lo_set(CPUE2KState *env, uint64_t lo)
{
env->cr1_lo = SET_FIELD(env->cr1_lo, wbs, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);
E2KCr1State *cr1 = &env->cr1;
cr1->tr = extract64(lo, CR1_LO_TR_OFF, CR1_LO_TR_LEN);
cr1->ein = extract64(lo, CR1_LO_EIN_OFF, CR1_LO_EIN_LEN);
cr1->ss = extract64(lo, CR1_LO_SS_OFF, 1);
cr1->wfx = extract64(lo, CR1_LO_WFX_OFF, 1);
cr1->wpsz = extract64(lo, CR1_LO_WPSZ_OFF, CR1_LO_WPSZ_LEN);
cr1->wbs = extract64(lo, CR1_LO_WBS_OFF, CR1_LO_WBS_LEN);
cr1->cuir = extract64(lo, CR1_LO_CUIR_OFF, CR1_LO_CUIR_LEN);
cr1->psr = extract64(lo, CR1_LO_PSR_OFF, CR1_LO_PSR_LEN);
}
static inline int e2k_state_cr1_wpsz_get(CPUE2KState *env)
static inline uint64_t e2k_state_cr1_hi(CPUE2KState *env)
{
return GET_FIELD(env->cr1_lo, CR1_LO_WPSZ_OFF, CR1_LO_WPSZ_LEN);
E2KCr1State *cr1 = &env->cr1;
uint64_t ret = 0;
ret = deposit64(ret, CR1_HI_BR_OFF, CR1_HI_BR_LEN, cr1->br);
ret = deposit64(ret, CR1_HI_WDBL_OFF, 1, cr1->wdbl);
ret = deposit64(ret, CR1_HI_USSZ_OFF, CR1_HI_USSZ_LEN, cr1->ussz);
return ret;
}
static inline void e2k_state_cr1_wpsz_set(CPUE2KState *env, int wpsz)
static inline void e2k_state_cr1_hi_set(CPUE2KState *env, uint64_t hi)
{
env->cr1_lo = SET_FIELD(env->cr1_lo, wpsz, CR1_LO_WPSZ_OFF,
CR1_LO_WPSZ_LEN);
}
E2KCr1State *cr1 = &env->cr1;
static inline uint32_t e2k_state_cr1_br_get(CPUE2KState *env)
{
return GET_FIELD(env->cr1_hi, CR1_HI_BR_OFF, CR1_HI_BR_LEN);
}
static inline void e2k_state_cr1_br_set(CPUE2KState *env, uint32_t br)
{
env->cr1_hi = SET_FIELD(env->cr1_hi, br, CR1_HI_BR_OFF, CR1_HI_BR_LEN);
cr1->br = extract64(hi, CR1_HI_BR_OFF, CR1_HI_BR_LEN);
cr1->wdbl = extract64(hi, CR1_HI_WDBL_OFF, 1);
cr1->ussz = extract64(hi, CR1_HI_USSZ_OFF, CR1_HI_USSZ_LEN);
}
#include "exec/cpu-all.h"

View File

@ -62,8 +62,8 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
case 51: return gdb_get_reg64(mem_buf, e2k_state_pshtp(env)); // pshtp
case 52: return gdb_get_reg64(mem_buf, env->cr0_lo); // cr0_lo
case 53: return gdb_get_reg64(mem_buf, env->cr0_hi); // cr0_hi
case 54: return gdb_get_reg64(mem_buf, env->cr1_lo); // cr1_lo
case 55: return gdb_get_reg64(mem_buf, env->cr1_hi); // cr1_hi
case 54: return gdb_get_reg64(mem_buf, e2k_state_cr1_lo(env)); // cr1_lo
case 55: return gdb_get_reg64(mem_buf, e2k_state_cr1_hi(env)); // cr1_hi
case 56: return gdb_get_reg64(mem_buf, 0); // cwd
case 57: return gdb_get_reg64(mem_buf, e2k_state_pcsp_lo(env)); // pcsp_lo
case 58: return gdb_get_reg64(mem_buf, e2k_state_pcsp_hi(env)); // pcsp_hi

View File

@ -16,36 +16,57 @@ static inline void reset_ctprs(CPUE2KState *env)
}
}
static inline void save_proc_chain_info(CPUE2KState *env, uint64_t buf[4])
{
env->cr1.br = e2k_state_br(env);
env->cr1.wpsz = env->wd.psize / 2;
buf[0] = env->cr0_lo;
buf[1] = env->cr0_hi;
buf[2] = e2k_state_cr1_lo(env);
buf[3] = e2k_state_cr1_hi(env);
}
static inline void restore_proc_chain_info(CPUE2KState *env, uint64_t buf[4])
{
e2k_state_cr1_hi_set(env, buf[3]);
e2k_state_cr1_lo_set(env, buf[2]);
env->cr0_hi = buf[1];
env->cr0_lo = buf[0];
env->wd.psize = env->cr1.wpsz * 2;
e2k_state_br_set(env, env->cr1.br);
}
static void pcs_push(CPUE2KState *env, int wbs)
{
size_t size = sizeof(env->proc_chain);
uint64_t buf[4];
if (env->pcsp.size < (env->pcsp.index + size)) {
if (env->pcsp.size < (env->pcsp.index + 32)) {
helper_raise_exception(env, E2K_EXCP_MAPERR);
return;
}
e2k_state_cr1_br_set(env, e2k_state_br(env));
e2k_state_cr1_wpsz_set(env, env->wd.psize / 2);
memcpy(env->pcsp.base + env->pcsp.index, env->proc_chain, size);
e2k_state_cr1_wbs_set(env, wbs);
// save proc chain
save_proc_chain_info(env, buf);
memcpy(env->pcsp.base + env->pcsp.index, buf, 32);
env->pcsp.index += size;
env->cr1.wbs = wbs;
env->pcsp.index += 32;
}
static void pcs_pop(CPUE2KState *env)
{
size_t size = sizeof(env->proc_chain);
uint64_t buf[4];
if (env->pcsp.index < size) {
if (env->pcsp.index < 32) {
helper_raise_exception(env, E2K_EXCP_MAPERR);
return;
}
env->pcsp.index -= size;
memcpy(env->proc_chain, env->pcsp.base + env->pcsp.index, size);
env->wd.psize = e2k_state_cr1_wpsz_get(env) * 2;
e2k_state_br_set(env, e2k_state_cr1_br_get(env));
env->pcsp.index -= 32;
memcpy(buf, env->pcsp.base + env->pcsp.index, 32);
restore_proc_chain_info(env, buf);
}
static void ps_push_nfx(CPUE2KState *env, unsigned int base, size_t len)
@ -149,7 +170,7 @@ void helper_return(CPUE2KState *env)
{
uint32_t new_wd_size, new_wd_base, wbs;
wbs = e2k_state_cr1_wbs_get(env);
wbs = env->cr1.wbs;
new_wd_size = env->wd.psize + wbs * 2;
new_wd_base = (env->wd.base - wbs * 2) % WREGS_SIZE;
@ -217,9 +238,8 @@ static void break_save_state(CPUE2KState *env)
void helper_break_restore_state(CPUE2KState *env)
{
int wbs;
int wbs = env->cr1.wbs;
wbs = e2k_state_cr1_wbs_get(env);
pcs_pop(env);
env->wd.size = wbs * 2;
env->wd.base = (env->wd.base - env->wd.size) % WREGS_SIZE;