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:
parent
bed634d944
commit
17be44b21b
@ -74,11 +74,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]);
|
||||
@ -89,7 +91,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;
|
||||
}
|
||||
|
@ -217,7 +217,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;
|
||||
@ -226,15 +226,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;
|
||||
}
|
||||
|
||||
@ -293,7 +293,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)) {
|
||||
|
@ -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)
|
||||
|
@ -169,7 +169,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++) {
|
||||
|
@ -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 CPUArchState {
|
||||
/* 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];
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user