qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] target/loongarch: Fix emulation of float-point disable exception
@ 2022-11-04  4:05 Rui Wang
  2022-11-04  4:05 ` [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields Rui Wang
  2022-11-04  4:05 ` [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
  0 siblings, 2 replies; 5+ messages in thread
From: Rui Wang @ 2022-11-04  4:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Song Gao, Xiaojuan Yang, qemu-devel, hev, Rui Wang

v3:
  target/loongarch: Adjust the layout of hardware flags bit fields
  target/loongarch: Fix emulation of float-point disable exception

 target/loongarch/cpu.c                        |  2 ++
 target/loongarch/cpu.h                        | 11 +++++-
 .../loongarch/insn_trans/trans_farith.c.inc   | 30 ++++++++++++++++
 target/loongarch/insn_trans/trans_fcmp.c.inc  | 11 ++++--
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 34 +++++++++++++++----
 target/loongarch/insn_trans/trans_fmov.c.inc  | 29 ++++++++++++++--
 .../insn_trans/trans_privileged.c.inc         |  2 +-
 target/loongarch/translate.c                  |  6 +++-
 8 files changed, 111 insertions(+), 14 deletions(-)

-- 
2.38.1



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields
  2022-11-04  4:05 [PATCH v3 0/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
@ 2022-11-04  4:05 ` Rui Wang
  2022-11-04 22:08   ` Richard Henderson
  2022-11-04  4:05 ` [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
  1 sibling, 1 reply; 5+ messages in thread
From: Rui Wang @ 2022-11-04  4:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Song Gao, Xiaojuan Yang, qemu-devel, hev, Rui Wang

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Rui Wang <wangrui@loongson.cn>
---
 target/loongarch/cpu.h                             | 9 ++++++++-
 target/loongarch/insn_trans/trans_privileged.c.inc | 2 +-
 target/loongarch/translate.c                       | 6 +++++-
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index dbce176564..f482ad94fe 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -14,6 +14,7 @@
 #include "qemu/timer.h"
 #include "exec/memory.h"
 #include "hw/sysbus.h"
+#include "cpu-csr.h"
 
 #define IOCSRF_TEMP             0
 #define IOCSRF_NODECNT          1
@@ -391,6 +392,12 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
 #endif
 }
 
+/*
+ * LoongArch CPUs hardware flags.
+ */
+#define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
+#define HW_FLAGS_CRMD_PG    R_CSR_CRMD_PG_MASK   /* 0x10 */
+
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
                                         target_ulong *pc,
                                         target_ulong *cs_base,
@@ -398,7 +405,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
 {
     *pc = env->pc;
     *cs_base = 0;
-    *flags = cpu_mmu_index(env, false);
+    *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc b/target/loongarch/insn_trans/trans_privileged.c.inc
index 9c4dcbfcfb..ff3a6d95ae 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -159,7 +159,7 @@ static const CSRInfo csr_info[] = {
 
 static bool check_plv(DisasContext *ctx)
 {
-    if (ctx->base.tb->flags == MMU_USER_IDX) {
+    if (ctx->mem_idx == MMU_USER_IDX) {
         generate_exception(ctx, EXCCODE_IPE);
         return true;
     }
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 6091772349..31462b2b61 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -75,7 +75,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
     DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
-    ctx->mem_idx = ctx->base.tb->flags;
+    if (ctx->base.tb->flags & HW_FLAGS_CRMD_PG) {
+        ctx->mem_idx = ctx->base.tb->flags & HW_FLAGS_PLV_MASK;
+    } else {
+        ctx->mem_idx = MMU_DA_IDX;
+    }
 
     /* Bound the number of insns to execute to those left on the page.  */
     bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
-- 
2.38.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception
  2022-11-04  4:05 [PATCH v3 0/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
  2022-11-04  4:05 ` [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields Rui Wang
@ 2022-11-04  4:05 ` Rui Wang
  2022-11-04 22:15   ` Richard Henderson
  1 sibling, 1 reply; 5+ messages in thread
From: Rui Wang @ 2022-11-04  4:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Song Gao, Xiaojuan Yang, qemu-devel, hev, Rui Wang

We need to emulate it to generate a floating point disable exception
when CSR.EUEN.FPE is zero.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Rui Wang <wangrui@loongson.cn>
---
 target/loongarch/cpu.c                        |  2 ++
 target/loongarch/cpu.h                        |  2 ++
 .../loongarch/insn_trans/trans_farith.c.inc   | 30 ++++++++++++++++
 target/loongarch/insn_trans/trans_fcmp.c.inc  | 11 ++++--
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 34 +++++++++++++++----
 target/loongarch/insn_trans/trans_fmov.c.inc  | 29 ++++++++++++++--
 6 files changed, 97 insertions(+), 11 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 1512664214..46b04cbdad 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -48,6 +48,7 @@ static const char * const excp_names[] = {
     [EXCCODE_BRK] = "Break",
     [EXCCODE_INE] = "Instruction Non-Existent",
     [EXCCODE_IPE] = "Instruction privilege error",
+    [EXCCODE_FPD] = "Floating Point Disabled",
     [EXCCODE_FPE] = "Floating Point Exception",
     [EXCCODE_DBP] = "Debug breakpoint",
     [EXCCODE_BCE] = "Bound Check Exception",
@@ -185,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
     case EXCCODE_BRK:
     case EXCCODE_INE:
     case EXCCODE_IPE:
+    case EXCCODE_FPD:
     case EXCCODE_FPE:
     case EXCCODE_BCE:
         env->CSR_BADV = env->pc;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index f482ad94fe..08c1f6baa1 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -397,6 +397,7 @@ static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
  */
 #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
 #define HW_FLAGS_CRMD_PG    R_CSR_CRMD_PG_MASK   /* 0x10 */
+#define HW_FLAGS_EUEN_FPE   0x04
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
                                         target_ulong *pc,
@@ -406,6 +407,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
     *pc = env->pc;
     *cs_base = 0;
     *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
+    *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/insn_trans/trans_farith.c.inc
index 7bb3f41aee..e2dec75dfb 100644
--- a/target/loongarch/insn_trans/trans_farith.c.inc
+++ b/target/loongarch/insn_trans/trans_farith.c.inc
@@ -3,9 +3,22 @@
  * Copyright (c) 2021 Loongson Technology Corporation Limited
  */
 
+#ifndef CONFIG_USER_ONLY
+#define CHECK_FPE do { \
+    if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \
+        generate_exception(ctx, EXCCODE_FPD); \
+        return false; \
+    } \
+} while (0)
+#else
+#define CHECK_FPE
+#endif
+
 static bool gen_fff(DisasContext *ctx, arg_fff *a,
                     void (*func)(TCGv, TCGv_env, TCGv, TCGv))
 {
+    CHECK_FPE;
+
     func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]);
     return true;
 }
@@ -13,6 +26,8 @@ static bool gen_fff(DisasContext *ctx, arg_fff *a,
 static bool gen_ff(DisasContext *ctx, arg_ff *a,
                    void (*func)(TCGv, TCGv_env, TCGv))
 {
+    CHECK_FPE;
+
     func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]);
     return true;
 }
@@ -22,6 +37,9 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a,
                        int flag)
 {
     TCGv_i32 tflag = tcg_constant_i32(flag);
+
+    CHECK_FPE;
+
     func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj],
          cpu_fpr[a->fk], cpu_fpr[a->fa], tflag);
     return true;
@@ -29,18 +47,24 @@ static bool gen_muladd(DisasContext *ctx, arg_ffff *a,
 
 static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
 {
+    CHECK_FPE;
+
     tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31);
     return true;
 }
 
 static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
 {
+    CHECK_FPE;
+
     tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63);
     return true;
 }
 
 static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 {
+    CHECK_FPE;
+
     tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31));
     gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
     return true;
@@ -48,12 +72,16 @@ static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 
 static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
 {
+    CHECK_FPE;
+
     tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63));
     return true;
 }
 
 static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 {
+    CHECK_FPE;
+
     tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000);
     gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
     return true;
@@ -61,6 +89,8 @@ static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 
 static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
 {
+    CHECK_FPE;
+
     tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL);
     return true;
 }
diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc b/target/loongarch/insn_trans/trans_fcmp.c.inc
index 93a6a2230f..2ccf646ccb 100644
--- a/target/loongarch/insn_trans/trans_fcmp.c.inc
+++ b/target/loongarch/insn_trans/trans_fcmp.c.inc
@@ -25,10 +25,13 @@ static uint32_t get_fcmp_flags(int cond)
 
 static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
 {
-    TCGv var = tcg_temp_new();
+    TCGv var;
     uint32_t flags;
     void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
 
+    CHECK_FPE;
+
+    var = tcg_temp_new();
     fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
     flags = get_fcmp_flags(a->fcond >> 1);
 
@@ -41,9 +44,13 @@ static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
 
 static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
 {
-    TCGv var = tcg_temp_new();
+    TCGv var;
     uint32_t flags;
     void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
+
+    CHECK_FPE;
+
+    var = tcg_temp_new();
     fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
     flags = get_fcmp_flags(a->fcond >> 1);
 
diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc b/target/loongarch/insn_trans/trans_fmemory.c.inc
index 74ee98f63a..3025a1d3e9 100644
--- a/target/loongarch/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -15,6 +15,8 @@ static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
     TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv temp = NULL;
 
+    CHECK_FPE;
+
     if (a->imm) {
         temp = tcg_temp_new();
         tcg_gen_addi_tl(temp, addr, a->imm);
@@ -36,6 +38,8 @@ static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
     TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv temp = NULL;
 
+    CHECK_FPE;
+
     if (a->imm) {
         temp = tcg_temp_new();
         tcg_gen_addi_tl(temp, addr, a->imm);
@@ -54,8 +58,11 @@ static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
 
+    CHECK_FPE;
+
+    addr = tcg_temp_new();
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
     maybe_nanbox_load(cpu_fpr[a->fd], mop);
@@ -68,8 +75,11 @@ static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
+
+    CHECK_FPE;
 
+    addr = tcg_temp_new();
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
     tcg_temp_free(addr);
@@ -81,8 +91,11 @@ static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
 
+    CHECK_FPE;
+
+    addr = tcg_temp_new();
     gen_helper_asrtgt_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
@@ -96,8 +109,11 @@ static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
+
+    CHECK_FPE;
 
+    addr = tcg_temp_new();
     gen_helper_asrtgt_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
@@ -110,8 +126,11 @@ static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
 
+    CHECK_FPE;
+
+    addr = tcg_temp_new();
     gen_helper_asrtle_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
@@ -125,8 +144,11 @@ static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop)
 {
     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
-    TCGv addr = tcg_temp_new();
+    TCGv addr;
+
+    CHECK_FPE;
 
+    addr = tcg_temp_new();
     gen_helper_asrtle_d(cpu_env, src1, src2);
     tcg_gen_add_tl(addr, src1, src2);
     tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/insn_trans/trans_fmov.c.inc
index 5537e3dd35..8e5106db4e 100644
--- a/target/loongarch/insn_trans/trans_fmov.c.inc
+++ b/target/loongarch/insn_trans/trans_fmov.c.inc
@@ -10,8 +10,11 @@ static const uint32_t fcsr_mask[4] = {
 static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
 {
     TCGv zero = tcg_constant_tl(0);
-    TCGv cond = tcg_temp_new();
+    TCGv cond;
 
+    CHECK_FPE;
+
+    cond = tcg_temp_new();
     tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca]));
     tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero,
                        cpu_fpr[a->fj], cpu_fpr[a->fk]);
@@ -26,6 +29,8 @@ static bool gen_f2f(DisasContext *ctx, arg_ff *a,
     TCGv dest = cpu_fpr[a->fd];
     TCGv src = cpu_fpr[a->fj];
 
+    CHECK_FPE;
+
     func(dest, src);
     if (nanbox) {
         gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
@@ -39,6 +44,8 @@ static bool gen_r2f(DisasContext *ctx, arg_fr *a,
 {
     TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
 
+    CHECK_FPE;
+
     func(cpu_fpr[a->fd], src);
     return true;
 }
@@ -48,6 +55,8 @@ static bool gen_f2r(DisasContext *ctx, arg_rf *a,
 {
     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 
+    CHECK_FPE;
+
     func(dest, cpu_fpr[a->fj]);
     gen_set_gpr(a->rd, dest, EXT_NONE);
 
@@ -59,6 +68,8 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a)
     uint32_t mask = fcsr_mask[a->fcsrd];
     TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
 
+    CHECK_FPE;
+
     if (mask == UINT32_MAX) {
         tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0));
     } else {
@@ -90,6 +101,8 @@ static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a)
 {
     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
 
+    CHECK_FPE;
+
     tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0));
     tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]);
     gen_set_gpr(a->rd, dest, EXT_NONE);
@@ -114,8 +127,11 @@ static void gen_movfrh2gr_s(TCGv dest, TCGv src)
 
 static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
 {
-    TCGv t0 = tcg_temp_new();
+    TCGv t0;
+
+    CHECK_FPE;
 
+    t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1);
     tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
     tcg_temp_free(t0);
@@ -125,6 +141,8 @@ static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
 
 static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
 {
+    CHECK_FPE;
+
     tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env,
                     offsetof(CPULoongArchState, cf[a->cj & 0x7]));
     return true;
@@ -132,8 +150,11 @@ static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a)
 
 static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
 {
-    TCGv t0 = tcg_temp_new();
+    TCGv t0;
 
+    CHECK_FPE;
+
+    t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1);
     tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
     tcg_temp_free(t0);
@@ -143,6 +164,8 @@ static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a)
 
 static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a)
 {
+    CHECK_FPE;
+
     tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env,
                     offsetof(CPULoongArchState, cf[a->cj & 0x7]));
     return true;
-- 
2.38.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields
  2022-11-04  4:05 ` [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields Rui Wang
@ 2022-11-04 22:08   ` Richard Henderson
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2022-11-04 22:08 UTC (permalink / raw)
  To: Rui Wang; +Cc: Song Gao, Xiaojuan Yang, qemu-devel, hev

On 11/4/22 15:05, Rui Wang wrote:
>   static bool check_plv(DisasContext *ctx)
>   {
> -    if (ctx->base.tb->flags == MMU_USER_IDX) {
> +    if (ctx->mem_idx == MMU_USER_IDX) {

Not quite.  This needs to check HW_FLAGS_PLV_MASK, not the mem_idx.  That was the intent 
of keeping them separate in HW_FLAGS.


r~


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception
  2022-11-04  4:05 ` [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
@ 2022-11-04 22:15   ` Richard Henderson
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2022-11-04 22:15 UTC (permalink / raw)
  To: Rui Wang; +Cc: Song Gao, Xiaojuan Yang, qemu-devel, hev

On 11/4/22 15:05, Rui Wang wrote:
> +#ifndef CONFIG_USER_ONLY
> +#define CHECK_FPE do { \
> +    if ((ctx->base.tb->flags & HW_FLAGS_EUEN_FPE) == 0) { \
> +        generate_exception(ctx, EXCCODE_FPD); \
> +        return false; \
> +    } \
> +} while (0)
> +#else
> +#define CHECK_FPE
> +#endif
> +
>   static bool gen_fff(DisasContext *ctx, arg_fff *a,
>                       void (*func)(TCGv, TCGv_env, TCGv, TCGv))
>   {
> +    CHECK_FPE;

Oh, sorry, I just realized this is not quite correct: CHECK_FPE should return true, not false.

Returning false indicates that the instruction has not been matched, and the decoder 
should continue searching.  If we reach the end of the search space, we raise EXCCODE_INE. 
But here we have successfully matched the instruction, and have found that the register 
bank is disabled and should raise EXCCODE_FPD.

The difference will in practice not be visible, because the code that will be emitted to 
raise EXCCODE_INE will not be reached, because control flow will have already raised 
EXCCODE_FPD, but it would be better to not emit the dead code.


r~


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-11-04 22:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-04  4:05 [PATCH v3 0/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
2022-11-04  4:05 ` [PATCH v3 1/2] target/loongarch: Adjust the layout of hardware flags bit fields Rui Wang
2022-11-04 22:08   ` Richard Henderson
2022-11-04  4:05 ` [PATCH v3 2/2] target/loongarch: Fix emulation of float-point disable exception Rui Wang
2022-11-04 22:15   ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).