e2k: use pointer to access regs in a window

This commit is contained in:
Denis Drakhnia 2024-01-08 12:44:36 +02:00
parent 627d8add8b
commit 4a415ddafa
8 changed files with 69 additions and 49 deletions

View File

@ -85,10 +85,10 @@ void cpu_loop(CPUE2KState *env)
int i;
for (i = 0; i < psize; i++) {
args[i] = env->regs[i].lo;
args[i] = env->wreg[i].lo;
}
if (!env->enable_tags || (env->tags[0] & E2K_TAG_MASK_32) == E2K_TAG_NUMBER32) {
if (!env->enable_tags || (env->wtag[0] & E2K_TAG_MASK_32) == E2K_TAG_NUMBER32) {
ret = do_syscall(env, (uint32_t) args[0], args[1], args[2], args[3],
args[4], args[5], args[6], args[7], args[8]);
} else {
@ -99,13 +99,13 @@ void cpu_loop(CPUE2KState *env)
/* do not set sysret address and syscall will be restarted */
} else if (ret != -QEMU_ESIGRETURN && env->wd.psize > 0) {
env->ip = E2K_SYSRET_ADDR;
env->regs[0].lo = ret;
env->wreg[0].lo = ret;
if (env->enable_tags) {
env->tags[0] = E2K_TAG_NUMBER64;
env->wtag[0] = E2K_TAG_NUMBER64;
for (i = 1; i < E2K_SYSCALL_MAX_ARGS; i++) {
env->tags[i] = E2K_TAG_NON_NUMBER64;
env->wtag[i] = E2K_TAG_NON_NUMBER64;
}
}
}
@ -180,6 +180,15 @@ void target_cpu_copy_regs(CPUE2KState *env, struct target_pt_regs *regs)
env->sbr = regs->sbr;
env->elf_flags = info->elf_flags;
env->wreg = env->regs;
env->wtag = env->tags;
env->wd.base = 0;
env->wd.size = 16;
env->wd.psize = 8;
e2k_set_rbs(env, 8);
env->bn.size = 8;
e2k_set_rcur(env, 0);
// Save initial frame for gdb.
env->is_bp = true;
e2k_proc_call(env, env->wd.size, env->ip, true);

View File

@ -247,19 +247,19 @@ static void target_setup_frame(int sig, struct target_sigaction *ka,
e2k_proc_call(env, 0, E2K_SIGRET_ADDR, false);
env->ip = ka->_sa_handler;
env->regs[0].lo = sig;
env->wreg[0].lo = sig;
if (env->enable_tags) {
env->tags[0] = E2K_TAG_NUMBER64;
env->wtag[0] = E2K_TAG_NUMBER64;
}
env->wd.size = 8;
if (info && (ka->sa_flags & TARGET_SA_SIGINFO)) {
frame->info = *info;
env->regs[1].lo = frame_addr + offsetof(struct target_sigframe, info);
env->regs[2].lo = frame_addr + offsetof(struct target_sigframe, uc);
env->wreg[1].lo = frame_addr + offsetof(struct target_sigframe, info);
env->wreg[2].lo = frame_addr + offsetof(struct target_sigframe, uc);
if (env->enable_tags) {
env->tags[1] = E2K_TAG_NUMBER64;
env->tags[2] = E2K_TAG_NUMBER64;
env->wtag[1] = E2K_TAG_NUMBER64;
env->wtag[2] = E2K_TAG_NUMBER64;
}
}

View File

@ -61,9 +61,9 @@ 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].lo = 0;
env->wreg[0].lo = 0;
if (env->enable_tags) {
env->tags[0] = 0;
env->wtag[0] = 0;
}
}
}

View File

@ -119,7 +119,7 @@ static void dump_regs(CPUE2KState *env, FILE *f, int flags)
int i, base, cur;
for (i = 0; i < env->wd.size; i++) {
int tags = env->enable_tags ? env->tags[i] : 0;
int tags = env->enable_tags ? env->wtag[i] : 0;
dump_reg(env, f, 'r', i, tags, env->regs[i]);
}
if (env->wd.size & 3) {
@ -130,9 +130,9 @@ static void dump_regs(CPUE2KState *env, FILE *f, int flags)
cur = e2k_get_rcur(env) * 2;
if ((env->wd.size - base) >= env->bn.size) {
for (i = 0; i < env->bn.size; i++) {
int index = base + (i + cur) % env->bn.size;
int tags = env->enable_tags ? env->tags[index] : 0;
dump_reg(env, f, 'b', i, tags, env->regs[index]);
int index = (i + cur) % env->bn.size;
int tags = env->enable_tags ? env->btag[index] : 0;
dump_reg(env, f, 'b', i, tags, env->breg[index]);
}
if (env->bn.size & 3) {
qemu_fprintf(f, "\n");

View File

@ -44,12 +44,16 @@ static void e2k_cpu_reset(DeviceState *dev)
env->psr = PSR_PM;
env->upsr = UPSR_NMIE | UPSR_FE;
#if !defined(CONFIG_USER_ONLY)
env->wreg = env->regs;
env->wtag = env->tags;
env->wd.base = 0;
env->wd.size = 16;
env->wd.psize = 8;
e2k_set_rbs(env, 8);
env->bn.size = 8;
e2k_set_rcur(env, 0);
#endif
/* Based predicate window must not be zero. */
env->bp.size = 1;
env->aau.incrs[0] = 1; /* always one */

View File

@ -787,8 +787,11 @@ typedef struct CPUArchState {
E2KReg regs[E2K_NR_COUNT];
uint8_t tags[E2K_NR_COUNT];
/* Global registers */
uint8_t gtag[32];
E2KReg greg[32];
uint8_t gtag[32];
/* Pointer to the first register in a procedure window */
E2KReg *wreg;
uint8_t *wtag;
/* Pointer to the first based register */
E2KReg *breg;
uint8_t *btag;
@ -928,14 +931,14 @@ struct ArchCPU {
static inline int e2k_get_rbs(CPUE2KState *env)
{
return ((uintptr_t) env->breg - (uintptr_t) env->regs) / sizeof(env->breg[0]) / 2;
return ((uintptr_t) env->breg - (uintptr_t) env->wreg) / sizeof(env->breg[0]) / 2;
}
static inline void e2k_set_rbs(CPUE2KState *env, int rbs)
{
int n = rbs * 2;
env->breg = &env->regs[n];
env->btag = &env->tags[n];
env->breg = &env->wreg[n];
env->btag = &env->wtag[n];
}
static inline int e2k_get_rcur(CPUE2KState *env)

View File

@ -49,19 +49,19 @@ static void ps_spill(CPUE2KState *env, int n, bool fx)
if (env->version >= 5) {
for (int i = 0; i < n; i++, index += 16) {
ps_write(env, env->regs[i].lo, env->tags[i], index);
ps_write(env, env->wreg[i].lo, env->wtag[i], index);
if (fx) {
ps_write(env, env->regs[i].hi, 0, index + 8);
ps_write(env, env->wreg[i].hi, 0, index + 8);
}
}
} else{
for (int i = 0; i < n; i += 2, index += 32) {
E2KReg r0 = env->regs[i + 0];
E2KReg r1 = env->regs[i + 1];
E2KReg r0 = env->wreg[i + 0];
E2KReg r1 = env->wreg[i + 1];
ps_write(env, r0.lo, env->tags[i], index);
ps_write(env, r1.lo, env->tags[i + 1], index + 8);
ps_write(env, r0.lo, env->wtag[i], index);
ps_write(env, r1.lo, env->wtag[i + 1], index + 8);
if (fx) {
ps_write(env, r0.hi, 0, index + 16);
@ -84,23 +84,23 @@ static void ps_fill(CPUE2KState *env, int n, bool fx)
if (env->version >= 5) {
for (int i = n; i-- > 0; index -= 16) {
if (fx) {
env->regs[i].hi = ps_read(env, NULL, index - 8);
env->wreg[i].hi = ps_read(env, NULL, index - 8);
}
env->regs[i].lo = ps_read(env, &env->tags[i], index - 16);
env->wreg[i].lo = ps_read(env, &env->wtag[i], index - 16);
}
} else {
for (int i = n; i > 0; i -= 2, index -= 32) {
E2KReg *r0 = &env->regs[i - 1];
E2KReg *r1 = &env->regs[i - 2];
E2KReg *r0 = &env->wreg[i - 1];
E2KReg *r1 = &env->wreg[i - 2];
if (fx) {
r0->hi = ps_read(env, NULL, index - 8);
r1->hi = ps_read(env, NULL, index - 16);
}
r0->lo = ps_read(env, &env->tags[i - 1], index - 24);
r1->lo = ps_read(env, &env->tags[i - 2], index - 32);
r0->lo = ps_read(env, &env->wtag[i - 1], index - 24);
r1->lo = ps_read(env, &env->wtag[i - 2], index - 32);
}
}
@ -109,9 +109,9 @@ static void ps_fill(CPUE2KState *env, int n, bool fx)
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->wreg[dst], &env->wreg[src], n * sizeof(env->wreg[0]));
if (env->enable_tags) {
memmove(&env->tags[dst], &env->tags[src], n * sizeof(env->tags[0]));
memmove(&env->wtag[dst], &env->wtag[src], n * sizeof(env->wtag[0]));
}
}
@ -276,9 +276,9 @@ void HELPER(return)(CPUE2KState *env)
if (opc == CTPR_OPC_SIGRET) {
CPUState *cs = env_cpu(env);
env->wd.psize = 2;
env->regs[0].lo = 119; /* TARGET_NR_sigreturn */
env->wreg[0].lo = 119; /* TARGET_NR_sigreturn */
if (env->enable_tags) {
env->tags[0] = E2K_TAG_NUMBER64;
env->wtag[0] = E2K_TAG_NUMBER64;
}
cs->exception_index = E2K_EXCP_SYSCALL;
cpu_loop_exit(cs);

View File

@ -97,6 +97,8 @@ typedef enum {
static TCGv cpu_pc;
static TCGv_i64 cpu_ctprs[3];
static TCGv_i32 cpu_bsize; /* holds rsz * 2 + 2 */
static TCGv_ptr cpu_wreg; /* pointer to the first register in a procedure window */
static TCGv_ptr cpu_wtag;
static TCGv_ptr cpu_breg; /* pointer to the first based register */
static TCGv_ptr cpu_btag;
static TCGv_i32 cpu_bcur; /* rcur * 2 * sizeof(E2KReg) */
@ -1362,11 +1364,11 @@ static Tagged gen_reg(DisasContext *ctx, TaggedKind kind, uint8_t reg)
}
} else if (IS_REGULAR(reg)) {
index = GET_REGULAR(reg);
reg_ptr = tcg_env;
offset_lo = offsetof(CPUE2KState, regs[index].lo);
offset_hi = offsetof(CPUE2KState, regs[index].hi);
tag_ptr = tcg_env;
tag_offset = offsetof(CPUE2KState, tags[index]);
reg_ptr = cpu_wreg;
offset_lo = index * sizeof(E2KReg) + offsetof(E2KReg, lo);
offset_hi = index * sizeof(E2KReg) + offsetof(E2KReg, hi);
tag_ptr = cpu_wtag;
tag_offset = index;
} else if (IS_GLOBAL(reg)) {
index = GET_GLOBAL(reg);
reg_ptr = tcg_env;
@ -1452,11 +1454,11 @@ static void gen_set_reg(DisasContext *ctx, Tagged *value, uint8_t reg)
}
} else if (IS_REGULAR(reg)) {
index = GET_REGULAR(reg);
reg_ptr = tcg_env;
offset_lo = offsetof(CPUE2KState, regs[index].lo);
offset_hi = offsetof(CPUE2KState, regs[index].hi);
tag_ptr = tcg_env;
tag_offset = offsetof(CPUE2KState, tags[index]);
reg_ptr = cpu_wreg;
offset_lo = index * sizeof(E2KReg) + offsetof(E2KReg, lo);
offset_hi = index * sizeof(E2KReg) + offsetof(E2KReg, hi);
tag_ptr = cpu_wtag;
tag_offset = index;
} else if (IS_GLOBAL(reg)) {
index = GET_GLOBAL(reg);
reg_ptr = tcg_env;
@ -7076,8 +7078,8 @@ static inline void gen_setbn(DisasContext *ctx)
ctx->b_size = setr->rsz * 2 + 2;
ctx->b_base = setr->rbs * 2;
tcg_gen_movi_i32(cpu_bsize, ctx->b_size);
tcg_gen_addi_ptr(cpu_breg, tcg_env, offsetof(CPUE2KState, regs[ctx->b_base]));
tcg_gen_addi_ptr(cpu_btag, tcg_env, offsetof(CPUE2KState, tags[ctx->b_base]));
tcg_gen_addi_ptr(cpu_breg, cpu_wreg, ctx->b_base * sizeof(E2KReg));
tcg_gen_addi_ptr(cpu_btag, cpu_wtag, ctx->b_base);
tcg_gen_movi_i32(cpu_bcur, setr->rcur * 2 * sizeof(E2KReg));
}
}
@ -7919,6 +7921,8 @@ void e2k_tcg_initialize(void) {
offsetof(CPUE2KState, ctprs[i].raw), buf);
}
cpu_wreg = tcg_global_mem_new_ptr(tcg_env, offsetof(CPUE2KState, wreg), "wreg");
cpu_wtag = tcg_global_mem_new_ptr(tcg_env, offsetof(CPUE2KState, wtag), "wtag");
cpu_breg = tcg_global_mem_new_ptr(tcg_env, offsetof(CPUE2KState, breg), "breg");
cpu_btag = tcg_global_mem_new_ptr(tcg_env, offsetof(CPUE2KState, btag), "btag");
cpu_bcur = tcg_global_mem_new_i32(tcg_env, offsetof(CPUE2KState, bcur), "bcur");