]> git.proxmox.com Git - mirror_qemu.git/blob - accel/tcg/atomic_common.c.inc
f3ab96e88839f9624ff4ffed8f50df9d81425dca
[mirror_qemu.git] / accel / tcg / atomic_common.c.inc
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
16 static void atomic_trace_rmw_pre(CPUArchState *env, target_ulong addr,
17 MemOpIdx oi)
18 {
19 CPUState *cpu = env_cpu(env);
20 uint16_t info = trace_mem_get_info(oi, false);
21
22 trace_guest_mem_before_exec(cpu, addr, info);
23 trace_guest_mem_before_exec(cpu, addr, info | TRACE_MEM_ST);
24 }
25
26 static void atomic_trace_rmw_post(CPUArchState *env, target_ulong addr,
27 MemOpIdx oi)
28 {
29 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_RW);
30 }
31
32 #if HAVE_ATOMIC128
33 static void atomic_trace_ld_pre(CPUArchState *env, target_ulong addr,
34 MemOpIdx oi)
35 {
36 uint16_t info = trace_mem_get_info(oi, false);
37
38 trace_guest_mem_before_exec(env_cpu(env), addr, info);
39 }
40
41 static void atomic_trace_ld_post(CPUArchState *env, target_ulong addr,
42 MemOpIdx oi)
43 {
44 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_R);
45 }
46
47 static void atomic_trace_st_pre(CPUArchState *env, target_ulong addr,
48 MemOpIdx oi)
49 {
50 uint16_t info = trace_mem_get_info(oi, true);
51
52 trace_guest_mem_before_exec(env_cpu(env), addr, info);
53 }
54
55 static void atomic_trace_st_post(CPUArchState *env, target_ulong addr,
56 MemOpIdx oi)
57 {
58 qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_W);
59 }
60 #endif
61
62 /*
63 * Atomic helpers callable from TCG.
64 * These have a common interface and all defer to cpu_atomic_*
65 * using the host return address from GETPC().
66 */
67
68 #define CMPXCHG_HELPER(OP, TYPE) \
69 TYPE HELPER(atomic_##OP)(CPUArchState *env, target_ulong addr, \
70 TYPE oldv, TYPE newv, uint32_t oi) \
71 { return cpu_atomic_##OP##_mmu(env, addr, oldv, newv, oi, GETPC()); }
72
73 CMPXCHG_HELPER(cmpxchgb, uint32_t)
74 CMPXCHG_HELPER(cmpxchgw_be, uint32_t)
75 CMPXCHG_HELPER(cmpxchgw_le, uint32_t)
76 CMPXCHG_HELPER(cmpxchgl_be, uint32_t)
77 CMPXCHG_HELPER(cmpxchgl_le, uint32_t)
78
79 #ifdef CONFIG_ATOMIC64
80 CMPXCHG_HELPER(cmpxchgq_be, uint64_t)
81 CMPXCHG_HELPER(cmpxchgq_le, uint64_t)
82 #endif
83
84 #undef CMPXCHG_HELPER
85
86 #define ATOMIC_HELPER(OP, TYPE) \
87 TYPE HELPER(glue(atomic_,OP))(CPUArchState *env, target_ulong addr, \
88 TYPE val, uint32_t oi) \
89 { return glue(glue(cpu_atomic_,OP),_mmu)(env, addr, val, oi, GETPC()); }
90
91 #ifdef CONFIG_ATOMIC64
92 #define GEN_ATOMIC_HELPERS(OP) \
93 ATOMIC_HELPER(glue(OP,b), uint32_t) \
94 ATOMIC_HELPER(glue(OP,w_be), uint32_t) \
95 ATOMIC_HELPER(glue(OP,w_le), uint32_t) \
96 ATOMIC_HELPER(glue(OP,l_be), uint32_t) \
97 ATOMIC_HELPER(glue(OP,l_le), uint32_t) \
98 ATOMIC_HELPER(glue(OP,q_be), uint64_t) \
99 ATOMIC_HELPER(glue(OP,q_le), uint64_t)
100 #else
101 #define GEN_ATOMIC_HELPERS(OP) \
102 ATOMIC_HELPER(glue(OP,b), uint32_t) \
103 ATOMIC_HELPER(glue(OP,w_be), uint32_t) \
104 ATOMIC_HELPER(glue(OP,w_le), uint32_t) \
105 ATOMIC_HELPER(glue(OP,l_be), uint32_t) \
106 ATOMIC_HELPER(glue(OP,l_le), uint32_t)
107 #endif
108
109 GEN_ATOMIC_HELPERS(fetch_add)
110 GEN_ATOMIC_HELPERS(fetch_and)
111 GEN_ATOMIC_HELPERS(fetch_or)
112 GEN_ATOMIC_HELPERS(fetch_xor)
113 GEN_ATOMIC_HELPERS(fetch_smin)
114 GEN_ATOMIC_HELPERS(fetch_umin)
115 GEN_ATOMIC_HELPERS(fetch_smax)
116 GEN_ATOMIC_HELPERS(fetch_umax)
117
118 GEN_ATOMIC_HELPERS(add_fetch)
119 GEN_ATOMIC_HELPERS(and_fetch)
120 GEN_ATOMIC_HELPERS(or_fetch)
121 GEN_ATOMIC_HELPERS(xor_fetch)
122 GEN_ATOMIC_HELPERS(smin_fetch)
123 GEN_ATOMIC_HELPERS(umin_fetch)
124 GEN_ATOMIC_HELPERS(smax_fetch)
125 GEN_ATOMIC_HELPERS(umax_fetch)
126
127 GEN_ATOMIC_HELPERS(xchg)
128
129 #undef ATOMIC_HELPER
130 #undef GEN_ATOMIC_HELPERS