[PATCH RESEND v5 17/19] target/loongarch: Add avail_LAM to check atomic instructions

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-ID: <20230822032724.1353391-14-gaos...@loongson.cn>
---
 target/loongarch/translate.h  |  1 +
 .../loongarch/insn_trans/trans_atomic.c.inc   | 72 +--
 2 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index f0d7b82932..faf4ce87f9 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -21,6 +21,7 @@
 #define avail_FP_SP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_SP))
 #define avail_FP_DP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_DP))
 #define avail_LSPW(C)  (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
+#define avail_LAM(C)   (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM))
 
 /*
  * If an operation is being performed on less than TARGET_LONG_BITS,
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 194818d74d..40085190f6 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -73,39 +73,39 @@ TRANS(ll_w, ALL, gen_ll, MO_TESL)
 TRANS(sc_w, ALL, gen_sc, MO_TESL)
 TRANS(ll_d, 64, gen_ll, MO_TEUQ)
 TRANS(sc_d, 64, gen_sc, MO_TEUQ)
-TRANS(amswap_w, 64, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
-TRANS(amswap_d, 64, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
-TRANS(amadd_w, 64, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
-TRANS(amadd_d, 64, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
-TRANS(amand_w, 64, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
-TRANS(amand_d, 64, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
-TRANS(amor_w, 64, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
-TRANS(amor_d, 64, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
-TRANS(amxor_w, 64, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
-TRANS(amxor_d, 64, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
-TRANS(ammax_w, 64, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
-TRANS(ammax_d, 64, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
-TRANS(ammin_w, 64, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
-TRANS(ammin_d, 64, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
-TRANS(ammax_wu, 64, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
-TRANS(ammax_du, 64, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
-TRANS(ammin_wu, 64, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
-TRANS(ammin_du, 64, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
-TRANS(amswap_db_w, 64, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
-TRANS(amswap_db_d, 64, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
-TRANS(amadd_db_w, 64, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
-TRANS(amadd_db_d, 64, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
-TRANS(amand_db_w, 64, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
-TRANS(amand_db_d, 64, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
-TRANS(amor_db_w, 64, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
-TRANS(amor_db_d, 64, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
-TRANS(amxor_db_w, 64, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
-TRANS(amxor_db_d, 64, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
-TRANS(ammax_db_w, 64, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
-TRANS(ammax_db_d, 64, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
-TRANS(ammin_db_w, 64, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
-TRANS(ammin_db_d, 64, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
-TRANS(ammax_db_wu, 64, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
-TRANS(ammax_db_du, 64, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
-TRANS(ammin_db_wu, 64, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
-TRANS(ammin_db_du, 64, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+TRANS(amswap_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
+TRANS(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
+TRANS(amadd_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
+TRANS(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
+TRANS(amand_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
+TRANS(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
+TRANS(amor_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
+TRANS(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
+TRANS(amxor_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
+TRANS(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
+TRANS(ammax_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
+TRANS(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
+TRANS(ammin_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
+TRANS(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
+TRANS(ammax_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
+TRANS(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
+TRANS(ammin_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
+TRANS(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+TRANS(amswap_db_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
+TRANS(amswap_db_d, LAM, gen_am, 

[PATCH RESEND v5 12/19] target/loongarch: Add avail_64 to check la64-only instructions

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

The la32 instructions listed in Table 2 at
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#overview-of-basic-integer-instructions

Co-authored-by: Jiajie Chen 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-ID: <20230822032724.1353391-9-gaos...@loongson.cn>
---
 target/loongarch/translate.h  |  3 +
 target/loongarch/translate.c  |  2 +
 target/loongarch/insn_trans/trans_arith.c.inc | 42 ++
 .../loongarch/insn_trans/trans_atomic.c.inc   | 76 +--
 target/loongarch/insn_trans/trans_bit.c.inc   | 28 +++
 .../loongarch/insn_trans/trans_branch.c.inc   |  4 +-
 target/loongarch/insn_trans/trans_extra.c.inc | 24 --
 target/loongarch/insn_trans/trans_fmov.c.inc  |  4 +-
 .../loongarch/insn_trans/trans_memory.c.inc   | 68 -
 target/loongarch/insn_trans/trans_shift.c.inc | 24 +++---
 10 files changed, 152 insertions(+), 123 deletions(-)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 3c5c746f30..1342446242 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -15,6 +15,8 @@
 { return avail_##AVAIL(ctx) && FUNC(ctx, a, __VA_ARGS__); }
 
 #define avail_ALL(C)   true
+#define avail_64(C)(FIELD_EX32((C)->cpucfg1, CPUCFG1, ARCH) == \
+CPUCFG1_ARCH_LA64)
 
 /*
  * If an operation is being performed on less than TARGET_LONG_BITS,
@@ -37,6 +39,7 @@ typedef struct DisasContext {
 TCGv zero;
 bool la64; /* LoongArch64 mode */
 bool va32; /* 32-bit virtual address */
+uint32_t cpucfg1;
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index de7c1c5d1f..6967e12fc3 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -127,6 +127,8 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 ctx->va32 = (ctx->base.tb->flags & HW_FLAGS_VA32) != 0;
 
 ctx->zero = tcg_constant_tl(0);
+
+ctx->cpucfg1 = env->cpucfg[1];
 }
 
 static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index d7f69a7553..2be057e932 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -199,6 +199,10 @@ static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d 
*a)
 TCGv src1 = gpr_src(ctx, a->rd, EXT_NONE);
 TCGv src2 = tcg_constant_tl(a->imm);
 
+if (!avail_64(ctx)) {
+return false;
+}
+
 tcg_gen_deposit_tl(dest, src1, src2, 32, 32);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -211,6 +215,10 @@ static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d 
*a)
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 TCGv src2 = tcg_constant_tl(a->imm);
 
+if (!avail_64(ctx)) {
+return false;
+}
+
 tcg_gen_deposit_tl(dest, src1, src2, 52, 12);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -242,6 +250,10 @@ static bool trans_addu16i_d(DisasContext *ctx, 
arg_addu16i_d *a)
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
+if (!avail_64(ctx)) {
+return false;
+}
+
 tcg_gen_addi_tl(dest, src1, a->imm << 16);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -249,9 +261,9 @@ static bool trans_addu16i_d(DisasContext *ctx, 
arg_addu16i_d *a)
 }
 
 TRANS(add_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
-TRANS(add_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
+TRANS(add_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
 TRANS(sub_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
-TRANS(sub_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
+TRANS(sub_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
 TRANS(and, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl)
 TRANS(or, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl)
 TRANS(xor, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl)
@@ -261,32 +273,32 @@ TRANS(orn, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, 
tcg_gen_orc_tl)
 TRANS(slt, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt)
 TRANS(sltu, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu)
 TRANS(mul_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl)
-TRANS(mul_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
+TRANS(mul_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
 TRANS(mulh_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w)
 TRANS(mulh_wu, ALL, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_w)
-TRANS(mulh_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
-TRANS(mulh_du, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
-TRANS(mulw_d_w, ALL, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
-TRANS

[PATCH RESEND v5 16/19] target/loongarch: Add avail_LSPW to check LSPW instructions

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Message-ID: <20230822032724.1353391-13-gaos...@loongson.cn>
---
 target/loongarch/translate.h   | 1 +
 target/loongarch/insn_trans/trans_privileged.c.inc | 8 
 2 files changed, 9 insertions(+)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 0f244cd83b..f0d7b82932 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -20,6 +20,7 @@
 #define avail_FP(C)(FIELD_EX32((C)->cpucfg2, CPUCFG2, FP))
 #define avail_FP_SP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_SP))
 #define avail_FP_DP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_DP))
+#define avail_LSPW(C)  (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
 
 /*
  * If an operation is being performed on less than TARGET_LONG_BITS,
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc 
b/target/loongarch/insn_trans/trans_privileged.c.inc
index 684ff547a7..099cd871f0 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -437,6 +437,10 @@ static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a)
 TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
+if (!avail_LSPW(ctx)) {
+return true;
+}
+
 if (check_plv(ctx)) {
 return false;
 }
@@ -450,6 +454,10 @@ static bool trans_lddir(DisasContext *ctx, arg_lddir *a)
 TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 
+if (!avail_LSPW(ctx)) {
+return true;
+}
+
 if (check_plv(ctx)) {
 return false;
 }
-- 
2.41.0




[PATCH RESEND v5 14/19] hw/loongarch: Remove restriction of la464 cores in the virt machine

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

Allow virt machine to be used with la132 instead of la464.

Co-authored-by: Jiajie Chen 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-11-gaos...@loongson.cn>
---
 hw/loongarch/virt.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e19b042ce8..af15bf5aaa 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine)
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
 }
 
-if (!strstr(cpu_model, "la464")) {
-error_report("LoongArch/TCG needs cpu type la464");
-exit(1);
-}
-
 if (ram_size < 1 * GiB) {
 error_report("ram_size must be greater than 1G.");
 exit(1);
-- 
2.41.0




[PATCH RESEND v5 15/19] target/loongarch: Add avail_FP/FP_SP/FP_DP to check fpu instructions

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

Signed-off-by: Song Gao 
Acked-by: Richard Henderson 
Message-ID: <20230822032724.1353391-12-gaos...@loongson.cn>
---
 target/loongarch/translate.h  |  4 +
 target/loongarch/translate.c  |  1 +
 .../loongarch/insn_trans/trans_farith.c.inc   | 96 ---
 target/loongarch/insn_trans/trans_fcmp.c.inc  |  8 ++
 target/loongarch/insn_trans/trans_fcnv.c.inc  | 56 +--
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 32 +++
 target/loongarch/insn_trans/trans_fmov.c.inc  | 48 --
 7 files changed, 159 insertions(+), 86 deletions(-)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 1342446242..0f244cd83b 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -17,6 +17,9 @@
 #define avail_ALL(C)   true
 #define avail_64(C)(FIELD_EX32((C)->cpucfg1, CPUCFG1, ARCH) == \
 CPUCFG1_ARCH_LA64)
+#define avail_FP(C)(FIELD_EX32((C)->cpucfg2, CPUCFG2, FP))
+#define avail_FP_SP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_SP))
+#define avail_FP_DP(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, FP_DP))
 
 /*
  * If an operation is being performed on less than TARGET_LONG_BITS,
@@ -40,6 +43,7 @@ typedef struct DisasContext {
 bool la64; /* LoongArch64 mode */
 bool va32; /* 32-bit virtual address */
 uint32_t cpucfg1;
+uint32_t cpucfg2;
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 6967e12fc3..fd393ed76d 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -129,6 +129,7 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 ctx->zero = tcg_constant_tl(0);
 
 ctx->cpucfg1 = env->cpucfg[1];
+ctx->cpucfg2 = env->cpucfg[2];
 }
 
 static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
diff --git a/target/loongarch/insn_trans/trans_farith.c.inc 
b/target/loongarch/insn_trans/trans_farith.c.inc
index b1a1dc7b01..a7ced99fd3 100644
--- a/target/loongarch/insn_trans/trans_farith.c.inc
+++ b/target/loongarch/insn_trans/trans_farith.c.inc
@@ -67,6 +67,10 @@ static bool trans_fcopysign_s(DisasContext *ctx, 
arg_fcopysign_s *a)
 TCGv src1 = get_fpr(ctx, a->fk);
 TCGv src2 = get_fpr(ctx, a->fj);
 
+if (!avail_FP_SP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_deposit_i64(dest, src1, src2, 0, 31);
@@ -81,6 +85,10 @@ static bool trans_fcopysign_d(DisasContext *ctx, 
arg_fcopysign_d *a)
 TCGv src1 = get_fpr(ctx, a->fk);
 TCGv src2 = get_fpr(ctx, a->fj);
 
+if (!avail_FP_DP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_deposit_i64(dest, src1, src2, 0, 63);
@@ -94,6 +102,10 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 TCGv dest = get_fpr(ctx, a->fd);
 TCGv src = get_fpr(ctx, a->fj);
 
+if (!avail_FP_SP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 31));
@@ -108,6 +120,10 @@ static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
 TCGv dest = get_fpr(ctx, a->fd);
 TCGv src = get_fpr(ctx, a->fj);
 
+if (!avail_FP_DP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 63));
@@ -121,6 +137,10 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 TCGv dest = get_fpr(ctx, a->fd);
 TCGv src = get_fpr(ctx, a->fj);
 
+if (!avail_FP_SP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_xori_i64(dest, src, 0x8000);
@@ -135,6 +155,10 @@ static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
 TCGv dest = get_fpr(ctx, a->fd);
 TCGv src = get_fpr(ctx, a->fj);
 
+if (!avail_FP_DP(ctx)) {
+return false;
+}
+
 CHECK_FPE;
 
 tcg_gen_xori_i64(dest, src, 0x8000LL);
@@ -143,41 +167,41 @@ static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
 return true;
 }
 
-TRANS(fadd_s, ALL, gen_fff, gen_helper_fadd_s)
-TRANS(fadd_d, ALL, gen_fff, gen_helper_fadd_d)
-TRANS(fsub_s, ALL, gen_fff, gen_helper_fsub_s)
-TRANS(fsub_d, ALL, gen_fff, gen_helper_fsub_d)
-TRANS(fmul_s, ALL, gen_fff, gen_helper_fmul_s)
-TRANS(fmul_d, ALL, gen_fff, gen_helper_fmul_d)
-TRANS(fdiv_s, ALL, gen_fff, gen_helper_fdiv_s)
-TRANS(fdiv_d, ALL, gen_fff, gen_helper_fdiv_d)
-TRANS(fmax_s, ALL, gen_fff, gen_helper_fmax_s)
-TRANS(fmax_d, ALL, gen_fff, gen_helper_fmax_d)
-TRANS(fmin_s, ALL, gen_fff, gen_helper_fmin_s)
-TRANS(fmin_d, ALL, gen_fff, gen_helper_fmin_d)
-TRANS(fmaxa_s, ALL, gen_fff, gen_helper_fmaxa_s)
-TRANS(fmaxa_d, ALL, gen_fff, gen_helper_fmaxa_d)
-TRANS(fmina_s, ALL, gen_fff, gen_helper_fmina_s)
-TRANS(fmina_d, ALL, gen_fff, gen_helper_fmina_d)
-TRANS(fscaleb_s, ALL, gen_fff, gen_helper_fscaleb_s)
-TRANS(fscaleb_d, ALL, gen_fff, gen_helper_fscaleb_d)
-TRANS(fsqrt_s, ALL, gen_ff, gen_helper_fsqrt_s)
-TRANS(fsqr

[PATCH RESEND v5 11/19] target/loongarch: Add a check parameter to the TRANS macro

2023-08-22 Thread Philippe Mathieu-Daudé
From: Song Gao 

The default check parmeter is ALL.

Suggested-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-ID: <20230822032724.1353391-8-gaos...@loongson.cn>
---
 target/loongarch/translate.h  |6 +-
 target/loongarch/insn_trans/trans_arith.c.inc |   84 +-
 .../loongarch/insn_trans/trans_atomic.c.inc   |   80 +-
 target/loongarch/insn_trans/trans_bit.c.inc   |   56 +-
 .../loongarch/insn_trans/trans_branch.c.inc   |   20 +-
 target/loongarch/insn_trans/trans_extra.c.inc |   16 +-
 .../loongarch/insn_trans/trans_farith.c.inc   |   72 +-
 target/loongarch/insn_trans/trans_fcnv.c.inc  |   56 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  |   32 +-
 target/loongarch/insn_trans/trans_fmov.c.inc  |   16 +-
 target/loongarch/insn_trans/trans_lsx.c.inc   | 1236 -
 .../loongarch/insn_trans/trans_memory.c.inc   |   84 +-
 .../insn_trans/trans_privileged.c.inc |   16 +-
 target/loongarch/insn_trans/trans_shift.c.inc |   30 +-
 14 files changed, 903 insertions(+), 901 deletions(-)

diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index b6fa5df82d..3c5c746f30 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -10,9 +10,11 @@
 
 #include "exec/translator.h"
 
-#define TRANS(NAME, FUNC, ...) \
+#define TRANS(NAME, AVAIL, FUNC, ...) \
 static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
-{ return FUNC(ctx, a, __VA_ARGS__); }
+{ return avail_##AVAIL(ctx) && FUNC(ctx, a, __VA_ARGS__); }
+
+#define avail_ALL(C)   true
 
 /*
  * If an operation is being performed on less than TARGET_LONG_BITS,
diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 2aea4e41d5..d7f69a7553 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -248,45 +248,45 @@ static bool trans_addu16i_d(DisasContext *ctx, 
arg_addu16i_d *a)
 return true;
 }
 
-TRANS(add_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
-TRANS(add_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
-TRANS(sub_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
-TRANS(sub_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
-TRANS(and, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl)
-TRANS(or, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl)
-TRANS(xor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl)
-TRANS(nor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_nor_tl)
-TRANS(andn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_andc_tl)
-TRANS(orn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_orc_tl)
-TRANS(slt, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt)
-TRANS(sltu, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu)
-TRANS(mul_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl)
-TRANS(mul_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl)
-TRANS(mulh_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w)
-TRANS(mulh_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_w)
-TRANS(mulh_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d)
-TRANS(mulh_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du)
-TRANS(mulw_d_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl)
-TRANS(mulw_d_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl)
-TRANS(div_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_div_w)
-TRANS(mod_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_rem_w)
-TRANS(div_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_div_du)
-TRANS(mod_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_rem_du)
-TRANS(div_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d)
-TRANS(mod_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d)
-TRANS(div_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du)
-TRANS(mod_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du)
-TRANS(slti, gen_rri_v, EXT_NONE, EXT_NONE, gen_slt)
-TRANS(sltui, gen_rri_v, EXT_NONE, EXT_NONE, gen_sltu)
-TRANS(addi_w, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_addi_tl)
-TRANS(addi_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_addi_tl)
-TRANS(alsl_w, gen_rrr_sa, EXT_NONE, EXT_SIGN, gen_alsl)
-TRANS(alsl_wu, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl)
-TRANS(alsl_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl)
-TRANS(pcaddi, gen_pc, gen_pcaddi)
-TRANS(pcalau12i, gen_pc, gen_pcalau12i)
-TRANS(pcaddu12i, gen_pc, gen_pcaddu12i)
-TRANS(pcaddu18i, gen_pc, gen_pcaddu18i)
-TRANS(andi, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_andi_tl)
-TRANS(ori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_ori_tl)
-TRANS(xori, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_xori_tl)
+TRANS(add_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
+TRANS(add_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl)
+TRANS(sub_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl)
+TRANS(sub_d, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl)
+TRANS(and, ALL, gen_rrr, EX

[PATCH RESEND v5 13/19] target/loongarch: Add LoongArch32 cpu la132

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Add LoongArch32 cpu la132.

Due to lack of public documentation of la132, it is currently a
synthetic LoongArch32 cpu model. Details need to be added in the future.

Signed-off-by: Jiajie Chen 
Signed-off-by: Song Gao 
Acked-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-10-gaos...@loongson.cn>
---
 target/loongarch/cpu.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 67eb6c3135..d3c3e0d8a1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -440,6 +440,35 @@ static void loongarch_la464_initfn(Object *obj)
 env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
 }
 
+static void loongarch_la132_initfn(Object *obj)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = &cpu->env;
+
+int i;
+
+for (i = 0; i < 21; i++) {
+env->cpucfg[i] = 0x0;
+}
+
+cpu->dtb_compatible = "loongarch,Loongson-1C103";
+env->cpucfg[0] = 0x148042;  /* PRID */
+
+uint32_t data = 0;
+data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */
+data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
+data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */
+data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */
+data = FIELD_DP32(data, CPUCFG1, UAL, 1);
+data = FIELD_DP32(data, CPUCFG1, RI, 0);
+data = FIELD_DP32(data, CPUCFG1, EP, 0);
+data = FIELD_DP32(data, CPUCFG1, RPLV, 0);
+data = FIELD_DP32(data, CPUCFG1, HP, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1);
+env->cpucfg[1] = data;
+}
+
 static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
 {
 const char *typename = object_class_get_name(OBJECT_CLASS(data));
@@ -787,6 +816,7 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 .class_init = loongarch64_cpu_class_init,
 },
 DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn),
+DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn),
 };
 
 DEFINE_TYPES(loongarch_cpu_type_infos)
-- 
2.41.0




[PATCH RESEND v5 10/19] target/loongarch: Sign extend results in VA32 mode

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

In VA32 mode, BL, JIRL and PC* instructions should sign-extend the low
32 bit result to 64 bits.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-7-gaos...@loongson.cn>
---
 target/loongarch/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 9a23ec786d..de7c1c5d1f 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -238,6 +238,9 @@ static TCGv make_address_i(DisasContext *ctx, TCGv base, 
target_long ofs)
 
 static uint64_t make_address_pc(DisasContext *ctx, uint64_t addr)
 {
+if (ctx->va32) {
+addr = (int32_t)addr;
+}
 return addr;
 }
 
-- 
2.41.0




Re: [PATCH v5 00/19] Based-on: https://patchew.org/QEMU/20230821125959.28666-1-phi...@linaro.org/

2023-08-22 Thread Philippe Mathieu-Daudé

On 22/8/23 09:09, Philippe Mathieu-Daudé wrote:

(all series reviewed, for Song Gao to pick whichever v4/v5 is preferred)


Incorrect subject, and SMTP failure, so disregard (will resend).



[PATCH RESEND v5 07/19] target/loongarch: Extract make_address_pc() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-7-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c   | 5 +
 target/loongarch/insn_trans/trans_arith.c.inc  | 2 +-
 target/loongarch/insn_trans/trans_branch.c.inc | 4 ++--
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index acc54d7587..8b26555a27 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -226,6 +226,11 @@ static TCGv make_address_i(DisasContext *ctx, TCGv base, 
target_long ofs)
 return make_address_x(ctx, base, addend);
 }
 
+static uint64_t make_address_pc(DisasContext *ctx, uint64_t addr)
+{
+return addr;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 43d6cf261d..2aea4e41d5 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -72,7 +72,7 @@ static bool gen_pc(DisasContext *ctx, arg_r_i *a,
target_ulong (*func)(target_ulong, int))
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
-target_ulong addr = func(ctx->base.pc_next, a->imm);
+target_ulong addr = make_address_pc(ctx, func(ctx->base.pc_next, a->imm));
 
 tcg_gen_movi_tl(dest, addr);
 gen_set_gpr(a->rd, dest, EXT_NONE);
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index 3ad34bcc05..2e35572cea 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -12,7 +12,7 @@ static bool trans_b(DisasContext *ctx, arg_b *a)
 
 static bool trans_bl(DisasContext *ctx, arg_bl *a)
 {
-tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
+tcg_gen_movi_tl(cpu_gpr[1], make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -25,7 +25,7 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 
 TCGv addr = make_address_i(ctx, src1, a->imm);
 tcg_gen_mov_tl(cpu_pc, addr);
-tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
+tcg_gen_movi_tl(dest, make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
 ctx->base.is_jmp = DISAS_NORETURN;
-- 
2.41.0




[PATCH RESEND v5 09/19] target/loongarch: Truncate high 32 bits of address in VA32 mode

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

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 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
---
 target/loongarch/cpu.h   |  6 +-
 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 e1562695e8..25a0ef7e41 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 8b26555a27..9a23ec786d 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)
-- 
2.41.0




[PATCH RESEND v5 08/19] target/loongarch: Extract set_pc() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/cpu.h   |  5 +
 target/loongarch/cpu.c   | 16 
 target/loongarch/gdbstub.c   |  2 +-
 target/loongarch/op_helper.c |  4 ++--
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 72109095e4..e1562695e8 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -443,6 +443,11 @@ static inline bool is_va32(CPULoongArchState *env)
 return va32;
 }
 
+static inline void set_pc(CPULoongArchState *env, uint64_t value)
+{
+env->pc = value;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 822f2a72e5..67eb6c3135 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -81,7 +81,7 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = value;
+set_pc(env, value);
 }
 
 static vaddr loongarch_cpu_get_pc(CPUState *cs)
@@ -168,7 +168,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 set_DERA:
 env->CSR_DERA = env->pc;
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
-env->pc = env->CSR_EENTRY + 0x480;
+set_pc(env, env->CSR_EENTRY + 0x480);
 break;
 case EXCCODE_INT:
 if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
@@ -249,7 +249,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 
 /* Find the highest-priority interrupt. */
 vector = 31 - clz32(pending);
-env->pc = env->CSR_EENTRY + (EXCCODE_EXTERNAL_INT + vector) * vec_size;
+set_pc(env, env->CSR_EENTRY + \
+   (EXCCODE_EXTERNAL_INT + vector) * vec_size);
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
   " cause %d\n" "A " TARGET_FMT_lx " D "
@@ -260,10 +261,9 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
   env->CSR_ECFG, env->CSR_ESTAT);
 } else {
 if (tlbfill) {
-env->pc = env->CSR_TLBRENTRY;
+set_pc(env, env->CSR_TLBRENTRY);
 } else {
-env->pc = env->CSR_EENTRY;
-env->pc += EXCODE_MCODE(cause) * vec_size;
+set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size);
 }
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
@@ -324,7 +324,7 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
 CPULoongArchState *env = &cpu->env;
 
 tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
-env->pc = tb->pc;
+set_pc(env, tb->pc);
 }
 
 static void loongarch_restore_state_to_opc(CPUState *cs,
@@ -334,7 +334,7 @@ static void loongarch_restore_state_to_opc(CPUState *cs,
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = data[0];
+set_pc(env, data[0]);
 }
 #endif /* CONFIG_TCG */
 
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index a462e25737..e20b20f99b 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -77,7 +77,7 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gpr[n] = tmp;
 length = read_length;
 } else if (n == 33) {
-env->pc = tmp;
+set_pc(env, tmp);
 length = read_length;
 }
 return length;
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index 60335a05e2..cf84f20aba 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -114,14 +114,14 @@ void helper_ertn(CPULoongArchState *env)
 env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 
0);
 env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 0);
 env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 1);
-env->pc = env->CSR_TLBRERA;
+set_pc(env, env->CSR_TLBRERA);
 qemu_log_mask(CPU_LOG_INT, "%s: TLBRERA " TARGET_FMT_lx "\n",
   __func__, env->CSR_TLBRERA);
 } else {
 csr_pplv = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV);
 csr_pie = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE);
 
-env->pc = env->CSR_ERA;
+set_pc(env, env->CSR_ERA);
 qemu_log_mask(CPU_LOG_INT, "%s: ERA " TARGET_FMT_lx "\n",
   __func__, env->CSR_ERA);
 }
-- 
2.41.0




[PATCH RESEND v5 03/19] target/loongarch: Support LoongArch32 VPPN

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-4-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  6 --
 target/loongarch/tlb_helper.c | 23 ++-
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index b93f99a9ef..c59d7a9fcb 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
 FIELD(CSR_TLBIDX, NE, 31, 1)
 
 #define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */
-FIELD(CSR_TLBEHI, VPPN, 13, 35)
+FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBEHI_64, VPPN, 13, 35)
 
 #define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
 #define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
@@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
 #define LOONGARCH_CSR_TLBRELO1   0x8d /* TLB refill entrylo1 */
 #define LOONGARCH_CSR_TLBREHI0x8e /* TLB refill entryhi */
 FIELD(CSR_TLBREHI, PS, 0, 6)
-FIELD(CSR_TLBREHI, VPPN, 13, 35)
+FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBREHI_64, VPPN, 13, 35)
 #define LOONGARCH_CSR_TLBRPRMD   0x8f /* TLB refill mode info */
 FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
 FIELD(CSR_TLBRPRMD, PIE, 2, 1)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 1f8e7911c7..c8b8b0497f 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -300,8 +300,13 @@ static void raise_mmu_exception(CPULoongArchState *env, 
target_ulong address,
 
 if (tlb_error == TLBRET_NOMATCH) {
 env->CSR_TLBRBADV = address;
-env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
-  extract64(address, 13, 35));
+if (is_la64(env)) {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
+VPPN, extract64(address, 13, 35));
+} else {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
+VPPN, extract64(address, 13, 19));
+}
 } else {
 if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
 env->CSR_BADV = address;
@@ -366,12 +371,20 @@ static void fill_tlb_entry(CPULoongArchState *env, int 
index)
 
 if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
 csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
+}
 lo0 = env->CSR_TLBRELO0;
 lo1 = env->CSR_TLBRELO1;
 } else {
 csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
+}
 lo0 = env->CSR_TLBELO0;
 lo1 = env->CSR_TLBELO1;
 }
@@ -491,7 +504,7 @@ void helper_tlbfill(CPULoongArchState *env)
 
 if (pagesize == stlb_ps) {
 /* Only write into STLB bits [47:13] */
-address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
 
 /* Choose one set ramdomly */
 set = get_random_tlb(0, 7);
-- 
2.41.0




[PATCH RESEND v5 05/19] target/loongarch: Extract make_address_x() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c   | 12 
 .../loongarch/insn_trans/trans_fmemory.c.inc   | 18 ++
 target/loongarch/insn_trans/trans_lsx.c.inc|  6 ++
 target/loongarch/insn_trans/trans_memory.c.inc |  6 ++
 4 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index ac847745df..a68a979a55 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -208,6 +208,18 @@ static void set_fpr(int reg_num, TCGv val)
offsetof(CPULoongArchState, fpr[reg_num].vreg.D(0)));
 }
 
+static TCGv make_address_x(DisasContext *ctx, TCGv base, TCGv addend)
+{
+TCGv temp = NULL;
+
+if (addend) {
+temp = tcg_temp_new();
+tcg_gen_add_tl(temp, base, addend);
+base = temp;
+}
+return base;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 91c09fb6d9..88ad209338 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -57,8 +57,7 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -75,8 +74,7 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
 return true;
@@ -91,9 +89,8 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtgt_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -110,9 +107,8 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtgt_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
 return true;
@@ -127,9 +123,8 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtle_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -146,9 +141,8 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtle_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 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..875cb7d51d 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4315,14 +4315,13 @@ static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
 
 CHECK_SXE;
 
-addr = tcg_temp_new();
 src1 = gpr_src(ctx, a->rj, EXT_NONE);
 src2 = gpr_src(ctx, a->rk, EXT_NONE);
 val = tcg_temp_new_i128();
 rl = tcg_temp_new_i64();
 rh = tcg_temp_new_i64();
 
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 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);
@@ -4339,14 +4338,13 @@ static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
 
 CHECK_SXE;
 
-addr = tcg_temp_new();
 src1 = gpr_src(ctx, a->rj, EXT_NONE);
 src2 = gpr_src(ctx, a->rk, EXT_NONE);
 val = tcg_temp_new_i128();
 ah = tcg_temp_new_i64();
 al = tcg_temp_new_i64();
 
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 get_vreg64(ah, a->vd, 1);
 get_vreg64(al, a->vd, 0);
 tcg_gen_concat_i64_i128(val, al, ah);
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/ins

[PATCH RESEND v5 06/19] target/loongarch: Extract make_address_i() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c  |  6 
 .../loongarch/insn_trans/trans_atomic.c.inc   |  5 +--
 .../loongarch/insn_trans/trans_branch.c.inc   |  3 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 12 ++-
 target/loongarch/insn_trans/trans_lsx.c.inc   | 32 +--
 .../loongarch/insn_trans/trans_memory.c.inc   | 28 +---
 6 files changed, 29 insertions(+), 57 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index a68a979a55..acc54d7587 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -220,6 +220,12 @@ static TCGv make_address_x(DisasContext *ctx, TCGv base, 
TCGv addend)
 return base;
 }
 
+static TCGv make_address_i(DisasContext *ctx, TCGv base, target_long ofs)
+{
+TCGv addend = ofs ? tcg_constant_tl(ofs) : NULL;
+return make_address_x(ctx, base, addend);
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 612709f2a7..fbc081448d 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -7,9 +7,8 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
-TCGv t0 = tcg_temp_new();
+TCGv t0 = make_address_i(ctx, src1, a->imm);
 
-tcg_gen_addi_tl(t0, src1, a->imm);
 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));
@@ -62,6 +61,8 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
 return false;
 }
 
+addr = make_address_i(ctx, addr, 0);
+
 func(dest, addr, val, ctx->mem_idx, mop);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index a860f7e733..3ad34bcc05 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -23,7 +23,8 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
-tcg_gen_addi_tl(cpu_pc, src1, a->imm);
+TCGv addr = make_address_i(ctx, src1, a->imm);
+tcg_gen_mov_tl(cpu_pc, addr);
 tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 88ad209338..bd3aba2c49 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -17,11 +17,7 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, 
MemOp mop)
 
 CHECK_FPE;
 
-if (a->imm) {
-TCGv temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
@@ -37,11 +33,7 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, 
MemOp mop)
 
 CHECK_FPE;
 
-if (a->imm) {
-TCGv temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_st_tl(src, addr, ctx->mem_idx, mop);
 
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 875cb7d51d..50153d6d0b 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4255,7 +4255,7 @@ TRANS(vextrins_d, gen_vv_i, gen_helper_vextrins_d)
 
 static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 {
-TCGv addr, temp;
+TCGv addr;
 TCGv_i64 rl, rh;
 TCGv_i128 val;
 
@@ -4266,11 +4266,7 @@ static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 rl = tcg_temp_new_i64();
 rh = tcg_temp_new_i64();
 
-if (a->imm) {
-temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
 tcg_gen_extr_i128_i64(rl, rh, val);
@@ -4282,7 +4278,7 @@ static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 
 static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
 {
-TCGv 

[PATCH RESEND v5 04/19] target/loongarch: Add LA64 & VA32 to DisasContext

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Add LA64 and VA32(32-bit Virtual Address) to DisasContext to allow the
translator to reject doubleword instructions in LA32 mode for example.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-5-gaos...@loongson.cn>
---
 target/loongarch/cpu.h   | 13 +
 target/loongarch/translate.h |  2 ++
 target/loongarch/translate.c |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index b8af491041..72109095e4 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -432,6 +432,17 @@ static inline bool is_la64(CPULoongArchState *env)
 return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
 }
 
+static inline bool is_va32(CPULoongArchState *env)
+{
+/* VA32 if !LA64 or VA32L[1-3] */
+bool va32 = !is_la64(env);
+uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
+va32 = true;
+}
+return va32;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
@@ -439,6 +450,7 @@ static inline bool is_la64(CPULoongArchState *env)
 #define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_EUEN_FPE   0x04
 #define HW_FLAGS_EUEN_SXE   0x08
+#define HW_FLAGS_VA32   0x20
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
@@ -448,6 +460,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env, vaddr *pc,
 *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;
 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
+*flags |= is_va32(env) * HW_FLAGS_VA32;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 7f60090580..b6fa5df82d 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -33,6 +33,8 @@ typedef struct DisasContext {
 uint16_t plv;
 int vl;   /* Vector length */
 TCGv zero;
+bool la64; /* LoongArch64 mode */
+bool va32; /* 32-bit virtual address */
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 3146a2d4ac..ac847745df 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -119,6 +119,9 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 ctx->vl = LSX_LEN;
 }
 
+ctx->la64 = is_la64(env);
+ctx->va32 = (ctx->base.tb->flags & HW_FLAGS_VA32) != 0;
+
 ctx->zero = tcg_constant_tl(0);
 }
 
-- 
2.41.0




[PATCH RESEND v5 01/19] target/loongarch: Support LoongArch32 TLB entry

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

The TLB entry of LA32 lacks NR, NX and RPLV and they are hardwired to
zero in LoongArch32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-2-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  9 +
 target/loongarch/tlb_helper.c | 17 -
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index f8f24032cb..48ed2e0632 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -66,10 +66,11 @@ FIELD(TLBENTRY, D, 1, 1)
 FIELD(TLBENTRY, PLV, 2, 2)
 FIELD(TLBENTRY, MAT, 4, 2)
 FIELD(TLBENTRY, G, 6, 1)
-FIELD(TLBENTRY, PPN, 12, 36)
-FIELD(TLBENTRY, NR, 61, 1)
-FIELD(TLBENTRY, NX, 62, 1)
-FIELD(TLBENTRY, RPLV, 63, 1)
+FIELD(TLBENTRY_32, PPN, 8, 24)
+FIELD(TLBENTRY_64, PPN, 12, 36)
+FIELD(TLBENTRY_64, NR, 61, 1)
+FIELD(TLBENTRY_64, NX, 62, 1)
+FIELD(TLBENTRY_64, RPLV, 63, 1)
 
 #define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
 FIELD(CSR_ASID, ASID, 0, 10)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 6e00190547..cef10e2257 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -48,10 +48,17 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
 tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
 tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
 tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
-tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY, PPN);
-tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY, NX);
-tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY, NR);
-tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY, RPLV);
+if (is_la64(env)) {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
+tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
+tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
+tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
+} else {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
+tlb_nx = 0;
+tlb_nr = 0;
+tlb_rplv = 0;
+}
 
 /* Check access rights */
 if (!tlb_v) {
@@ -79,7 +86,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
  * tlb_entry contains ppn[47:12] while 16KiB ppn is [47:15]
  * need adjust.
  */
-*physical = (tlb_ppn << R_TLBENTRY_PPN_SHIFT) |
+*physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
 (address & MAKE_64BIT_MASK(0, tlb_ps));
 *prot = PAGE_READ;
 if (tlb_d) {
-- 
2.41.0




[PATCH RESEND v5 02/19] target/loongarch: Support LoongArch32 DMW

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

LA32 uses a different encoding for CSR.DMW and a new direct mapping
mechanism.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-3-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  7 +++
 target/loongarch/tlb_helper.c | 26 +++---
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 48ed2e0632..b93f99a9ef 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -188,10 +188,9 @@ FIELD(CSR_DMW, PLV1, 1, 1)
 FIELD(CSR_DMW, PLV2, 2, 1)
 FIELD(CSR_DMW, PLV3, 3, 1)
 FIELD(CSR_DMW, MAT, 4, 2)
-FIELD(CSR_DMW, VSEG, 60, 4)
-
-#define dmw_va2pa(va) \
-(va & MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS))
+FIELD(CSR_DMW_32, PSEG, 25, 3)
+FIELD(CSR_DMW_32, VSEG, 29, 3)
+FIELD(CSR_DMW_64, VSEG, 60, 4)
 
 /* Debug CSRs */
 #define LOONGARCH_CSR_DBG0x500 /* debug config */
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index cef10e2257..1f8e7911c7 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -173,6 +173,18 @@ static int loongarch_map_address(CPULoongArchState *env, 
hwaddr *physical,
 return TLBRET_NOMATCH;
 }
 
+static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
+target_ulong dmw)
+{
+if (is_la64(env)) {
+return va & TARGET_VIRT_MASK;
+} else {
+uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG);
+return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \
+(pseg << R_CSR_DMW_32_VSEG_SHIFT);
+}
+}
+
 static int get_physical_address(CPULoongArchState *env, hwaddr *physical,
 int *prot, target_ulong address,
 MMUAccessType access_type, int mmu_idx)
@@ -192,12 +204,20 @@ static int get_physical_address(CPULoongArchState *env, 
hwaddr *physical,
 }
 
 plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
-base_v = address >> R_CSR_DMW_VSEG_SHIFT;
+if (is_la64(env)) {
+base_v = address >> R_CSR_DMW_64_VSEG_SHIFT;
+} else {
+base_v = address >> R_CSR_DMW_32_VSEG_SHIFT;
+}
 /* Check direct map window */
 for (int i = 0; i < 4; i++) {
-base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW, VSEG);
+if (is_la64(env)) {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG);
+} else {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
+}
 if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
-*physical = dmw_va2pa(address);
+*physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
-- 
2.41.0




[PATCH RESEND v5 00/19] Add some checks before translating instructions

2023-08-22 Thread Philippe Mathieu-Daudé
Based-on: https://patchew.org/QEMU/20230821125959.28666-1-phi...@linaro.org/

(all series reviewed, for Song Gao to pick whichever v4/v5 is preferred)

Hi,

This series adds some checks before translating instructions

This includes:

CPUCFG[1].IOCSR

CPUCFG[2].FP
CPUCFG[2].FP_SP
CPUCFG[2].FP_DP
CPUCFG[2].LSPW
CPUCFG[2].LAM
CPUCFG[2].LSX

V5:
- Split 2 patches, extracting helpers
- R-b

V4:
- Rebase;
- Split patch 'Add LoongArch32 cpu la132' in two patch; (PMD)
- Remove unrelated cpucfgX;(PMD)
- R-b.

V3:
- Rebase;
- The la32 instructions following Table 2 at [2].

V2:
- Add a check parameter to the TRANS macro.
- remove TRANS_64.
- Add avail_ALL/64/FP/FP_SP/FP_DP/LSPW/LAM/LSX/IOCSR
  to check instructions.

[1]: https://patchew.org/QEMU/20230809083258.1787464-...@jia.je/
[2]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#overview-of-basic-integer-instructions

Jiajie Chen (11):
  target/loongarch: Support LoongArch32 TLB entry
  target/loongarch: Support LoongArch32 DMW
  target/loongarch: Support LoongArch32 VPPN
  target/loongarch: Add LA64 & VA32 to DisasContext
  target/loongarch: Extract make_address_x() helper
  target/loongarch: Extract make_address_i() helper
  target/loongarch: Extract make_address_pc() helper
  target/loongarch: Extract set_pc() helper
  target/loongarch: Truncate high 32 bits of address in VA32 mode
  target/loongarch: Sign extend results in VA32 mode
  target/loongarch: Add LoongArch32 cpu la132

Song Gao (8):
  target/loongarch: Add a check parameter to the TRANS macro
  target/loongarch: Add avail_64 to check la64-only instructions
  hw/loongarch: Remove restriction of la464 cores in the virt machine
  target/loongarch: Add avail_FP/FP_SP/FP_DP to check fpu instructions
  target/loongarch: Add avail_LSPW to check LSPW instructions
  target/loongarch: Add avail_LAM to check atomic instructions
  target/loongarch: Add avail_LSX to check LSX instructions
  target/loongarch: Add avail_IOCSR to check iocsr instructions

 target/loongarch/cpu-csr.h|   22 +-
 target/loongarch/cpu.h|   22 +
 target/loongarch/translate.h  |   19 +-
 hw/loongarch/virt.c   |5 -
 target/loongarch/cpu.c|   46 +-
 target/loongarch/gdbstub.c|2 +-
 target/loongarch/op_helper.c  |4 +-
 target/loongarch/tlb_helper.c |   66 +-
 target/loongarch/translate.c  |   46 +
 target/loongarch/insn_trans/trans_arith.c.inc |   98 +-
 .../loongarch/insn_trans/trans_atomic.c.inc   |   85 +-
 target/loongarch/insn_trans/trans_bit.c.inc   |   56 +-
 .../loongarch/insn_trans/trans_branch.c.inc   |   27 +-
 target/loongarch/insn_trans/trans_extra.c.inc |   24 +-
 .../loongarch/insn_trans/trans_farith.c.inc   |   96 +-
 target/loongarch/insn_trans/trans_fcmp.c.inc  |8 +
 target/loongarch/insn_trans/trans_fcnv.c.inc  |   56 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  |   62 +-
 target/loongarch/insn_trans/trans_fmov.c.inc  |   52 +-
 target/loongarch/insn_trans/trans_lsx.c.inc   | 1434 +
 .../loongarch/insn_trans/trans_memory.c.inc   |  118 +-
 .../insn_trans/trans_privileged.c.inc |   24 +-
 target/loongarch/insn_trans/trans_shift.c.inc |   34 +-
 23 files changed, 1386 insertions(+), 1020 deletions(-)

-- 
2.41.0




[PATCH v5 08/19] target/loongarch: Extract set_pc() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/cpu.h   |  5 +
 target/loongarch/cpu.c   | 16 
 target/loongarch/gdbstub.c   |  2 +-
 target/loongarch/op_helper.c |  4 ++--
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 72109095e4..e1562695e8 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -443,6 +443,11 @@ static inline bool is_va32(CPULoongArchState *env)
 return va32;
 }
 
+static inline void set_pc(CPULoongArchState *env, uint64_t value)
+{
+env->pc = value;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 822f2a72e5..67eb6c3135 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -81,7 +81,7 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = value;
+set_pc(env, value);
 }
 
 static vaddr loongarch_cpu_get_pc(CPUState *cs)
@@ -168,7 +168,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 set_DERA:
 env->CSR_DERA = env->pc;
 env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
-env->pc = env->CSR_EENTRY + 0x480;
+set_pc(env, env->CSR_EENTRY + 0x480);
 break;
 case EXCCODE_INT:
 if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
@@ -249,7 +249,8 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 
 /* Find the highest-priority interrupt. */
 vector = 31 - clz32(pending);
-env->pc = env->CSR_EENTRY + (EXCCODE_EXTERNAL_INT + vector) * vec_size;
+set_pc(env, env->CSR_EENTRY + \
+   (EXCCODE_EXTERNAL_INT + vector) * vec_size);
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
   " cause %d\n" "A " TARGET_FMT_lx " D "
@@ -260,10 +261,9 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
   env->CSR_ECFG, env->CSR_ESTAT);
 } else {
 if (tlbfill) {
-env->pc = env->CSR_TLBRENTRY;
+set_pc(env, env->CSR_TLBRENTRY);
 } else {
-env->pc = env->CSR_EENTRY;
-env->pc += EXCODE_MCODE(cause) * vec_size;
+set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size);
 }
 qemu_log_mask(CPU_LOG_INT,
   "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx
@@ -324,7 +324,7 @@ static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
 CPULoongArchState *env = &cpu->env;
 
 tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
-env->pc = tb->pc;
+set_pc(env, tb->pc);
 }
 
 static void loongarch_restore_state_to_opc(CPUState *cs,
@@ -334,7 +334,7 @@ static void loongarch_restore_state_to_opc(CPUState *cs,
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);
 CPULoongArchState *env = &cpu->env;
 
-env->pc = data[0];
+set_pc(env, data[0]);
 }
 #endif /* CONFIG_TCG */
 
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index a462e25737..e20b20f99b 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -77,7 +77,7 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t 
*mem_buf, int n)
 env->gpr[n] = tmp;
 length = read_length;
 } else if (n == 33) {
-env->pc = tmp;
+set_pc(env, tmp);
 length = read_length;
 }
 return length;
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index 60335a05e2..cf84f20aba 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -114,14 +114,14 @@ void helper_ertn(CPULoongArchState *env)
 env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 
0);
 env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 0);
 env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 1);
-env->pc = env->CSR_TLBRERA;
+set_pc(env, env->CSR_TLBRERA);
 qemu_log_mask(CPU_LOG_INT, "%s: TLBRERA " TARGET_FMT_lx "\n",
   __func__, env->CSR_TLBRERA);
 } else {
 csr_pplv = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV);
 csr_pie = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE);
 
-env->pc = env->CSR_ERA;
+set_pc(env, env->CSR_ERA);
 qemu_log_mask(CPU_LOG_INT, "%s: ERA " TARGET_FMT_lx "\n",
   __func__, env->CSR_ERA);
 }
-- 
2.41.0




[PATCH v5 06/19] target/loongarch: Extract make_address_i() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c  |  6 
 .../loongarch/insn_trans/trans_atomic.c.inc   |  5 +--
 .../loongarch/insn_trans/trans_branch.c.inc   |  3 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 12 ++-
 target/loongarch/insn_trans/trans_lsx.c.inc   | 32 +--
 .../loongarch/insn_trans/trans_memory.c.inc   | 28 +---
 6 files changed, 29 insertions(+), 57 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index a68a979a55..acc54d7587 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -220,6 +220,12 @@ static TCGv make_address_x(DisasContext *ctx, TCGv base, 
TCGv addend)
 return base;
 }
 
+static TCGv make_address_i(DisasContext *ctx, TCGv base, target_long ofs)
+{
+TCGv addend = ofs ? tcg_constant_tl(ofs) : NULL;
+return make_address_x(ctx, base, addend);
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
index 612709f2a7..fbc081448d 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -7,9 +7,8 @@ static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
-TCGv t0 = tcg_temp_new();
+TCGv t0 = make_address_i(ctx, src1, a->imm);
 
-tcg_gen_addi_tl(t0, src1, a->imm);
 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));
@@ -62,6 +61,8 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
 return false;
 }
 
+addr = make_address_i(ctx, addr, 0);
+
 func(dest, addr, val, ctx->mem_idx, mop);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index a860f7e733..3ad34bcc05 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -23,7 +23,8 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
 
-tcg_gen_addi_tl(cpu_pc, src1, a->imm);
+TCGv addr = make_address_i(ctx, src1, a->imm);
+tcg_gen_mov_tl(cpu_pc, addr);
 tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 88ad209338..bd3aba2c49 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -17,11 +17,7 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, 
MemOp mop)
 
 CHECK_FPE;
 
-if (a->imm) {
-TCGv temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
@@ -37,11 +33,7 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, 
MemOp mop)
 
 CHECK_FPE;
 
-if (a->imm) {
-TCGv temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_st_tl(src, addr, ctx->mem_idx, mop);
 
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 875cb7d51d..50153d6d0b 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4255,7 +4255,7 @@ TRANS(vextrins_d, gen_vv_i, gen_helper_vextrins_d)
 
 static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 {
-TCGv addr, temp;
+TCGv addr;
 TCGv_i64 rl, rh;
 TCGv_i128 val;
 
@@ -4266,11 +4266,7 @@ static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 rl = tcg_temp_new_i64();
 rh = tcg_temp_new_i64();
 
-if (a->imm) {
-temp = tcg_temp_new();
-tcg_gen_addi_tl(temp, addr, a->imm);
-addr = temp;
-}
+addr = make_address_i(ctx, addr, a->imm);
 
 tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
 tcg_gen_extr_i128_i64(rl, rh, val);
@@ -4282,7 +4278,7 @@ static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
 
 static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
 {
-TCGv 

[PATCH v5 09/19] target/loongarch: Truncate high 32 bits of address in VA32 mode

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

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 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
---
 target/loongarch/cpu.h   |  6 +-
 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 e1562695e8..25a0ef7e41 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 8b26555a27..9a23ec786d 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)
-- 
2.41.0




[PATCH v5 02/19] target/loongarch: Support LoongArch32 DMW

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

LA32 uses a different encoding for CSR.DMW and a new direct mapping
mechanism.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-3-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  7 +++
 target/loongarch/tlb_helper.c | 26 +++---
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 48ed2e0632..b93f99a9ef 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -188,10 +188,9 @@ FIELD(CSR_DMW, PLV1, 1, 1)
 FIELD(CSR_DMW, PLV2, 2, 1)
 FIELD(CSR_DMW, PLV3, 3, 1)
 FIELD(CSR_DMW, MAT, 4, 2)
-FIELD(CSR_DMW, VSEG, 60, 4)
-
-#define dmw_va2pa(va) \
-(va & MAKE_64BIT_MASK(0, TARGET_VIRT_ADDR_SPACE_BITS))
+FIELD(CSR_DMW_32, PSEG, 25, 3)
+FIELD(CSR_DMW_32, VSEG, 29, 3)
+FIELD(CSR_DMW_64, VSEG, 60, 4)
 
 /* Debug CSRs */
 #define LOONGARCH_CSR_DBG0x500 /* debug config */
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index cef10e2257..1f8e7911c7 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -173,6 +173,18 @@ static int loongarch_map_address(CPULoongArchState *env, 
hwaddr *physical,
 return TLBRET_NOMATCH;
 }
 
+static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
+target_ulong dmw)
+{
+if (is_la64(env)) {
+return va & TARGET_VIRT_MASK;
+} else {
+uint32_t pseg = FIELD_EX32(dmw, CSR_DMW_32, PSEG);
+return (va & MAKE_64BIT_MASK(0, R_CSR_DMW_32_VSEG_SHIFT)) | \
+(pseg << R_CSR_DMW_32_VSEG_SHIFT);
+}
+}
+
 static int get_physical_address(CPULoongArchState *env, hwaddr *physical,
 int *prot, target_ulong address,
 MMUAccessType access_type, int mmu_idx)
@@ -192,12 +204,20 @@ static int get_physical_address(CPULoongArchState *env, 
hwaddr *physical,
 }
 
 plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
-base_v = address >> R_CSR_DMW_VSEG_SHIFT;
+if (is_la64(env)) {
+base_v = address >> R_CSR_DMW_64_VSEG_SHIFT;
+} else {
+base_v = address >> R_CSR_DMW_32_VSEG_SHIFT;
+}
 /* Check direct map window */
 for (int i = 0; i < 4; i++) {
-base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW, VSEG);
+if (is_la64(env)) {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG);
+} else {
+base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
+}
 if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
-*physical = dmw_va2pa(address);
+*physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TLBRET_MATCH;
 }
-- 
2.41.0




[PATCH v5 07/19] target/loongarch: Extract make_address_pc() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-7-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c   | 5 +
 target/loongarch/insn_trans/trans_arith.c.inc  | 2 +-
 target/loongarch/insn_trans/trans_branch.c.inc | 4 ++--
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index acc54d7587..8b26555a27 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -226,6 +226,11 @@ static TCGv make_address_i(DisasContext *ctx, TCGv base, 
target_long ofs)
 return make_address_x(ctx, base, addend);
 }
 
+static uint64_t make_address_pc(DisasContext *ctx, uint64_t addr)
+{
+return addr;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
index 43d6cf261d..2aea4e41d5 100644
--- a/target/loongarch/insn_trans/trans_arith.c.inc
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -72,7 +72,7 @@ static bool gen_pc(DisasContext *ctx, arg_r_i *a,
target_ulong (*func)(target_ulong, int))
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
-target_ulong addr = func(ctx->base.pc_next, a->imm);
+target_ulong addr = make_address_pc(ctx, func(ctx->base.pc_next, a->imm));
 
 tcg_gen_movi_tl(dest, addr);
 gen_set_gpr(a->rd, dest, EXT_NONE);
diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
index 3ad34bcc05..2e35572cea 100644
--- a/target/loongarch/insn_trans/trans_branch.c.inc
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -12,7 +12,7 @@ static bool trans_b(DisasContext *ctx, arg_b *a)
 
 static bool trans_bl(DisasContext *ctx, arg_bl *a)
 {
-tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
+tcg_gen_movi_tl(cpu_gpr[1], make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
 ctx->base.is_jmp = DISAS_NORETURN;
 return true;
@@ -25,7 +25,7 @@ static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
 
 TCGv addr = make_address_i(ctx, src1, a->imm);
 tcg_gen_mov_tl(cpu_pc, addr);
-tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
+tcg_gen_movi_tl(dest, make_address_pc(ctx, ctx->base.pc_next + 4));
 gen_set_gpr(a->rd, dest, EXT_NONE);
 tcg_gen_lookup_and_goto_ptr();
 ctx->base.is_jmp = DISAS_NORETURN;
-- 
2.41.0




[PATCH v5 04/19] target/loongarch: Add LA64 & VA32 to DisasContext

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Add LA64 and VA32(32-bit Virtual Address) to DisasContext to allow the
translator to reject doubleword instructions in LA32 mode for example.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-5-gaos...@loongson.cn>
---
 target/loongarch/cpu.h   | 13 +
 target/loongarch/translate.h |  2 ++
 target/loongarch/translate.c |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index b8af491041..72109095e4 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -432,6 +432,17 @@ static inline bool is_la64(CPULoongArchState *env)
 return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64;
 }
 
+static inline bool is_va32(CPULoongArchState *env)
+{
+/* VA32 if !LA64 or VA32L[1-3] */
+bool va32 = !is_la64(env);
+uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
+va32 = true;
+}
+return va32;
+}
+
 /*
  * LoongArch CPUs hardware flags.
  */
@@ -439,6 +450,7 @@ static inline bool is_la64(CPULoongArchState *env)
 #define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_EUEN_FPE   0x04
 #define HW_FLAGS_EUEN_SXE   0x08
+#define HW_FLAGS_VA32   0x20
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
 uint64_t *cs_base, uint32_t *flags)
@@ -448,6 +460,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env, vaddr *pc,
 *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;
 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
+*flags |= is_va32(env) * HW_FLAGS_VA32;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 7f60090580..b6fa5df82d 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -33,6 +33,8 @@ typedef struct DisasContext {
 uint16_t plv;
 int vl;   /* Vector length */
 TCGv zero;
+bool la64; /* LoongArch64 mode */
+bool va32; /* 32-bit virtual address */
 } DisasContext;
 
 void generate_exception(DisasContext *ctx, int excp);
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 3146a2d4ac..ac847745df 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -119,6 +119,9 @@ static void 
loongarch_tr_init_disas_context(DisasContextBase *dcbase,
 ctx->vl = LSX_LEN;
 }
 
+ctx->la64 = is_la64(env);
+ctx->va32 = (ctx->base.tb->flags & HW_FLAGS_VA32) != 0;
+
 ctx->zero = tcg_constant_tl(0);
 }
 
-- 
2.41.0




[PATCH v5 05/19] target/loongarch: Extract make_address_x() helper

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

Signed-off-by: Jiajie Chen 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Reviewed-by: Philippe Mathieu-Daudé 
Message-ID: <20230822032724.1353391-6-gaos...@loongson.cn>
[PMD: Extract helper from bigger patch]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/loongarch/translate.c   | 12 
 .../loongarch/insn_trans/trans_fmemory.c.inc   | 18 ++
 target/loongarch/insn_trans/trans_lsx.c.inc|  6 ++
 target/loongarch/insn_trans/trans_memory.c.inc |  6 ++
 4 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index ac847745df..a68a979a55 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -208,6 +208,18 @@ static void set_fpr(int reg_num, TCGv val)
offsetof(CPULoongArchState, fpr[reg_num].vreg.D(0)));
 }
 
+static TCGv make_address_x(DisasContext *ctx, TCGv base, TCGv addend)
+{
+TCGv temp = NULL;
+
+if (addend) {
+temp = tcg_temp_new();
+tcg_gen_add_tl(temp, base, addend);
+base = temp;
+}
+return base;
+}
+
 #include "decode-insns.c.inc"
 #include "insn_trans/trans_arith.c.inc"
 #include "insn_trans/trans_shift.c.inc"
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 91c09fb6d9..88ad209338 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -57,8 +57,7 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -75,8 +74,7 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
 return true;
@@ -91,9 +89,8 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp 
mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtgt_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -110,9 +107,8 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtgt_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_st_tl(src3, addr, ctx->mem_idx, mop);
 
 return true;
@@ -127,9 +123,8 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtle_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
 maybe_nanbox_load(dest, mop);
 set_fpr(a->fd, dest);
@@ -146,9 +141,8 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, 
MemOp mop)
 
 CHECK_FPE;
 
-addr = tcg_temp_new();
 gen_helper_asrtle_d(cpu_env, src1, src2);
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 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..875cb7d51d 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4315,14 +4315,13 @@ static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
 
 CHECK_SXE;
 
-addr = tcg_temp_new();
 src1 = gpr_src(ctx, a->rj, EXT_NONE);
 src2 = gpr_src(ctx, a->rk, EXT_NONE);
 val = tcg_temp_new_i128();
 rl = tcg_temp_new_i64();
 rh = tcg_temp_new_i64();
 
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 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);
@@ -4339,14 +4338,13 @@ static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
 
 CHECK_SXE;
 
-addr = tcg_temp_new();
 src1 = gpr_src(ctx, a->rj, EXT_NONE);
 src2 = gpr_src(ctx, a->rk, EXT_NONE);
 val = tcg_temp_new_i128();
 ah = tcg_temp_new_i64();
 al = tcg_temp_new_i64();
 
-tcg_gen_add_tl(addr, src1, src2);
+addr = make_address_x(ctx, src1, src2);
 get_vreg64(ah, a->vd, 1);
 get_vreg64(al, a->vd, 0);
 tcg_gen_concat_i64_i128(val, al, ah);
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/ins

[PATCH v5 01/19] target/loongarch: Support LoongArch32 TLB entry

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

The TLB entry of LA32 lacks NR, NX and RPLV and they are hardwired to
zero in LoongArch32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-2-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  9 +
 target/loongarch/tlb_helper.c | 17 -
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index f8f24032cb..48ed2e0632 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -66,10 +66,11 @@ FIELD(TLBENTRY, D, 1, 1)
 FIELD(TLBENTRY, PLV, 2, 2)
 FIELD(TLBENTRY, MAT, 4, 2)
 FIELD(TLBENTRY, G, 6, 1)
-FIELD(TLBENTRY, PPN, 12, 36)
-FIELD(TLBENTRY, NR, 61, 1)
-FIELD(TLBENTRY, NX, 62, 1)
-FIELD(TLBENTRY, RPLV, 63, 1)
+FIELD(TLBENTRY_32, PPN, 8, 24)
+FIELD(TLBENTRY_64, PPN, 12, 36)
+FIELD(TLBENTRY_64, NR, 61, 1)
+FIELD(TLBENTRY_64, NX, 62, 1)
+FIELD(TLBENTRY_64, RPLV, 63, 1)
 
 #define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
 FIELD(CSR_ASID, ASID, 0, 10)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 6e00190547..cef10e2257 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -48,10 +48,17 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
 tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
 tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
 tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
-tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY, PPN);
-tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY, NX);
-tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY, NR);
-tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY, RPLV);
+if (is_la64(env)) {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
+tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
+tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
+tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
+} else {
+tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
+tlb_nx = 0;
+tlb_nr = 0;
+tlb_rplv = 0;
+}
 
 /* Check access rights */
 if (!tlb_v) {
@@ -79,7 +86,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, 
hwaddr *physical,
  * tlb_entry contains ppn[47:12] while 16KiB ppn is [47:15]
  * need adjust.
  */
-*physical = (tlb_ppn << R_TLBENTRY_PPN_SHIFT) |
+*physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
 (address & MAKE_64BIT_MASK(0, tlb_ps));
 *prot = PAGE_READ;
 if (tlb_d) {
-- 
2.41.0




[PATCH v5 03/19] target/loongarch: Support LoongArch32 VPPN

2023-08-22 Thread Philippe Mathieu-Daudé
From: Jiajie Chen 

VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-ID: <20230822032724.1353391-4-gaos...@loongson.cn>
---
 target/loongarch/cpu-csr.h|  6 --
 target/loongarch/tlb_helper.c | 23 ++-
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index b93f99a9ef..c59d7a9fcb 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
 FIELD(CSR_TLBIDX, NE, 31, 1)
 
 #define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */
-FIELD(CSR_TLBEHI, VPPN, 13, 35)
+FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBEHI_64, VPPN, 13, 35)
 
 #define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
 #define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
@@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
 #define LOONGARCH_CSR_TLBRELO1   0x8d /* TLB refill entrylo1 */
 #define LOONGARCH_CSR_TLBREHI0x8e /* TLB refill entryhi */
 FIELD(CSR_TLBREHI, PS, 0, 6)
-FIELD(CSR_TLBREHI, VPPN, 13, 35)
+FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
+FIELD(CSR_TLBREHI_64, VPPN, 13, 35)
 #define LOONGARCH_CSR_TLBRPRMD   0x8f /* TLB refill mode info */
 FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
 FIELD(CSR_TLBRPRMD, PIE, 2, 1)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index 1f8e7911c7..c8b8b0497f 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -300,8 +300,13 @@ static void raise_mmu_exception(CPULoongArchState *env, 
target_ulong address,
 
 if (tlb_error == TLBRET_NOMATCH) {
 env->CSR_TLBRBADV = address;
-env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
-  extract64(address, 13, 35));
+if (is_la64(env)) {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
+VPPN, extract64(address, 13, 35));
+} else {
+env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
+VPPN, extract64(address, 13, 19));
+}
 } else {
 if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
 env->CSR_BADV = address;
@@ -366,12 +371,20 @@ static void fill_tlb_entry(CPULoongArchState *env, int 
index)
 
 if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
 csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
+}
 lo0 = env->CSR_TLBRELO0;
 lo1 = env->CSR_TLBRELO1;
 } else {
 csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
-csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
+if (is_la64(env)) {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
+} else {
+csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
+}
 lo0 = env->CSR_TLBELO0;
 lo1 = env->CSR_TLBELO1;
 }
@@ -491,7 +504,7 @@ void helper_tlbfill(CPULoongArchState *env)
 
 if (pagesize == stlb_ps) {
 /* Only write into STLB bits [47:13] */
-address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
 
 /* Choose one set ramdomly */
 set = get_random_tlb(0, 7);
-- 
2.41.0




[PATCH v5 00/19] Based-on: https://patchew.org/QEMU/20230821125959.28666-1-phi...@linaro.org/

2023-08-22 Thread Philippe Mathieu-Daudé
(all series reviewed, for Song Gao to pick whichever v4/v5 is preferred)

Hi,

This series adds some checks before translating instructions

This includes:

CPUCFG[1].IOCSR

CPUCFG[2].FP
CPUCFG[2].FP_SP
CPUCFG[2].FP_DP
CPUCFG[2].LSPW
CPUCFG[2].LAM
CPUCFG[2].LSX

V5:
- Split 2 patches, extracting helpers
- R-b

V4:
- Rebase;
- Split patch 'Add LoongArch32 cpu la132' in two patch; (PMD)
- Remove unrelated cpucfgX;(PMD)
- R-b.

V3:
- Rebase;
- The la32 instructions following Table 2 at [2].

V2:
- Add a check parameter to the TRANS macro.
- remove TRANS_64.
- Add avail_ALL/64/FP/FP_SP/FP_DP/LSPW/LAM/LSX/IOCSR
  to check instructions.

[1]: https://patchew.org/QEMU/20230809083258.1787464-...@jia.je/
[2]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#overview-of-basic-integer-instructions

Jiajie Chen (11):
  target/loongarch: Support LoongArch32 TLB entry
  target/loongarch: Support LoongArch32 DMW
  target/loongarch: Support LoongArch32 VPPN
  target/loongarch: Add LA64 & VA32 to DisasContext
  target/loongarch: Extract make_address_x() helper
  target/loongarch: Extract make_address_i() helper
  target/loongarch: Extract make_address_pc() helper
  target/loongarch: Extract set_pc() helper
  target/loongarch: Truncate high 32 bits of address in VA32 mode
  target/loongarch: Sign extend results in VA32 mode
  target/loongarch: Add LoongArch32 cpu la132

Song Gao (8):
  target/loongarch: Add a check parameter to the TRANS macro
  target/loongarch: Add avail_64 to check la64-only instructions
  hw/loongarch: Remove restriction of la464 cores in the virt machine
  target/loongarch: Add avail_FP/FP_SP/FP_DP to check fpu instructions
  target/loongarch: Add avail_LSPW to check LSPW instructions
  target/loongarch: Add avail_LAM to check atomic instructions
  target/loongarch: Add avail_LSX to check LSX instructions
  target/loongarch: Add avail_IOCSR to check iocsr instructions

 target/loongarch/cpu-csr.h|   22 +-
 target/loongarch/cpu.h|   22 +
 target/loongarch/translate.h  |   19 +-
 hw/loongarch/virt.c   |5 -
 target/loongarch/cpu.c|   46 +-
 target/loongarch/gdbstub.c|2 +-
 target/loongarch/op_helper.c  |4 +-
 target/loongarch/tlb_helper.c |   66 +-
 target/loongarch/translate.c  |   46 +
 target/loongarch/insn_trans/trans_arith.c.inc |   98 +-
 .../loongarch/insn_trans/trans_atomic.c.inc   |   85 +-
 target/loongarch/insn_trans/trans_bit.c.inc   |   56 +-
 .../loongarch/insn_trans/trans_branch.c.inc   |   27 +-
 target/loongarch/insn_trans/trans_extra.c.inc |   24 +-
 .../loongarch/insn_trans/trans_farith.c.inc   |   96 +-
 target/loongarch/insn_trans/trans_fcmp.c.inc  |8 +
 target/loongarch/insn_trans/trans_fcnv.c.inc  |   56 +-
 .../loongarch/insn_trans/trans_fmemory.c.inc  |   62 +-
 target/loongarch/insn_trans/trans_fmov.c.inc  |   52 +-
 target/loongarch/insn_trans/trans_lsx.c.inc   | 1434 +
 .../loongarch/insn_trans/trans_memory.c.inc   |  118 +-
 .../insn_trans/trans_privileged.c.inc |   24 +-
 target/loongarch/insn_trans/trans_shift.c.inc |   34 +-
 23 files changed, 1386 insertions(+), 1020 deletions(-)

-- 
2.41.0




Re: [PATCH v4 06/15] target/loongarch: Sign extend results in VA32 mode

2023-08-22 Thread Philippe Mathieu-Daudé

On 22/8/23 05:27, Song Gao wrote:

From: Jiajie Chen 

In VA32 mode, BL, JIRL and PC* instructions should sign-extend the low
32 bit result to 64 bits.

Signed-off-by: Jiajie Chen 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
---
  target/loongarch/translate.c   | 8 
  target/loongarch/insn_trans/trans_arith.c.inc  | 2 +-
  target/loongarch/insn_trans/trans_branch.c.inc | 4 ++--
  3 files changed, 11 insertions(+), 3 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 




Re: [PATCH v4 05/15] target/loongarch: Truncate high 32 bits of address in VA32 mode

2023-08-22 Thread Philippe Mathieu-Daudé

On 22/8/23 05:27, Song Gao wrote:

From: Jiajie Chen 

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 
Co-authored-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
---
  target/loongarch/cpu.h|  9 +
  target/loongarch/cpu.c| 16 
  target/loongarch/gdbstub.c|  2 +-
  target/loongarch/op_helper.c  |  4 +-
  target/loongarch/translate.c  | 32 
  .../loongarch/insn_trans/trans_atomic.c.inc   |  5 ++-
  .../loongarch/insn_trans/trans_branch.c.inc   |  3 +-
  .../loongarch/insn_trans/trans_fmemory.c.inc  | 30 ---
  target/loongarch/insn_trans/trans_lsx.c.inc   | 38 +--
  .../loongarch/insn_trans/trans_memory.c.inc   | 34 +
  10 files changed, 85 insertions(+), 88 deletions(-)


(I had to split this patch to ease my review)

Reviewed-by: Philippe Mathieu-Daudé 




<    1   2   3   4