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 committed by Denis Drakhnia
parent bed634d944
commit 17be44b21b
11 changed files with 67 additions and 61 deletions

View File

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

View File

@ -217,7 +217,7 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
} }
/* fake kernel frame */ /* fake kernel frame */
env->regs[0] = frame_addr; env->regs[0].lo = frame_addr;
env->tags[0] = E2K_TAG_NUMBER64; env->tags[0] = E2K_TAG_NUMBER64;
env->wd.size = 2; env->wd.size = 2;
env->wd.psize = 0; env->wd.psize = 0;
@ -226,15 +226,15 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
helper_signal_frame(env, 2, E2K_SIGRET_ADDR); helper_signal_frame(env, 2, E2K_SIGRET_ADDR);
env->ip = ka->_sa_handler; env->ip = ka->_sa_handler;
env->regs[0] = sig; env->regs[0].lo = sig;
env->tags[0] = E2K_TAG_NUMBER64; env->tags[0] = E2K_TAG_NUMBER64;
env->wd.size = 8; env->wd.size = 8;
if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) { if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) {
tswap_siginfo(&frame->info, info); 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->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; env->tags[2] = E2K_TAG_NUMBER64;
} }
@ -293,7 +293,7 @@ long do_rt_sigreturn(CPUE2KState *env)
/* restore fake kernel frame */ /* restore fake kernel frame */
helper_signal_return(env); helper_signal_return(env);
frame_addr = env->regs[0]; frame_addr = env->regs[0].lo;
trace_user_do_rt_sigreturn(env, frame_addr); trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { 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->ip = E2K_SYSRET_ADDR;
env->pcsp = pcs; env->pcsp = pcs;
env->psp = ps; env->psp = ps;
env->regs[0] = 0; env->regs[0].lo = 0;
env->tags[0] = 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) 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) 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) static inline abi_ulong get_sp_from_cpustate(CPUE2KState *env)

View File

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

View File

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

View File

@ -44,11 +44,11 @@ static void ps_spill(CPUE2KState *env, int n, bool fx)
{ {
int i; int i;
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
ps_push(env, env->regs[i], env->tags[i]); ps_push(env, env->regs[i + 0].lo, env->tags[i]);
ps_push(env, env->regs[i + 1], env->tags[i + 1]); ps_push(env, env->regs[i + 1].lo, env->tags[i + 1]);
if (fx || E2K_FORCE_FX) { if (fx || E2K_FORCE_FX) {
ps_push(env, env->xregs[i + 0], 0); ps_push(env, env->regs[i + 0].hi, 0);
ps_push(env, env->xregs[i + 1], 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; int i;
for (i = n; i > 0; i -= 2) { for (i = n; i > 0; i -= 2) {
if (fx || E2K_FORCE_FX) { if (fx || E2K_FORCE_FX) {
env->xregs[i - 1] = ps_pop(env, NULL); env->regs[i - 1].hi = ps_pop(env, NULL);
env->xregs[i - 2] = 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 - 1].lo = ps_pop(env, &env->tags[i - 1]);
env->regs[i - 2] = ps_pop(env, &env->tags[i - 2]); 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->regs[dst], &env->regs[src], n * sizeof(env->regs[0]));
memmove(&env->tags[dst], &env->tags[src], n * sizeof(env->tags[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) 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) { if (opc == CTPR_OPC_SIGRET) {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
env->wd.psize = 2; 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; env->tags[0] = E2K_TAG_NUMBER64;
cs->exception_index = EXCP_SYSCALL; cs->exception_index = EXCP_SYSCALL;
cpu_loop_exit(cs); 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 // FIXME: zeroing registers is not needed, but useful for debugging
#if 1 #if 1
memset(&env->regs[env->wd.size], 0, diff * sizeof(env->regs[0])); 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 #endif
memset(&env->tags[env->wd.size], E2K_TAG_NON_NUMBER64, diff); 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_lo_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_reg_read_i32(TCGv_i32 ret, TCGv_i32 idx); void e2k_gen_reg_lo_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_reg_write_i64(TCGv_i64 value, TCGv_i32 idx); void e2k_gen_reg_lo_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_write_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_xreg_read_i64(TCGv_i64 ret, TCGv_i32 idx); void e2k_gen_reg_hi_read_i64(TCGv_i64 ret, TCGv_i32 idx);
void e2k_gen_xreg_read_i32(TCGv_i32 ret, TCGv_i32 idx); void e2k_gen_reg_hi_read_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_xreg_read16u_i32(TCGv_i32 ret, TCGv_i32 idx); void e2k_gen_reg_hi_read16u_i32(TCGv_i32 ret, TCGv_i32 idx);
void e2k_gen_xreg_write_i64(TCGv_i64 value, TCGv_i32 idx); void e2k_gen_reg_hi_write_i64(TCGv_i64 value, TCGv_i32 idx);
void e2k_gen_xreg_write_i32(TCGv_i32 value, TCGv_i32 idx); void e2k_gen_reg_hi_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_write16u_i32(TCGv_i32 value, TCGv_i32 idx);
void e2k_gen_preg_i32(TCGv_i32 ret, int reg); void e2k_gen_preg_i32(TCGv_i32 ret, int reg);
void e2k_gen_cond_i32(DisasContext *ctx, TCGv_i32 ret, uint8_t psrc); 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 // TODO: aau.tags
if (res->is_set) { if (res->is_set) {
e2k_gen_reg_tag_write_i64(res->tag, res->index); 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->lo = e2k_get_temp_i64(ctx);
ret->hi = e2k_get_temp_i32(ctx); ret->hi = e2k_get_temp_i32(ctx);
e2k_gen_reg_tag_read_i64(ret->tag, t0); e2k_gen_reg_tag_read_i64(ret->tag, t0);
e2k_gen_reg_read_i64(ret->lo, t0); e2k_gen_reg_lo_read_i64(ret->lo, t0);
e2k_gen_xreg_read16u_i32(ret->hi, t0); e2k_gen_reg_hi_read16u_i32(ret->hi, t0);
tcg_temp_free_i32(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->tag = e2k_get_temp_i32(ctx);
ret->value = e2k_get_temp_i64(ctx); ret->value = e2k_get_temp_i64(ctx);
e2k_gen_reg_tag_read_i64(ret->tag, t0); 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); 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->tag = e2k_get_temp_i32(ctx);
ret->value = e2k_get_temp_i32(ctx); ret->value = e2k_get_temp_i32(ctx);
e2k_gen_reg_tag_read_i32(ret->tag, t0); 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); tcg_temp_free_i32(t0);
} }
@ -4769,7 +4769,7 @@ static inline void gen_al_result_commit_reg32(bool poison, TCGv_i32 index,
} else { } else {
tcg_gen_mov_i32(t0, value); 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); tcg_temp_free_i32(t0);
} }
@ -4785,7 +4785,7 @@ static inline void gen_al_result_commit_reg64(bool poison, TCGv_i32 index,
} else { } else {
tcg_gen_mov_i64(t0, value); 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); tcg_temp_free_i64(t0);
} }
@ -4837,12 +4837,12 @@ static inline void gen_al_result_commit_reg(AlResult *res)
case AL_RESULT_80: case AL_RESULT_80:
gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag, gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag,
res->reg.v64); 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; break;
case AL_RESULT_128: case AL_RESULT_128:
gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag, gen_al_result_commit_reg64(res->poison, res->reg.index, res->reg.tag,
res->reg.v64); 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; break;
default: default:
g_assert_not_reached(); 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); 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(); TCGv_ptr t0 = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t0, cpu_env, offsetof(CPUE2KState, regs)); 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); 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(); TCGv_ptr t0 = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t0, cpu_env, offsetof(CPUE2KState, xregs)); gen_reg_lo_ptr(t0, idx);
gen_ptr_from_index(ret, t0, idx, 8); tcg_gen_addi_ptr(ret, t0, offsetof(E2KReg, hi));
tcg_temp_free_ptr(t0); 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); \ 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) \ #define GEN_REG_WRITE(name, ty, ptr_func, st_func) \
void name(ty value, TCGv_i32 idx) \ 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); \ tcg_temp_free_ptr(t0); \
} }
GEN_REG_READ(e2k_gen_reg_read_i64, TCGv_i64, gen_reg_ptr, tcg_gen_ld_i64) GEN_REG_WRITE(e2k_gen_reg_lo_write_i64, TCGv_i64, gen_reg_lo_ptr, tcg_gen_st_i64)
GEN_REG_READ(e2k_gen_reg_read_i32, TCGv_i32, gen_reg_ptr, tcg_gen_ld_i32) 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_write_i64, TCGv_i64, gen_reg_ptr, tcg_gen_st_i64) 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_write_i32, TCGv_i32, gen_reg_ptr, tcg_gen_st_i32) 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)
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)