e2k: use pointer to access regs in a window
This commit is contained in:
parent
627d8add8b
commit
4a415ddafa
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user