]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
target/mips: Inline cpu_ld/st_mmuidx_ra() calls in Atomic LD/ST helpers
authorPhilippe Mathieu-Daudé <philmd@linaro.org>
Thu, 16 Apr 2026 14:25:45 +0000 (16:25 +0200)
committerPhilippe Mathieu-Daudé <philmd@linaro.org>
Wed, 6 May 2026 10:58:08 +0000 (12:58 +0200)
Have callers set MO_ALIGN in the MemOp bits.

Perform the access first, filling the TLB in the process.
If the tlb cannot be filled, access is not permitted, and
an exception is raised. Thus remove the now unnecessary
do_raise_exception() call.

Since the TLB is filled, use probe_access() to get CP0_LLAddr.

Move env->CP0_LLAddr and env->lladdr assignments so we
don't update them when an alignment fault occurs.

Since we have a handy MemOpIdx, replace the legacy
cpu_ld*_mmuidx_ra() calls by cpu_ld*_mmu() equivalent.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20260417042620.35329-3-philmd@linaro.org>

target/mips/tcg/ldst_helper.c
target/mips/tcg/translate.c

index b36b12d87d678b78bbba411552af4bd48d88a0c9..1b25466b496d1756b3e4f2b318fc0f58f1790497 100644 (file)
 #include "internal.h"
 
 #ifndef CONFIG_USER_ONLY
+#include "accel/tcg/probe.h"
+#include "exec/tlb-flags.h"
 
 #define HELPER_LD_ATOMIC(name, insn, almask, do_cast)                         \
 target_ulong helper_##name(CPUMIPSState *env, target_ulong arg,               \
                            uint32_t memop_idx)                                \
 {                                                                             \
-    MemOpIdx oi = memop_idx; \
-    unsigned mem_idx = get_mmuidx(oi); \
-    if (arg & almask) {                                                       \
-        if (!(env->hflags & MIPS_HFLAG_DM)) {                                 \
-            env->CP0_BadVAddr = arg;                                          \
-        }                                                                     \
-        do_raise_exception(env, EXCP_AdEL, GETPC());                          \
-    }                                                                         \
-    env->CP0_LLAddr = cpu_mips_translate_address(env, arg, MMU_DATA_LOAD,     \
-                                                 GETPC());                    \
+    MemOpIdx oi = memop_idx;                                                  \
+    unsigned mem_idx = get_mmuidx(oi);                                        \
+    unsigned size = memop_size(get_memop(oi));                                \
+    uintptr_t ra = GETPC();                                                   \
+    CPUTLBEntryFull *full;                                                    \
+    void *host_unused;                                                        \
+    int flags;                                                                \
+                                                                              \
+    env->llval = do_cast cpu_##insn##_mmu(env, arg, oi, ra);                  \
+    flags = probe_access_full(env, arg, size, MMU_DATA_LOAD, mem_idx,         \
+                              true, &host_unused, &full, ra);                 \
+    assert(!(flags & TLB_INVALID_MASK));                                      \
+    env->CP0_LLAddr = full->phys_addr;                                        \
     env->lladdr = arg;                                                        \
-    env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC());  \
     return env->llval;                                                        \
 }
 HELPER_LD_ATOMIC(ll, ldl, 0x3, (target_long)(int32_t))
index ee6199875cf23d811352c0ad1a17d1450faad0f1..fff6390f5d4781c6912be9cf0127f700df0a6384 100644 (file)
@@ -1936,7 +1936,7 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx_ignored,  \
 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
                                 DisasContext *ctx)                         \
 {                                                                          \
-    MemOpIdx oi = make_memop_idx(memop, mem_idx);                          \
+    MemOpIdx oi = make_memop_idx(memop | MO_ALIGN, mem_idx);               \
     gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(oi));           \
 }
 #endif