Building riscv64-softmmu with --disable-tcg currently fails because
RISC-V still builds or references TCG-only sources and helpers in the
no-TCG configuration.

Move TCG-only helper and translator sources under CONFIG_TCG, guard the
remaining TCG-only code in common files, and move common CSR helpers out
of TCG-only helper files.

misa writes still rely on the TCG extension validation path. Since
x-misa-w is a TCG-only experimental property, reject it during CPU
realize when TCG is not available.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3483

Signed-off-by: Zephyr Li <[email protected]>
---
Testing:
- riscv64-softmmu --enable-kvm --disable-tcg --enable-debug builds
  successfully.
- riscv64-softmmu --enable-debug builds successfully.
- qemu-system-riscv64 -M virt,accel=qtest -cpu rv64,x-misa-w=true \
      -S -nographic reports "x-misa-w requires TCG".

 target/riscv/cpu.c        |  9 +++++++
 target/riscv/cpu_helper.c | 53 +++++++++++++++++++++++++++++++++++++++
 target/riscv/csr.c        | 18 +++++++++++--
 target/riscv/fpu_helper.c | 27 --------------------
 target/riscv/meson.build  |  9 ++++---
 target/riscv/op_helper.c  | 15 -----------
 6 files changed, 84 insertions(+), 47 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 862834b480..3f4563fce2 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -36,7 +36,9 @@
 #include "system/tcg.h"
 #include "kvm/kvm_riscv.h"
 #include "tcg/tcg-cpu.h"
+#ifdef CONFIG_TCG
 #include "tcg/tcg.h"
+#endif
 
 /* RISC-V CPU definitions */
 static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -956,6 +958,13 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
     Error *local_err = NULL;
 
+#ifndef CONFIG_TCG
+    if (cpu->cfg.misa_w) {
+        error_setg(errp, "x-misa-w requires TCG");
+        return;
+    }
+#endif
+
     cpu_exec_realizefn(cs, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 17305e1bb7..e53a5d567d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,6 +21,7 @@
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "cpu.h"
+#include "fpu/softfloat.h"
 #include "internals.h"
 #include "pmu.h"
 #include "exec/cputlb.h"
@@ -28,8 +29,10 @@
 #include "exec/target_page.h"
 #include "system/memory.h"
 #include "instmap.h"
+#ifdef CONFIG_TCG
 #include "tcg/tcg-op.h"
 #include "accel/tcg/cpu-ops.h"
+#endif
 #include "trace.h"
 #include "semihosting/common-semi.h"
 #include "exec/icount.h"
@@ -38,6 +41,52 @@
 #include "pmp.h"
 #include "qemu/plugin.h"
 
+/* Exceptions processing helpers */
+G_NORETURN void riscv_raise_exception(CPURISCVState *env,
+                                      RISCVException exception,
+                                      uintptr_t pc)
+{
+    CPUState *cs = env_cpu(env);
+
+    trace_riscv_exception(exception,
+                          riscv_cpu_get_trap_name(exception, false),
+                          env->pc);
+
+    cs->exception_index = exception;
+#ifdef CONFIG_TCG
+    cpu_loop_exit_restore(cs, pc);
+#else
+    qemu_build_not_reached();
+#endif
+}
+
+target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
+{
+    int soft = get_float_exception_flags(&env->fp_status);
+    target_ulong hard = 0;
+
+    hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
+    hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
+    hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
+    hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
+    hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
+
+    return hard;
+}
+
+void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
+{
+    int soft = 0;
+
+    soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
+    soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
+    soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
+    soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
+    soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
+
+    set_float_exception_flags(soft, &env->fp_status);
+}
+
 int riscv_env_mmu_index(CPURISCVState *env, bool ifetch)
 {
 #ifdef CONFIG_USER_ONLY
@@ -1667,6 +1716,7 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
     return TRANSLATE_SUCCESS;
 }
 
+#ifdef CONFIG_TCG
 static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
                                 MMUAccessType access_type, bool pmp_violation,
                                 bool first_stage, bool two_stage,
@@ -1709,6 +1759,7 @@ static void raise_mmu_exception(CPURISCVState *env, 
target_ulong address,
     env->two_stage_lookup = two_stage;
     env->two_stage_indirect_lookup = two_stage_indirect;
 }
+#endif
 
 hwaddr riscv_cpu_get_phys_addr_debug(CPUState *cs, vaddr addr)
 {
@@ -1733,6 +1784,7 @@ hwaddr riscv_cpu_get_phys_addr_debug(CPUState *cs, vaddr 
addr)
     return phys_addr;
 }
 
+#ifdef CONFIG_TCG
 void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
                                      vaddr addr, unsigned size,
                                      MMUAccessType access_type,
@@ -1957,6 +2009,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 
     return true;
 }
+#endif
 
 static target_ulong riscv_transformed_insn(CPURISCVState *env,
                                            target_ulong insn,
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5514e0f455..04fa320ff8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2135,21 +2135,31 @@ static RISCVException read_misa(CPURISCVState *env, int 
csrno,
 
 static target_ulong get_next_pc(CPURISCVState *env, uintptr_t ra)
 {
+    /* Outside of a running cpu, env contains the next pc. */
+    if (ra == 0) {
+        return env->pc;
+    }
+
+#ifdef CONFIG_TCG
     uint64_t data[INSN_START_WORDS];
 
-    /* Outside of a running cpu, env contains the next pc. */
-    if (ra == 0 || !cpu_unwind_state_data(env_cpu(env), ra, data)) {
+    if (!cpu_unwind_state_data(env_cpu(env), ra, data)) {
         return env->pc;
     }
 
     /* Within unwind data, [0] is pc and [1] is the opcode. */
     return data[0] + insn_len(data[1]);
+#else
+    qemu_build_not_reached();
+#endif
 }
 
 static RISCVException write_misa(CPURISCVState *env, int csrno,
                                  target_ulong val, uintptr_t ra)
 {
+#ifdef CONFIG_TCG
     RISCVCPU *cpu = env_archcpu(env);
+#endif
     uint32_t orig_misa_ext = env->misa_ext;
     Error *local_err = NULL;
 
@@ -2178,7 +2188,11 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
     }
 
     env->misa_ext = val;
+#ifdef CONFIG_TCG
     riscv_cpu_validate_set_extensions(cpu, &local_err);
+#else
+    qemu_build_not_reached();
+#endif
     if (local_err != NULL) {
         /* Rollback on validation error */
         qemu_log_mask(LOG_GUEST_ERROR, "Unable to write MISA ext value "
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index af40561b31..eec6328281 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -23,33 +23,6 @@
 #include "fpu/softfloat.h"
 #include "internals.h"
 
-target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
-{
-    int soft = get_float_exception_flags(&env->fp_status);
-    target_ulong hard = 0;
-
-    hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
-    hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
-    hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
-    hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
-    hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
-
-    return hard;
-}
-
-void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
-{
-    int soft = 0;
-
-    soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
-    soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
-    soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
-    soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
-    soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
-
-    set_float_exception_flags(soft, &env->fp_status);
-}
-
 void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
 {
     int softrm;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 79f36abd63..c2b2f61ad9 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -9,7 +9,7 @@ gen = [
 ]
 
 riscv_ss = ss.source_set()
-riscv_ss.add(gen)
+riscv_ss.add(when: 'CONFIG_TCG', if_true: gen)
 
 riscv_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
                     if_true: files('common-semi-target.c'))
@@ -18,11 +18,14 @@ riscv_ss.add(files(
   'cpu.c',
   'cpu_helper.c',
   'csr.c',
-  'fpu_helper.c',
   'gdbstub.c',
+  'vector_internals.c',
+))
+
+riscv_ss.add(when: 'CONFIG_TCG', if_true: files(
+  'fpu_helper.c',
   'op_helper.c',
   'vector_helper.c',
-  'vector_internals.c',
   'bitmanip_helper.c',
   'translate.c',
   'm128_helper.c',
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 81873014cb..d17a8bbf10 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -28,21 +28,6 @@
 #include "exec/tlb-flags.h"
 #include "trace.h"
 
-/* Exceptions processing helpers */
-G_NORETURN void riscv_raise_exception(CPURISCVState *env,
-                                      RISCVException exception,
-                                      uintptr_t pc)
-{
-    CPUState *cs = env_cpu(env);
-
-    trace_riscv_exception(exception,
-                          riscv_cpu_get_trap_name(exception, false),
-                          env->pc);
-
-    cs->exception_index = exception;
-    cpu_loop_exit_restore(cs, pc);
-}
-
 void helper_raise_exception(CPURISCVState *env, uint32_t exception)
 {
     riscv_raise_exception(env, exception, 0);
-- 
2.43.0


Reply via email to