diff options
author | Jiajie Chen <c@jia.je> | 2023-08-22 09:13:55 +0200 |
---|---|---|
committer | Song Gao <gaosong@loongson.cn> | 2023-08-24 11:17:57 +0800 |
commit | 7033c0e6dd36cd2bfa9a323c3a51ecb0b55903fc (patch) | |
tree | 332e0692c8649c7dc091cf187ab12844259be545 /target | |
parent | 2f6478ffad1770a474460b7692588bae7f031da3 (diff) | |
download | qemu-7033c0e6dd36cd2bfa9a323c3a51ecb0b55903fc.zip qemu-7033c0e6dd36cd2bfa9a323c3a51ecb0b55903fc.tar.gz qemu-7033c0e6dd36cd2bfa9a323c3a51ecb0b55903fc.tar.bz2 |
target/loongarch: Truncate high 32 bits of address in VA32 mode
When running in VA32 mode(!LA64 or VA32L[1-3] matching PLV), virtual
address is truncated to 32 bits before address mapping.
Signed-off-by: Jiajie Chen <c@jia.je>
Co-authored-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20230822032724.1353391-6-gaosong@loongson.cn>
Message-Id: <20230822071405.35386-10-philmd@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/loongarch/cpu.h | 6 | ||||
-rw-r--r-- | target/loongarch/translate.c | 16 |
2 files changed, 20 insertions, 2 deletions
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index e156269..25a0ef7 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -445,7 +445,11 @@ static inline bool is_va32(CPULoongArchState *env) static inline void set_pc(CPULoongArchState *env, uint64_t value) { - env->pc = value; + if (is_va32(env)) { + env->pc = (uint32_t)value; + } else { + env->pc = value; + } } /* diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 8b26555..9a23ec7 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -86,6 +86,10 @@ void generate_exception(DisasContext *ctx, int excp) static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { + if (ctx->va32) { + dest = (uint32_t) dest; + } + if (translator_use_goto_tb(&ctx->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_pc, dest); @@ -212,11 +216,17 @@ static TCGv make_address_x(DisasContext *ctx, TCGv base, TCGv addend) { TCGv temp = NULL; - if (addend) { + if (addend || ctx->va32) { temp = tcg_temp_new(); + } + if (addend) { tcg_gen_add_tl(temp, base, addend); base = temp; } + if (ctx->va32) { + tcg_gen_ext32u_tl(temp, base); + base = temp; + } return base; } @@ -262,6 +272,10 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) } ctx->base.pc_next += 4; + + if (ctx->va32) { + ctx->base.pc_next = (uint32_t)ctx->base.pc_next; + } } static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) |