@samitouri / QOSamiQemu / commits / ef3885cd38

target/mips: Inline cpu_ld/st_mmuidx_ra() calls in Atomic LD/ST helpers

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>

Philippe Mathieu-Daudé committed Apr 16, 2026 at 16:25 UTC ef3885cd38564ccab24a89ce444a0ec9f590009e
2 files changed +16 -12
target/mips/tcg/ldst_helper.c
+15 -11
@@ -28,23 +28,27 @@
28 #include "internal.h"
29
30 #ifndef CONFIG_USER_ONLY
31 +#include "accel/tcg/probe.h"
32 +#include "exec/tlb-flags.h"
33
34 #define HELPER_LD_ATOMIC(name, insn, almask, do_cast) \
35 target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, \
36 uint32_t memop_idx) \
37 { \
36 - MemOpIdx oi = memop_idx; \
37 - unsigned mem_idx = get_mmuidx(oi); \
38 - if (arg & almask) { \
39 - if (!(env->hflags & MIPS_HFLAG_DM)) { \
40 - env->CP0_BadVAddr = arg; \
41 - } \
42 - do_raise_exception(env, EXCP_AdEL, GETPC()); \
43 - } \
44 - env->CP0_LLAddr = cpu_mips_translate_address(env, arg, MMU_DATA_LOAD, \
45 - GETPC()); \
38 + MemOpIdx oi = memop_idx; \
39 + unsigned mem_idx = get_mmuidx(oi); \
40 + unsigned size = memop_size(get_memop(oi)); \
41 + uintptr_t ra = GETPC(); \
42 + CPUTLBEntryFull *full; \
43 + void *host_unused; \
44 + int flags; \
45 + \
46 + env->llval = do_cast cpu_##insn##_mmu(env, arg, oi, ra); \
47 + flags = probe_access_full(env, arg, size, MMU_DATA_LOAD, mem_idx, \
48 + true, &host_unused, &full, ra); \
49 + assert(!(flags & TLB_INVALID_MASK)); \
50 + env->CP0_LLAddr = full->phys_addr; \
51 env->lladdr = arg; \
47 - env->llval = do_cast cpu_##insn##_mmuidx_ra(env, arg, mem_idx, GETPC()); \
52 return env->llval; \
53 }
54 HELPER_LD_ATOMIC(ll, ldl, 0x3, (target_long)(int32_t))
target/mips/tcg/translate.c
+1 -1
@@ -1936,7 +1936,7 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx_ignored, \
1936 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1937 DisasContext *ctx) \
1938 { \
1939 - MemOpIdx oi = make_memop_idx(memop, mem_idx); \
1939 + MemOpIdx oi = make_memop_idx(memop | MO_ALIGN, mem_idx); \
1940 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(oi)); \
1941 }
1942 #endif