On 8/7/23 10:32, Jiajie Chen wrote:
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
+ /* Truncate high 32 bits for LA32 */
+ if (env->mode == LA32) {
+ address = (uint32_t)address;
+ }
You need to do this in the translator, because this also depends on VA32L* and the
current priv level.
Could you please elaborate on this? I am checking LA32 and VA32L* in
get_physical_address() currently, the current priv level is read from mmu_idx(or
alternatively, read from env->CSR_CRMD), and I am unsure how to do this in the translator.
In insn_trans/trans_memory.c.inc, gen_load, we compute the address,
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
if (a->imm) {
TCGv temp = tcg_temp_new();
tcg_gen_addi_tl(temp, addr, a->imm);
addr = temp;
}
One would use
if (ctx->va32) {
tcg_gen_ext32u_tl(temp, addr);
addr = temp;
}
to zero-extend the address. You would want to create no more than one temporary for the
entire computation.
You would need to modify all of the places which generate an address for tcg_gen_qemu_*:
gen_load*, gen_store*, gen_ldptr, gen_stptr. Also trans_fmemory.c.inc and trans_lsx.c.inc.
I would strongly suggest creating helper functions, so that all of the addition and
extension is done in one place, and not in lots of places as we do now.
If this sounds like more work than just changing get_physical_address, and it is. But it
works better with the softmmu tlb. If you clear upper bits late, then you get false
conflicts in the tlb, and extra tlb fills.
r~