1/* 2 * Common Atomic Helper Functions 3 * 4 * This file should be included before the various instantiations of 5 * the atomic_template.h helpers. 6 * 7 * Copyright (c) 2019 Linaro 8 * Written by Alex Bennée <alex.bennee@linaro.org> 9 * 10 * SPDX-License-Identifier: GPL-2.0-or-later 11 * 12 * This work is licensed under the terms of the GNU GPL, version 2 or later. 13 * See the COPYING file in the top-level directory. 14 */ 15 16static inline 17void atomic_trace_rmw_pre(CPUArchState *env, target_ulong addr, uint16_t info) 18{ 19 CPUState *cpu = env_cpu(env); 20 21 trace_guest_mem_before_exec(cpu, addr, info); 22 trace_guest_mem_before_exec(cpu, addr, info | TRACE_MEM_ST); 23} 24 25static inline void 26atomic_trace_rmw_post(CPUArchState *env, target_ulong addr, uint16_t info) 27{ 28 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info); 29 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info | TRACE_MEM_ST); 30} 31 32static inline 33void atomic_trace_ld_pre(CPUArchState *env, target_ulong addr, uint16_t info) 34{ 35 trace_guest_mem_before_exec(env_cpu(env), addr, info); 36} 37 38static inline 39void atomic_trace_ld_post(CPUArchState *env, target_ulong addr, uint16_t info) 40{ 41 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info); 42} 43 44static inline 45void atomic_trace_st_pre(CPUArchState *env, target_ulong addr, uint16_t info) 46{ 47 trace_guest_mem_before_exec(env_cpu(env), addr, info); 48} 49 50static inline 51void atomic_trace_st_post(CPUArchState *env, target_ulong addr, uint16_t info) 52{ 53 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, info); 54} 55 56/* 57 * Atomic helpers callable from TCG. 58 * These have a common interface and all defer to cpu_atomic_* 59 * using the host return address from GETPC(). 60 */ 61 62#define CMPXCHG_HELPER(OP, TYPE) \ 63 TYPE HELPER(atomic_##OP)(CPUArchState *env, target_ulong addr, \ 64 TYPE oldv, TYPE newv, uint32_t oi) \ 65 { return cpu_atomic_##OP##_mmu(env, addr, oldv, newv, oi, GETPC()); } 66 67CMPXCHG_HELPER(cmpxchgb, uint32_t) 68CMPXCHG_HELPER(cmpxchgw_be, uint32_t) 69CMPXCHG_HELPER(cmpxchgw_le, uint32_t) 70CMPXCHG_HELPER(cmpxchgl_be, uint32_t) 71CMPXCHG_HELPER(cmpxchgl_le, uint32_t) 72 73#ifdef CONFIG_ATOMIC64 74CMPXCHG_HELPER(cmpxchgq_be, uint64_t) 75CMPXCHG_HELPER(cmpxchgq_le, uint64_t) 76#endif 77 78#undef CMPXCHG_HELPER 79 80#define ATOMIC_HELPER(OP, TYPE) \ 81 TYPE HELPER(glue(atomic_,OP))(CPUArchState *env, target_ulong addr, \ 82 TYPE val, uint32_t oi) \ 83 { return glue(glue(cpu_atomic_,OP),_mmu)(env, addr, val, oi, GETPC()); } 84 85#ifdef CONFIG_ATOMIC64 86#define GEN_ATOMIC_HELPERS(OP) \ 87 ATOMIC_HELPER(glue(OP,b), uint32_t) \ 88 ATOMIC_HELPER(glue(OP,w_be), uint32_t) \ 89 ATOMIC_HELPER(glue(OP,w_le), uint32_t) \ 90 ATOMIC_HELPER(glue(OP,l_be), uint32_t) \ 91 ATOMIC_HELPER(glue(OP,l_le), uint32_t) \ 92 ATOMIC_HELPER(glue(OP,q_be), uint64_t) \ 93 ATOMIC_HELPER(glue(OP,q_le), uint64_t) 94#else 95#define GEN_ATOMIC_HELPERS(OP) \ 96 ATOMIC_HELPER(glue(OP,b), uint32_t) \ 97 ATOMIC_HELPER(glue(OP,w_be), uint32_t) \ 98 ATOMIC_HELPER(glue(OP,w_le), uint32_t) \ 99 ATOMIC_HELPER(glue(OP,l_be), uint32_t) \ 100 ATOMIC_HELPER(glue(OP,l_le), uint32_t) 101#endif 102 103GEN_ATOMIC_HELPERS(fetch_add) 104GEN_ATOMIC_HELPERS(fetch_and) 105GEN_ATOMIC_HELPERS(fetch_or) 106GEN_ATOMIC_HELPERS(fetch_xor) 107GEN_ATOMIC_HELPERS(fetch_smin) 108GEN_ATOMIC_HELPERS(fetch_umin) 109GEN_ATOMIC_HELPERS(fetch_smax) 110GEN_ATOMIC_HELPERS(fetch_umax) 111 112GEN_ATOMIC_HELPERS(add_fetch) 113GEN_ATOMIC_HELPERS(and_fetch) 114GEN_ATOMIC_HELPERS(or_fetch) 115GEN_ATOMIC_HELPERS(xor_fetch) 116GEN_ATOMIC_HELPERS(smin_fetch) 117GEN_ATOMIC_HELPERS(umin_fetch) 118GEN_ATOMIC_HELPERS(smax_fetch) 119GEN_ATOMIC_HELPERS(umax_fetch) 120 121GEN_ATOMIC_HELPERS(xchg) 122 123#undef ATOMIC_HELPER 124#undef GEN_ATOMIC_HELPERS 125