When running in VA32 mode(LA32 or VA32L[1-3] matching PLV), virtual
address is truncated to 32 bits before address mapping.

Signed-off-by: Jiajie Chen <c...@jia.je>
---
 target/loongarch/cpu.h                          |  6 +++++-
 target/loongarch/insn_trans/trans_atomic.c.inc  |  1 +
 target/loongarch/insn_trans/trans_fmemory.c.inc |  8 ++++++++
 target/loongarch/insn_trans/trans_lsx.c.inc     |  6 ++++++
 target/loongarch/insn_trans/trans_memory.c.inc  | 10 ++++++++++
 target/loongarch/translate.c                    | 10 ++++++++++
 6 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 69589f0aef..9ad5fcc494 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -457,7 +457,11 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env, vaddr *pc,
         va32 = 1;
     }
 
-    *pc = env->pc;
+    if (va32) {
+        *pc = (uint32_t)env->pc;
+    } else {
+        *pc = env->pc;
+    }
     *cs_base = 0;
     *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
     *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index c69f31bc78..d9d950d642 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -10,6 +10,7 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
     TCGv t0 = tcg_temp_new();
 
     tcg_gen_addi_tl(t0, src1, a->imm);
+    t0 = va32_address(ctx, t0);
     tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
     tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
     tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 91c09fb6d9..391af356d0 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -22,6 +22,7 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp 
mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
@@ -42,6 +43,7 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, 
MemOp mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_st_tl(src, addr, ctx->mem_idx, mop);
 
@@ -59,6 +61,7 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
     addr = tcg_temp_new();
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
     set_fpr(a->fd, dest);
@@ -77,6 +80,7 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
     addr = tcg_temp_new();
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
     return true;
@@ -94,6 +98,7 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp 
mop)
     addr = tcg_temp_new();
     gen_helper_asrtgt_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
     set_fpr(a->fd, dest);
@@ -113,6 +118,7 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, 
MemOp mop)
     addr = tcg_temp_new();
     gen_helper_asrtgt_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
     return true;
@@ -130,6 +136,7 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
     addr = tcg_temp_new();
     gen_helper_asrtle_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     maybe_nanbox_load(dest, mop);
     set_fpr(a->fd, dest);
@@ -149,6 +156,7 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
     addr = tcg_temp_new();
     gen_helper_asrtle_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
     return true;
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 68779daff6..b7325cfd8a 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4271,6 +4271,7 @@ static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
     tcg_gen_extr_i128_i64(rl, rh, val);
@@ -4298,6 +4299,7 @@ static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     get_vreg64(ah, a->vd, 1);
     get_vreg64(al, a->vd, 0);
@@ -4323,6 +4325,7 @@ static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
     rh = tcg_temp_new_i64();
 
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
     tcg_gen_extr_i128_i64(rl, rh, val);
     set_vreg64(rh, a->vd, 1);
@@ -4347,6 +4350,7 @@ static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
     al = tcg_temp_new_i64();
 
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     get_vreg64(ah, a->vd, 1);
     get_vreg64(al, a->vd, 0);
     tcg_gen_concat_i64_i128(val, al, ah);
@@ -4371,6 +4375,7 @@ static bool trans_## NAME (DisasContext *ctx, arg_vr_i 
*a)                \
         tcg_gen_addi_tl(temp, addr, a->imm);                              \
         addr = temp;                                                      \
     }                                                                     \
+    addr = va32_address(ctx, addr);                                        \
                                                                           \
     tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, MO);                     \
     tcg_gen_gvec_dup_i64(MO, vec_full_offset(a->vd), 16, ctx->vl/8, val); \
@@ -4399,6 +4404,7 @@ static bool trans_## NAME (DisasContext *ctx, arg_vr_ii 
*a)                  \
         tcg_gen_addi_tl(temp, addr, a->imm);                                 \
         addr = temp;                                                         \
     }                                                                        \
+    addr = va32_address(ctx, addr);                                           \
                                                                              \
     tcg_gen_ld_i64(val, cpu_env,                                             \
                    offsetof(CPULoongArchState, fpr[a->vd].vreg.E(a->imm2))); \
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/insn_trans/trans_memory.c.inc
index 858c97951b..5b45444be4 100644
--- a/target/loongarch/insn_trans/trans_memory.c.inc
+++ b/target/loongarch/insn_trans/trans_memory.c.inc
@@ -13,6 +13,7 @@ static bool gen_load(DisasContext *ctx, arg_rr_i *a, MemOp 
mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -29,6 +30,7 @@ static bool gen_store(DisasContext *ctx, arg_rr_i *a, MemOp 
mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
     return true;
@@ -42,6 +44,7 @@ static bool gen_loadx(DisasContext *ctx, arg_rrr *a, MemOp 
mop)
     TCGv addr = tcg_temp_new();
 
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -56,6 +59,7 @@ static bool gen_storex(DisasContext *ctx, arg_rrr *a, MemOp 
mop)
     TCGv addr = tcg_temp_new();
 
     tcg_gen_add_tl(addr, src1, src2);
+    addr = va32_address(ctx, addr);
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
 
     return true;
@@ -68,6 +72,7 @@ static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp 
mop)
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
 
     gen_helper_asrtgt_d(cpu_env, src1, src2);
+    src1 = va32_address(ctx, src1);
     tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -81,6 +86,7 @@ static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp 
mop)
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
 
     gen_helper_asrtle_d(cpu_env, src1, src2);
+    src1 = va32_address(ctx, src1);
     tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -94,6 +100,7 @@ static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, 
MemOp mop)
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
 
     gen_helper_asrtgt_d(cpu_env, src1, src2);
+    src1 = va32_address(ctx, src1);
     tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
 
     return true;
@@ -106,6 +113,7 @@ static bool gen_store_le(DisasContext *ctx, arg_rrr *a, 
MemOp mop)
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
 
     gen_helper_asrtle_d(cpu_env, src1, src2);
+    src1 = va32_address(ctx, src1);
     tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
 
     return true;
@@ -138,6 +146,7 @@ static bool gen_ldptr(DisasContext *ctx, arg_rr_i *a, MemOp 
mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
     gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -154,6 +163,7 @@ static bool gen_stptr(DisasContext *ctx, arg_rr_i *a, MemOp 
mop)
         tcg_gen_addi_tl(temp, addr, a->imm);
         addr = temp;
     }
+    addr = va32_address(ctx, addr);
 
     tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
     return true;
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index f1e5fe4cf8..9cd2f13778 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -208,6 +208,16 @@ static void set_fpr(int reg_num, TCGv val)
                    offsetof(CPULoongArchState, fpr[reg_num].vreg.D(0)));
 }
 
+static TCGv va32_address(DisasContext *ctx, TCGv addr)
+{
+    if (ctx->va32) {
+        TCGv temp = tcg_temp_new();
+        tcg_gen_ext32u_tl(temp, addr);
+        addr = temp;
+    }
+    return addr;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
-- 
2.41.0


Reply via email to