qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 2/6] target/loongarch: Add some checks before translating


From: gaosong
Subject: Re: [PATCH v1 2/6] target/loongarch: Add some checks before translating fpu instructions
Date: Fri, 11 Aug 2023 11:43:42 +0800
User-agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0

在 2023/8/10 下午11:03, Richard Henderson 写道:
On 8/10/23 05:41, Song Gao wrote:
This patch adds REQUIRE_FP/FP_SP/FP_DP to check CPUCFG2.FP/FP_SP/FP_DP.

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
  target/loongarch/cpu.h                        |   6 +
  .../loongarch/insn_trans/trans_farith.c.inc   | 132 ++++++++++++------
  target/loongarch/insn_trans/trans_fcmp.c.inc  |   4 +
  target/loongarch/insn_trans/trans_fcnv.c.inc  |  56 ++++----
  .../loongarch/insn_trans/trans_fmemory.c.inc  | 104 ++++++++++----
  target/loongarch/insn_trans/trans_fmov.c.inc  |  47 +++++--
  6 files changed, 247 insertions(+), 102 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 9f550793ca..5594d83011 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -459,6 +459,9 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
  #define HW_FLAGS_EUEN_FPE   0x04
  #define HW_FLAGS_EUEN_SXE   0x08
  #define HW_FLAGS_VA32       0x20
+#define HW_FLAGS_FP         0x40
+#define HW_FLAGS_FP_SP      0x80
+#define HW_FLAGS_FP_DP      0x100
  static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,                                           uint64_t *cs_base, uint32_t *flags) @@ -469,6 +472,9 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,       *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;
+    *flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, FP) * HW_FLAGS_FP;
+    *flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, FP_SP) * HW_FLAGS_FP_SP; +    *flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, FP_DP) * HW_FLAGS_FP_DP;

You do not need to put any of these in HW_FLAGS, because CPUCFG space never changes for the lifetime of the cpu.

You can extract these into DisasContext in loongarch_tr_init_disas_context.

+#define REQUIRE_FP do { \
+    if ((ctx->base.tb->flags & HW_FLAGS_FP) == 0) { \
+        return false; \
+    } \
+} while (0)
+
+#define REQUIRE_FP_SP do { \
+    if ((ctx->base.tb->flags & HW_FLAGS_FP_SP) == 0) { \
+        return false; \
+    } \
+} while (0)
+
+#define REQUIRE_FP_DP do { \
+    if ((ctx->base.tb->flags & HW_FLAGS_FP_DP) == 0) { \
+        return false; \
+    } \
+} while (0)

It would be much better to not create so many of these REQUIRE macros.

+TRANS(fadd_s, gen_fff, 0, gen_helper_fadd_s)
+TRANS(fadd_d, gen_fff, 1, gen_helper_fadd_d)

0 vs 1 is very opaque.

Better is something like Jiajie Chen's TRANS_64,

+/* for LoongArch64-only instructions */
+#define TRANS_64(NAME, FUNC, ...) \
+    static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
+    { \
+        return ctx->la64 && FUNC(ctx, a, __VA_ARGS__); \
+    }

But as we now know, we would need at least 7 of these.

Even better would be to generalize this so that every instruction records the condition under which it is valid.

Perhaps

typedef struct DisasContext {
     ...
     uint32_t cpucfg1;
     uint32_t cpucfg2;
};

static void loongarch_tr_init_disas_context(...)
{
     ...
     ctx->cpucfg1 = env->cpucfg[1];
     ctx->cpucfg2 = env->cpucfg[2];
}

#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)
etc


#define TRANS(NAME, AVAIL, FUNC, ...) \
     static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a)  \
     { return avail_##AVAIL(ctx) && FUNC(ctx, a, __VA_ARGS__); }

so that the above becomes

TRANS(fadd_s, FP_SP, gen_fff, gen_helper_fadd_s)
TRANS(fadd_d, FP_DP, gen_fff, gen_helper_fadd_d)

and even simple instructions get

TRANS(add_w, ALL, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)
TRANS(add_d,  64, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl)

Thanks for your suggestions, I will send v2 as soon as possblie.

Thanks.
Song Gao




reply via email to

[Prev in Thread] Current Thread [Next in Thread]