e2k: Use one large array for registers.

Previously was used two separate arrays for low and
high halves of a register. Now we can pass direct
pointer to a register into helpers instead of copying
the halves into a temporary buffer and pass pointer to
that buffer.

Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
Denis Drakhnia 2021-02-22 16:32:15 +02:00
parent 8af9457a46
commit 46c1c9a6e1
11 changed files with 67 additions and 61 deletions

View File

@ -71,11 +71,13 @@ void cpu_loop(CPUE2KState *env)
switch (trapnr) {
case EXCP_SYSCALL: {
abi_ullong args[E2K_SYSCALL_MAX_ARGS] = { 0 };
int psize = MIN(E2K_SYSCALL_MAX_ARGS, env->wd.size);
int i, psize = MIN(E2K_SYSCALL_MAX_ARGS, env->wd.size);
abi_ulong ret;
// TODO: check what happens if env->wd.size is zero
memcpy(args, env->regs, psize * sizeof(args[0]));
for (i = 0; i < psize; i++) {
args[i] = env->regs[i].lo;
}
ret = do_syscall(env, args[0], args[1], args[2], args[3],
args[4], args[5], args[6], args[7], args[8]);
@ -86,7 +88,7 @@ void cpu_loop(CPUE2KState *env)
memset(env->tags, E2K_TAG_NON_NUMBER64,
psize * sizeof(env->tags[0]));
env->regs[0] = ret;
env->regs[0].lo = ret;
env->tags[0] = E2K_TAG_NUMBER64;
env->ip = E2K_SYSRET_ADDR;
}

View File

@ -216,7 +216,7 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
}
/* fake kernel frame */
env->regs[0] = frame_addr;
env->regs[0].lo = frame_addr;
env->tags[0] = E2K_TAG_NUMBER64;
env->wd.size = 2;
env->wd.psize = 0;
@ -225,15 +225,15 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
helper_signal_frame(env, 2, E2K_SIGRET_ADDR);
env->ip = ka->_sa_handler;
env->regs[0] = sig;
env->regs[0].lo = sig;
env->tags[0] = E2K_TAG_NUMBER64;
env->wd.size = 8;
if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) {
tswap_siginfo(&frame->info, info);
env->regs[1] = frame_addr + offsetof(struct target_sigframe, info);
env->regs[1].lo = frame_addr + offsetof(struct target_sigframe, info);
env->tags[1] = E2K_TAG_NUMBER64;
env->regs[2] = frame_addr + offsetof(struct target_sigframe, uc);
env->regs[2].lo = frame_addr + offsetof(struct target_sigframe, uc);
env->tags[2] = E2K_TAG_NUMBER64;
}
@ -292,7 +292,7 @@ long do_rt_sigreturn(CPUE2KState *env)
/* restore fake kernel frame */
helper_signal_return(env);
frame_addr = env->regs[0];
frame_addr = env->regs[0].lo;
trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {

View File

@ -61,7 +61,7 @@ static inline void cpu_clone_regs_child(CPUE2KState *env, target_ulong newsp,
env->ip = E2K_SYSRET_ADDR;
env->pcsp = pcs;
env->psp = ps;
env->regs[0] = 0;
env->regs[0].lo = 0;
env->tags[0] = 0;
}
}
@ -72,12 +72,12 @@ static inline void cpu_clone_regs_parent(CPUE2KState *env, unsigned flags)
static inline void cpu_set_tls(CPUE2KState *env, target_ulong newtls)
{
env->regs[E2K_TLS_REG] = newtls;
env->regs[E2K_TLS_REG].lo = newtls;
}
static inline target_ulong cpu_get_tls(CPUE2KState *env)
{
return env->regs[E2K_TLS_REG];
return env->regs[E2K_TLS_REG].lo;
}
static inline abi_ulong get_sp_from_cpustate(CPUE2KState *env)

View File

@ -164,7 +164,7 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
char name = i < E2K_NR_COUNT ? 'r' : 'g';
int tag = env->tags[i];
qemu_fprintf(f, "%%%c%d\t<%d%d> 0x%lx\n", name, i, tag >> 2, tag & 3,
env->regs[i]);
env->regs[i].lo);
}
for (i = 0; i < 32; i++) {

View File

@ -694,19 +694,25 @@ typedef union {
int16_t i16v[8];
int32_t i32v[4];
int64_t i64v[2];
struct {
uint64_t lo;
uint64_t hi;
};
} E2KReg;
typedef struct {
/* register file */
uint8_t tags[E2K_REG_COUNT]; /* registers tags */
uint64_t regs[E2K_REG_COUNT]; /* low parts of registers */
uint64_t xregs[E2K_REG_COUNT]; /* high parts of registers */
E2KReg regs[E2K_REG_COUNT]; /* low parts of registers */
uint64_t pregs; /* predicate file */
target_ulong ip; /* instruction address */
/* temporaries for FX/SIMD ops */
E2KReg t0, t1, t2, t3;
E2KReg tmp[3];
E2KReg al_result[6];
/* DAM */
E2KDamEntry dam[32];

View File

@ -47,7 +47,7 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
}
if (3 <= n && n < 35) {
return gdb_get_reg64(mem_buf, env->regs[E2K_NR_COUNT + n - 3]);
return gdb_get_reg64(mem_buf, env->regs[E2K_NR_COUNT + n - 3].lo);
}
switch (n) {

View File

@ -44,11 +44,11 @@ static void ps_spill(CPUE2KState *env, int n, bool fx)
{
int i;
for (i = 0; i < n; i += 2) {
ps_push(env, env->regs[i], env->tags[i]);
ps_push(env, env->regs[i + 1], env->tags[i + 1]);
ps_push(env, env->regs[i + 0].lo, env->tags[i]);
ps_push(env, env->regs[i + 1].lo, env->tags[i + 1]);
if (fx || E2K_FORCE_FX) {
ps_push(env, env->xregs[i + 0], 0);
ps_push(env, env->xregs[i + 1], 0);
ps_push(env, env->regs[i + 0].hi, 0);
ps_push(env, env->regs[i + 1].hi, 0);
}
}
}
@ -58,11 +58,11 @@ static void ps_fill(CPUE2KState *env, int n, bool fx)
int i;
for (i = n; i > 0; i -= 2) {
if (fx || E2K_FORCE_FX) {
env->xregs[i - 1] = ps_pop(env, NULL);
env->xregs[i - 2] = ps_pop(env, NULL);
env->regs[i - 1].hi = ps_pop(env, NULL);
env->regs[i - 2].hi = ps_pop(env, NULL);
}
env->regs[i - 1] = ps_pop(env, &env->tags[i - 1]);
env->regs[i - 2] = ps_pop(env, &env->tags[i - 2]);
env->regs[i - 1].lo = ps_pop(env, &env->tags[i - 1]);
env->regs[i - 2].lo = ps_pop(env, &env->tags[i - 2]);
}
}
@ -70,7 +70,6 @@ static void move_regs(CPUE2KState *env, int dst, int src, int n)
{
memmove(&env->regs[dst], &env->regs[src], n * sizeof(env->regs[0]));
memmove(&env->tags[dst], &env->tags[src], n * sizeof(env->tags[0]));
memmove(&env->xregs[dst], &env->xregs[src], n * sizeof(env->xregs[0]));
}
static void callee_window(CPUE2KState *env, int base, int size, bool fx)
@ -241,7 +240,7 @@ void HELPER(return)(CPUE2KState *env)
if (opc == CTPR_OPC_SIGRET) {
CPUState *cs = env_cpu(env);
env->wd.psize = 2;
env->regs[0] = 119; /* TARGET_NR_sigreturn */
env->regs[0].lo = 119; /* TARGET_NR_sigreturn */
env->tags[0] = E2K_TAG_NUMBER64;
cs->exception_index = EXCP_SYSCALL;
cpu_loop_exit(cs);
@ -297,7 +296,6 @@ void HELPER(setwd)(CPUE2KState *env, int wsz, int nfx, int dbl)
// FIXME: zeroing registers is not needed, but useful for debugging
#if 1
memset(&env->regs[env->wd.size], 0, diff * sizeof(env->regs[0]));
memset(&env->xregs[env->wd.size], 0, diff * sizeof(env->xregs[0]));
#endif
memset(&env->tags[env->wd.size], E2K_TAG_NON_NUMBER64, diff);
}

View File

@ -552,17 +552,17 @@ static inline void e2k_gen_reg_index(DisasContext *ctx, TCGv_i32 ret, uint8_t ar
}
}
void e2k_gen_reg_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_reg_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_reg_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_reg_lo_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_reg_lo_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_lo_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_reg_lo_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_xreg_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_xreg_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_xreg_read16u_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_xreg_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_xreg_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_xreg_write16u_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_reg_hi_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_reg_hi_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_hi_read16u_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_hi_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_reg_hi_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_reg_hi_write16u_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_preg_i32(TCGv_i32 ret, int reg);
void e2k_gen_cond_i32(DisasContext *ctx, TCGv_i32 ret, uint8_t psrc);

View File

@ -174,7 +174,7 @@ void e2k_aau_commit(DisasContext *ctx)
// TODO: aau.tags
if (res->is_set) {
e2k_gen_reg_tag_write_i64(res->tag, res->index);
e2k_gen_reg_write_i64(res->value, res->index);
e2k_gen_reg_lo_write_i64(res->value, res->index);
}
}

View File

@ -157,8 +157,8 @@ static inline void gen_reg_i80(DisasContext *ctx, Src80 *ret, uint8_t arg)
ret->lo = e2k_get_temp_i64(ctx);
ret->hi = e2k_get_temp_i32(ctx);
e2k_gen_reg_tag_read_i64(ret->tag, t0);
e2k_gen_reg_read_i64(ret->lo, t0);
e2k_gen_xreg_read16u_i32(ret->hi, t0);
e2k_gen_reg_lo_read_i64(ret->lo, t0);
e2k_gen_reg_hi_read16u_i32(ret->hi, t0);
tcg_temp_free_i32(t0);
}
@ -170,7 +170,7 @@ static inline void gen_reg_i64(DisasContext *ctx, Src64 *ret, uint8_t arg)
ret->tag = e2k_get_temp_i32(ctx);
ret->value = e2k_get_temp_i64(ctx);
e2k_gen_reg_tag_read_i64(ret->tag, t0);
e2k_gen_reg_read_i64(ret->value, t0);
e2k_gen_reg_lo_read_i64(ret->value, t0);
tcg_temp_free_i32(t0);
}
@ -183,7 +183,7 @@ static inline void gen_reg_i32(DisasContext *ctx, Src32 *ret, uint8_t arg)
ret->tag = e2k_get_temp_i32(ctx);
ret->value = e2k_get_temp_i32(ctx);
e2k_gen_reg_tag_read_i32(ret->tag, t0);
e2k_gen_reg_read_i32(ret->value, t0);
e2k_gen_reg_lo_read_i32(ret->value, t0);
tcg_temp_free_i32(t0);
}
@ -4769,7 +4769,7 @@ static inline void gen_al_result_commit_reg32(bool poison, TCGv_i32 index,
} else {
tcg_gen_mov_i32(t0, value);
}
e2k_gen_reg_write_i32(t0, index);
e2k_gen_reg_lo_write_i32(t0, index);
tcg_temp_free_i32(t0);
}
@ -4785,7 +4785,7 @@ static inline void gen_al_result_commit_reg64(bool poison, TCGv_i32 index,
} else {
tcg_gen_mov_i64(t0, value);
}
e2k_gen_reg_write_i64(t0, index);
e2k_gen_reg_lo_write_i64(t0, index);
tcg_temp_free_i64(t0);
}
@ -4837,12 +4837,12 @@ static inline void gen_al_result_commit_reg(AlResult *res)
case AL_RESULT_80:
gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag,
res->reg.v64);
e2k_gen_xreg_write16u_i32(res->reg.x32, res->reg.index);
e2k_gen_reg_hi_write16u_i32(res->reg.x32, res->reg.index);
break;
case AL_RESULT_128:
gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag,
res->reg.v64);
e2k_gen_xreg_write_i64(res->reg.x64, res->reg.index);
e2k_gen_reg_hi_write_i64(res->reg.x64, res->reg.index);
break;
default:
g_assert_not_reached();

View File

@ -226,21 +226,21 @@ void e2k_gen_reg_index_from_gregi(TCGv_i32 ret, int idx)
tcg_gen_movi_i32(ret, E2K_NR_COUNT + idx);
}
static inline void gen_reg_ptr(TCGv_ptr ret, TCGv_i32 idx)
static inline void gen_reg_lo_ptr(TCGv_ptr ret, TCGv_i32 idx)
{
TCGv_ptr t0 = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t0, cpu_env, offsetof(CPUE2KState, regs));
gen_ptr_from_index(ret, t0, idx, 8);
gen_ptr_from_index(ret, t0, idx, sizeof(E2KReg));
tcg_temp_free_ptr(t0);
}
static inline void gen_xreg_ptr(TCGv_ptr ret, TCGv_i32 idx)
static inline void gen_reg_hi_ptr(TCGv_ptr ret, TCGv_i32 idx)
{
TCGv_ptr t0 = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t0, cpu_env, offsetof(CPUE2KState, xregs));
gen_ptr_from_index(ret, t0, idx, 8);
gen_reg_lo_ptr(t0, idx);
tcg_gen_addi_ptr(ret, t0, offsetof(E2KReg, hi));
tcg_temp_free_ptr(t0);
}
@ -253,6 +253,12 @@ static inline void gen_xreg_ptr(TCGv_ptr ret, TCGv_i32 idx)
tcg_temp_free_ptr(t0); \
}
GEN_REG_READ(e2k_gen_reg_lo_read_i64, TCGv_i64, gen_reg_lo_ptr, tcg_gen_ld_i64)
GEN_REG_READ(e2k_gen_reg_lo_read_i32, TCGv_i32, gen_reg_lo_ptr, tcg_gen_ld_i32)
GEN_REG_READ(e2k_gen_reg_hi_read_i64, TCGv_i64, gen_reg_hi_ptr, tcg_gen_ld_i64)
GEN_REG_READ(e2k_gen_reg_hi_read_i32, TCGv_i32, gen_reg_hi_ptr, tcg_gen_ld_i32)
GEN_REG_READ(e2k_gen_reg_hi_read16u_i32, TCGv_i32, gen_reg_hi_ptr, tcg_gen_ld16u_i32)
#define GEN_REG_WRITE(name, ty, ptr_func, st_func) \
void name(ty value, TCGv_i32 idx) \
{ \
@ -262,14 +268,8 @@ static inline void gen_xreg_ptr(TCGv_ptr ret, TCGv_i32 idx)
tcg_temp_free_ptr(t0); \
}
GEN_REG_READ(e2k_gen_reg_read_i64, TCGv_i64, gen_reg_ptr, tcg_gen_ld_i64)
GEN_REG_READ(e2k_gen_reg_read_i32, TCGv_i32, gen_reg_ptr, tcg_gen_ld_i32)
GEN_REG_WRITE(e2k_gen_reg_write_i64, TCGv_i64, gen_reg_ptr, tcg_gen_st_i64)
GEN_REG_WRITE(e2k_gen_reg_write_i32, TCGv_i32, gen_reg_ptr, tcg_gen_st_i32)
GEN_REG_READ(e2k_gen_xreg_read_i64, TCGv_i64, gen_xreg_ptr, tcg_gen_ld_i64)
GEN_REG_READ(e2k_gen_xreg_read_i32, TCGv_i32, gen_xreg_ptr, tcg_gen_ld_i32)
GEN_REG_READ(e2k_gen_xreg_read16u_i32, TCGv_i32, gen_xreg_ptr, tcg_gen_ld16u_i32)
GEN_REG_WRITE(e2k_gen_xreg_write_i64, TCGv_i64, gen_xreg_ptr, tcg_gen_st_i64)
GEN_REG_WRITE(e2k_gen_xreg_write_i32, TCGv_i32, gen_xreg_ptr, tcg_gen_st_i32)
GEN_REG_WRITE(e2k_gen_xreg_write16u_i32, TCGv_i32, gen_xreg_ptr, tcg_gen_st16_i32)
GEN_REG_WRITE(e2k_gen_reg_lo_write_i64, TCGv_i64, gen_reg_lo_ptr, tcg_gen_st_i64)
GEN_REG_WRITE(e2k_gen_reg_lo_write_i32, TCGv_i32, gen_reg_lo_ptr, tcg_gen_st_i32)
GEN_REG_WRITE(e2k_gen_reg_hi_write_i64, TCGv_i64, gen_reg_hi_ptr, tcg_gen_st_i64)
GEN_REG_WRITE(e2k_gen_reg_hi_write_i32, TCGv_i32, gen_reg_hi_ptr, tcg_gen_st_i32)
GEN_REG_WRITE(e2k_gen_reg_hi_write16u_i32, TCGv_i32, gen_reg_hi_ptr, tcg_gen_st16_i32)