|
@@ -34,12 +34,12 @@
|
|
|
#include "qemu/atomic128.h"
|
|
|
#include "exec/translate-all.h"
|
|
|
#include "trace/trace-root.h"
|
|
|
-#include "trace/mem.h"
|
|
|
#include "tb-hash.h"
|
|
|
#include "internal.h"
|
|
|
#ifdef CONFIG_PLUGIN
|
|
|
#include "qemu/plugin-memory.h"
|
|
|
#endif
|
|
|
+#include "tcg/tcg-ldst.h"
|
|
|
|
|
|
/* DEBUG defines, enable DEBUG_TLB_LOG to log to the CPU_LOG_MMU target */
|
|
|
/* #define DEBUG_TLB */
|
|
@@ -1749,7 +1749,7 @@ bool tlb_plugin_lookup(CPUState *cpu, target_ulong addr, int mmu_idx,
|
|
|
* @prot may be PAGE_READ, PAGE_WRITE, or PAGE_READ|PAGE_WRITE.
|
|
|
*/
|
|
|
static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, int size, int prot,
|
|
|
+ MemOpIdx oi, int size, int prot,
|
|
|
uintptr_t retaddr)
|
|
|
{
|
|
|
size_t mmu_idx = get_mmuidx(oi);
|
|
@@ -1840,6 +1840,25 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|
|
cpu_loop_exit_atomic(env_cpu(env), retaddr);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Verify that we have passed the correct MemOp to the correct function.
|
|
|
+ *
|
|
|
+ * In the case of the helper_*_mmu functions, we will have done this by
|
|
|
+ * using the MemOp to look up the helper during code generation.
|
|
|
+ *
|
|
|
+ * In the case of the cpu_*_mmu functions, this is up to the caller.
|
|
|
+ * We could present one function to target code, and dispatch based on
|
|
|
+ * the MemOp, but so far we have worked hard to avoid an indirect function
|
|
|
+ * call along the memory path.
|
|
|
+ */
|
|
|
+static void validate_memop(MemOpIdx oi, MemOp expected)
|
|
|
+{
|
|
|
+#ifdef CONFIG_DEBUG_TCG
|
|
|
+ MemOp have = get_memop(oi) & (MO_SIZE | MO_BSWAP);
|
|
|
+ assert(have == expected);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Load Helpers
|
|
|
*
|
|
@@ -1850,7 +1869,7 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
|
|
|
*/
|
|
|
|
|
|
typedef uint64_t FullLoadHelper(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr);
|
|
|
+ MemOpIdx oi, uintptr_t retaddr);
|
|
|
|
|
|
static inline uint64_t QEMU_ALWAYS_INLINE
|
|
|
load_memop(const void *haddr, MemOp op)
|
|
@@ -1876,7 +1895,7 @@ load_memop(const void *haddr, MemOp op)
|
|
|
}
|
|
|
|
|
|
static inline uint64_t QEMU_ALWAYS_INLINE
|
|
|
-load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
|
|
|
+load_helper(CPUArchState *env, target_ulong addr, MemOpIdx oi,
|
|
|
uintptr_t retaddr, MemOp op, bool code_read,
|
|
|
FullLoadHelper *full_load)
|
|
|
{
|
|
@@ -1991,79 +2010,86 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi,
|
|
|
*/
|
|
|
|
|
|
static uint64_t full_ldub_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_UB);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_UB, false, full_ldub_mmu);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return full_ldub_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_le_lduw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_LEUW);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_LEUW, false,
|
|
|
full_le_lduw_mmu);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_le_lduw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return full_le_lduw_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_be_lduw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_BEUW);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_BEUW, false,
|
|
|
full_be_lduw_mmu);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_be_lduw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return full_be_lduw_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_le_ldul_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_LEUL);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_LEUL, false,
|
|
|
full_le_ldul_mmu);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_le_ldul_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return full_le_ldul_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_be_ldul_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_BEUL);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_BEUL, false,
|
|
|
full_be_ldul_mmu);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_be_ldul_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return full_be_ldul_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
uint64_t helper_le_ldq_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_LEQ);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_LEQ, false,
|
|
|
helper_le_ldq_mmu);
|
|
|
}
|
|
|
|
|
|
uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_BEQ);
|
|
|
return load_helper(env, addr, oi, retaddr, MO_BEQ, false,
|
|
|
helper_be_ldq_mmu);
|
|
|
}
|
|
@@ -2075,31 +2101,31 @@ uint64_t helper_be_ldq_mmu(CPUArchState *env, target_ulong addr,
|
|
|
|
|
|
|
|
|
tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return (int8_t)helper_ret_ldub_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_le_ldsw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return (int16_t)helper_le_lduw_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_be_ldsw_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return (int16_t)helper_be_lduw_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_le_ldsl_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return (int32_t)helper_le_ldul_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return (int32_t)helper_be_ldul_mmu(env, addr, oi, retaddr);
|
|
|
}
|
|
@@ -2109,193 +2135,56 @@ tcg_target_ulong helper_be_ldsl_mmu(CPUArchState *env, target_ulong addr,
|
|
|
*/
|
|
|
|
|
|
static inline uint64_t cpu_load_helper(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t retaddr,
|
|
|
- MemOp op, FullLoadHelper *full_load)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr,
|
|
|
+ FullLoadHelper *full_load)
|
|
|
{
|
|
|
- uint16_t meminfo;
|
|
|
- TCGMemOpIdx oi;
|
|
|
uint64_t ret;
|
|
|
|
|
|
- meminfo = trace_mem_get_info(op, mmu_idx, false);
|
|
|
- trace_guest_mem_before_exec(env_cpu(env), addr, meminfo);
|
|
|
-
|
|
|
- op &= ~MO_SIGN;
|
|
|
- oi = make_memop_idx(op, mmu_idx);
|
|
|
+ trace_guest_ld_before_exec(env_cpu(env), addr, oi);
|
|
|
ret = full_load(env, addr, oi, retaddr);
|
|
|
-
|
|
|
- qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, meminfo);
|
|
|
-
|
|
|
+ qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_UB, full_ldub_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return (int8_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_SB,
|
|
|
- full_ldub_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUW, full_be_lduw_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_BESW,
|
|
|
- full_be_lduw_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEUL, full_be_ldul_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_BEQ, helper_be_ldq_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUW, full_le_lduw_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return (int16_t)cpu_load_helper(env, addr, mmu_idx, ra, MO_LESW,
|
|
|
- full_le_lduw_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEUL, full_le_ldul_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
|
|
|
- int mmu_idx, uintptr_t ra)
|
|
|
-{
|
|
|
- return cpu_load_helper(env, addr, mmu_idx, ra, MO_LEQ, helper_le_ldq_mmu);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldub_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldub_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsb_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldsb_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_lduw_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_lduw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsw_be_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldsw_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldl_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldl_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint64_t cpu_ldq_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldq_be_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_lduw_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_lduw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsw_le_data_ra(CPUArchState *env, target_ulong ptr, uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldsw_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldl_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldl_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint64_t cpu_ldq_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uintptr_t retaddr)
|
|
|
-{
|
|
|
- return cpu_ldq_le_mmuidx_ra(env, ptr, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldub_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_ldub_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, full_ldub_mmu);
|
|
|
}
|
|
|
|
|
|
-int cpu_ldsb_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint16_t cpu_ldw_be_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_ldsb_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, full_be_lduw_mmu);
|
|
|
}
|
|
|
|
|
|
-uint32_t cpu_lduw_be_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint32_t cpu_ldl_be_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_lduw_be_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, full_be_ldul_mmu);
|
|
|
}
|
|
|
|
|
|
-int cpu_ldsw_be_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint64_t cpu_ldq_be_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_ldsw_be_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, MO_BEQ, helper_be_ldq_mmu);
|
|
|
}
|
|
|
|
|
|
-uint32_t cpu_ldl_be_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint16_t cpu_ldw_le_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_ldl_be_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, full_le_lduw_mmu);
|
|
|
}
|
|
|
|
|
|
-uint64_t cpu_ldq_be_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint32_t cpu_ldl_le_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_ldq_be_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, full_le_ldul_mmu);
|
|
|
}
|
|
|
|
|
|
-uint32_t cpu_lduw_le_data(CPUArchState *env, target_ulong ptr)
|
|
|
+uint64_t cpu_ldq_le_mmu(CPUArchState *env, abi_ptr addr,
|
|
|
+ MemOpIdx oi, uintptr_t ra)
|
|
|
{
|
|
|
- return cpu_lduw_le_data_ra(env, ptr, 0);
|
|
|
-}
|
|
|
-
|
|
|
-int cpu_ldsw_le_data(CPUArchState *env, target_ulong ptr)
|
|
|
-{
|
|
|
- return cpu_ldsw_le_data_ra(env, ptr, 0);
|
|
|
-}
|
|
|
-
|
|
|
-uint32_t cpu_ldl_le_data(CPUArchState *env, target_ulong ptr)
|
|
|
-{
|
|
|
- return cpu_ldl_le_data_ra(env, ptr, 0);
|
|
|
-}
|
|
|
-
|
|
|
-uint64_t cpu_ldq_le_data(CPUArchState *env, target_ulong ptr)
|
|
|
-{
|
|
|
- return cpu_ldq_le_data_ra(env, ptr, 0);
|
|
|
+ return cpu_load_helper(env, addr, oi, ra, helper_le_ldq_mmu);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2332,6 +2221,9 @@ store_memop(void *haddr, uint64_t val, MemOp op)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void full_stb_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr);
|
|
|
+
|
|
|
static void __attribute__((noinline))
|
|
|
store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
uintptr_t retaddr, size_t size, uintptr_t mmu_idx,
|
|
@@ -2341,7 +2233,7 @@ store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
uintptr_t index, index2;
|
|
|
CPUTLBEntry *entry, *entry2;
|
|
|
target_ulong page2, tlb_addr, tlb_addr2;
|
|
|
- TCGMemOpIdx oi;
|
|
|
+ MemOpIdx oi;
|
|
|
size_t size2;
|
|
|
int i;
|
|
|
|
|
@@ -2395,20 +2287,20 @@ store_helper_unaligned(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
for (i = 0; i < size; ++i) {
|
|
|
/* Big-endian extract. */
|
|
|
uint8_t val8 = val >> (((size - 1) * 8) - (i * 8));
|
|
|
- helper_ret_stb_mmu(env, addr + i, val8, oi, retaddr);
|
|
|
+ full_stb_mmu(env, addr + i, val8, oi, retaddr);
|
|
|
}
|
|
|
} else {
|
|
|
for (i = 0; i < size; ++i) {
|
|
|
/* Little-endian extract. */
|
|
|
uint8_t val8 = val >> (i * 8);
|
|
|
- helper_ret_stb_mmu(env, addr + i, val8, oi, retaddr);
|
|
|
+ full_stb_mmu(env, addr + i, val8, oi, retaddr);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static inline void QEMU_ALWAYS_INLINE
|
|
|
store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr, MemOp op)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr, MemOp op)
|
|
|
{
|
|
|
uintptr_t mmu_idx = get_mmuidx(oi);
|
|
|
uintptr_t index = tlb_index(env, mmu_idx, addr);
|
|
@@ -2504,187 +2396,145 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
store_memop(haddr, val, op);
|
|
|
}
|
|
|
|
|
|
-void __attribute__((noinline))
|
|
|
-helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+static void __attribute__((noinline))
|
|
|
+full_stb_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
+ validate_memop(oi, MO_UB);
|
|
|
store_helper(env, addr, val, oi, retaddr, MO_UB);
|
|
|
}
|
|
|
|
|
|
-void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_LEUW);
|
|
|
-}
|
|
|
-
|
|
|
-void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_BEUW);
|
|
|
-}
|
|
|
-
|
|
|
-void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_LEUL);
|
|
|
-}
|
|
|
-
|
|
|
-void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_BEUL);
|
|
|
-}
|
|
|
-
|
|
|
-void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_LEQ);
|
|
|
-}
|
|
|
-
|
|
|
-void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
-{
|
|
|
- store_helper(env, addr, val, oi, retaddr, MO_BEQ);
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Store Helpers for cpu_ldst.h
|
|
|
- */
|
|
|
-
|
|
|
-static inline void QEMU_ALWAYS_INLINE
|
|
|
-cpu_store_helper(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr, MemOp op)
|
|
|
+void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- TCGMemOpIdx oi;
|
|
|
- uint16_t meminfo;
|
|
|
-
|
|
|
- meminfo = trace_mem_get_info(op, mmu_idx, true);
|
|
|
- trace_guest_mem_before_exec(env_cpu(env), addr, meminfo);
|
|
|
-
|
|
|
- oi = make_memop_idx(op, mmu_idx);
|
|
|
- store_helper(env, addr, val, oi, retaddr, op);
|
|
|
-
|
|
|
- qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, meminfo);
|
|
|
+ full_stb_mmu(env, addr, val, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
-void cpu_stb_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+static void full_le_stw_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_UB);
|
|
|
+ validate_memop(oi, MO_LEUW);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_LEUW);
|
|
|
}
|
|
|
|
|
|
-void cpu_stw_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+void helper_le_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUW);
|
|
|
+ full_le_stw_mmu(env, addr, val, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
-void cpu_stl_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+static void full_be_stw_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEUL);
|
|
|
+ validate_memop(oi, MO_BEUW);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_BEUW);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_be_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+void helper_be_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_BEQ);
|
|
|
+ full_be_stw_mmu(env, addr, val, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
-void cpu_stw_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+static void full_le_stl_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUW);
|
|
|
+ validate_memop(oi, MO_LEUL);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_LEUL);
|
|
|
}
|
|
|
|
|
|
-void cpu_stl_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+void helper_le_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEUL);
|
|
|
+ full_le_stl_mmu(env, addr, val, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_le_mmuidx_ra(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
- int mmu_idx, uintptr_t retaddr)
|
|
|
+static void full_be_stl_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_store_helper(env, addr, val, mmu_idx, retaddr, MO_LEQ);
|
|
|
+ validate_memop(oi, MO_BEUL);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_BEUL);
|
|
|
}
|
|
|
|
|
|
-void cpu_stb_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint32_t val, uintptr_t retaddr)
|
|
|
+void helper_be_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stb_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
+ full_be_stl_mmu(env, addr, val, oi, retaddr);
|
|
|
}
|
|
|
|
|
|
-void cpu_stw_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint32_t val, uintptr_t retaddr)
|
|
|
+void helper_le_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stw_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
+ validate_memop(oi, MO_LEQ);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_LEQ);
|
|
|
}
|
|
|
|
|
|
-void cpu_stl_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint32_t val, uintptr_t retaddr)
|
|
|
+void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stl_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
+ validate_memop(oi, MO_BEQ);
|
|
|
+ store_helper(env, addr, val, oi, retaddr, MO_BEQ);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_be_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint64_t val, uintptr_t retaddr)
|
|
|
-{
|
|
|
- cpu_stq_be_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
+/*
|
|
|
+ * Store Helpers for cpu_ldst.h
|
|
|
+ */
|
|
|
|
|
|
-void cpu_stw_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint32_t val, uintptr_t retaddr)
|
|
|
-{
|
|
|
- cpu_stw_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
-}
|
|
|
+typedef void FullStoreHelper(CPUArchState *env, target_ulong addr,
|
|
|
+ uint64_t val, MemOpIdx oi, uintptr_t retaddr);
|
|
|
|
|
|
-void cpu_stl_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint32_t val, uintptr_t retaddr)
|
|
|
+static inline void cpu_store_helper(CPUArchState *env, target_ulong addr,
|
|
|
+ uint64_t val, MemOpIdx oi, uintptr_t ra,
|
|
|
+ FullStoreHelper *full_store)
|
|
|
{
|
|
|
- cpu_stl_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
+ trace_guest_st_before_exec(env_cpu(env), addr, oi);
|
|
|
+ full_store(env, addr, val, oi, ra);
|
|
|
+ qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_le_data_ra(CPUArchState *env, target_ulong ptr,
|
|
|
- uint64_t val, uintptr_t retaddr)
|
|
|
+void cpu_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stq_le_mmuidx_ra(env, ptr, val, cpu_mmu_index(env, false), retaddr);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, full_stb_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stb_data(CPUArchState *env, target_ulong ptr, uint32_t val)
|
|
|
+void cpu_stw_be_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stb_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, full_be_stw_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stw_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
|
|
|
+void cpu_stl_be_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stw_be_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, full_be_stl_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stl_be_data(CPUArchState *env, target_ulong ptr, uint32_t val)
|
|
|
+void cpu_stq_be_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stl_be_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, helper_be_stq_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_be_data(CPUArchState *env, target_ulong ptr, uint64_t val)
|
|
|
+void cpu_stw_le_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stq_be_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, full_le_stw_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stw_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
|
|
|
+void cpu_stl_le_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stw_le_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, full_le_stl_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stl_le_data(CPUArchState *env, target_ulong ptr, uint32_t val)
|
|
|
+void cpu_stq_le_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
- cpu_stl_le_data_ra(env, ptr, val, 0);
|
|
|
+ cpu_store_helper(env, addr, val, oi, retaddr, helper_le_stq_mmu);
|
|
|
}
|
|
|
|
|
|
-void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
|
|
|
-{
|
|
|
- cpu_stq_le_data_ra(env, ptr, val, 0);
|
|
|
-}
|
|
|
+#include "ldst_common.c.inc"
|
|
|
|
|
|
/*
|
|
|
* First set of functions passes in OI and RETADDR.
|
|
@@ -2721,49 +2571,49 @@ void cpu_stq_le_data(CPUArchState *env, target_ulong ptr, uint64_t val)
|
|
|
/* Code access functions. */
|
|
|
|
|
|
static uint64_t full_ldub_code(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return load_helper(env, addr, oi, retaddr, MO_8, true, full_ldub_code);
|
|
|
}
|
|
|
|
|
|
uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr)
|
|
|
{
|
|
|
- TCGMemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(env, true));
|
|
|
+ MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(env, true));
|
|
|
return full_ldub_code(env, addr, oi, 0);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_lduw_code(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return load_helper(env, addr, oi, retaddr, MO_TEUW, true, full_lduw_code);
|
|
|
}
|
|
|
|
|
|
uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr)
|
|
|
{
|
|
|
- TCGMemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(env, true));
|
|
|
+ MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(env, true));
|
|
|
return full_lduw_code(env, addr, oi, 0);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_ldl_code(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return load_helper(env, addr, oi, retaddr, MO_TEUL, true, full_ldl_code);
|
|
|
}
|
|
|
|
|
|
uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
|
|
|
{
|
|
|
- TCGMemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(env, true));
|
|
|
+ MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(env, true));
|
|
|
return full_ldl_code(env, addr, oi, 0);
|
|
|
}
|
|
|
|
|
|
static uint64_t full_ldq_code(CPUArchState *env, target_ulong addr,
|
|
|
- TCGMemOpIdx oi, uintptr_t retaddr)
|
|
|
+ MemOpIdx oi, uintptr_t retaddr)
|
|
|
{
|
|
|
return load_helper(env, addr, oi, retaddr, MO_TEQ, true, full_ldq_code);
|
|
|
}
|
|
|
|
|
|
uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
|
|
|
{
|
|
|
- TCGMemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true));
|
|
|
+ MemOpIdx oi = make_memop_idx(MO_TEQ, cpu_mmu_index(env, true));
|
|
|
return full_ldq_code(env, addr, oi, 0);
|
|
|
}
|