+/*
+ * LoongArch CPUs hardware flags.
+ * bit[2..0] for MMU index.
+ * bit[7..4] for CSR.EUEN.{ BTE, ASXE, SXE, FPE }.
+ */
+#define HW_FLAGS_MMU_MASK 0x07
+#define HW_FLAGS_EUEN_FPE 0x10
+
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
target_ulong *pc,
target_ulong *cs_base,
@@ -399,6 +408,10 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState
*env,
*pc = env->pc;
*cs_base = 0;
*flags = cpu_mmu_index(env, false);
+
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE)) {
+ *flags |= 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
--- 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) {