]>
Commit | Line | Data |
---|---|---|
cfec3885 EC |
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 | ||
ddfdd417 | 16 | static void atomic_trace_rmw_post(CPUArchState *env, uint64_t addr, |
c3e83e37 | 17 | MemOpIdx oi) |
cfec3885 | 18 | { |
37aff087 | 19 | qemu_plugin_vcpu_mem_cb(env_cpu(env), addr, oi, QEMU_PLUGIN_MEM_RW); |
cfec3885 EC |
20 | } |
21 | ||
e28a8664 RH |
22 | /* |
23 | * Atomic helpers callable from TCG. | |
24 | * These have a common interface and all defer to cpu_atomic_* | |
25 | * using the host return address from GETPC(). | |
26 | */ | |
27 | ||
28 | #define CMPXCHG_HELPER(OP, TYPE) \ | |
ddfdd417 | 29 | TYPE HELPER(atomic_##OP)(CPUArchState *env, uint64_t addr, \ |
e28a8664 RH |
30 | TYPE oldv, TYPE newv, uint32_t oi) \ |
31 | { return cpu_atomic_##OP##_mmu(env, addr, oldv, newv, oi, GETPC()); } | |
32 | ||
33 | CMPXCHG_HELPER(cmpxchgb, uint32_t) | |
34 | CMPXCHG_HELPER(cmpxchgw_be, uint32_t) | |
35 | CMPXCHG_HELPER(cmpxchgw_le, uint32_t) | |
36 | CMPXCHG_HELPER(cmpxchgl_be, uint32_t) | |
37 | CMPXCHG_HELPER(cmpxchgl_le, uint32_t) | |
38 | ||
39 | #ifdef CONFIG_ATOMIC64 | |
40 | CMPXCHG_HELPER(cmpxchgq_be, uint64_t) | |
41 | CMPXCHG_HELPER(cmpxchgq_le, uint64_t) | |
42 | #endif | |
43 | ||
76f9d6ad | 44 | #if HAVE_CMPXCHG128 |
123ae568 RH |
45 | CMPXCHG_HELPER(cmpxchgo_be, Int128) |
46 | CMPXCHG_HELPER(cmpxchgo_le, Int128) | |
47 | #endif | |
48 | ||
e28a8664 RH |
49 | #undef CMPXCHG_HELPER |
50 | ||
fbea7a40 RH |
51 | Int128 HELPER(nonatomic_cmpxchgo)(CPUArchState *env, uint64_t addr, |
52 | Int128 cmpv, Int128 newv, uint32_t oi) | |
123ae568 RH |
53 | { |
54 | #if TCG_TARGET_REG_BITS == 32 | |
55 | uintptr_t ra = GETPC(); | |
56 | Int128 oldv; | |
57 | ||
fbea7a40 | 58 | oldv = cpu_ld16_mmu(env, addr, oi, ra); |
123ae568 | 59 | if (int128_eq(oldv, cmpv)) { |
fbea7a40 | 60 | cpu_st16_mmu(env, addr, newv, oi, ra); |
123ae568 RH |
61 | } else { |
62 | /* Even with comparison failure, still need a write cycle. */ | |
63 | probe_write(env, addr, 16, get_mmuidx(oi), ra); | |
64 | } | |
65 | return oldv; | |
66 | #else | |
67 | g_assert_not_reached(); | |
68 | #endif | |
69 | } | |
70 | ||
e28a8664 | 71 | #define ATOMIC_HELPER(OP, TYPE) \ |
ddfdd417 | 72 | TYPE HELPER(glue(atomic_,OP))(CPUArchState *env, uint64_t addr, \ |
e28a8664 RH |
73 | TYPE val, uint32_t oi) \ |
74 | { return glue(glue(cpu_atomic_,OP),_mmu)(env, addr, val, oi, GETPC()); } | |
75 | ||
76 | #ifdef CONFIG_ATOMIC64 | |
77 | #define GEN_ATOMIC_HELPERS(OP) \ | |
78 | ATOMIC_HELPER(glue(OP,b), uint32_t) \ | |
79 | ATOMIC_HELPER(glue(OP,w_be), uint32_t) \ | |
80 | ATOMIC_HELPER(glue(OP,w_le), uint32_t) \ | |
81 | ATOMIC_HELPER(glue(OP,l_be), uint32_t) \ | |
82 | ATOMIC_HELPER(glue(OP,l_le), uint32_t) \ | |
83 | ATOMIC_HELPER(glue(OP,q_be), uint64_t) \ | |
84 | ATOMIC_HELPER(glue(OP,q_le), uint64_t) | |
85 | #else | |
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 | #endif | |
93 | ||
94 | GEN_ATOMIC_HELPERS(fetch_add) | |
95 | GEN_ATOMIC_HELPERS(fetch_and) | |
96 | GEN_ATOMIC_HELPERS(fetch_or) | |
97 | GEN_ATOMIC_HELPERS(fetch_xor) | |
98 | GEN_ATOMIC_HELPERS(fetch_smin) | |
99 | GEN_ATOMIC_HELPERS(fetch_umin) | |
100 | GEN_ATOMIC_HELPERS(fetch_smax) | |
101 | GEN_ATOMIC_HELPERS(fetch_umax) | |
102 | ||
103 | GEN_ATOMIC_HELPERS(add_fetch) | |
104 | GEN_ATOMIC_HELPERS(and_fetch) | |
105 | GEN_ATOMIC_HELPERS(or_fetch) | |
106 | GEN_ATOMIC_HELPERS(xor_fetch) | |
107 | GEN_ATOMIC_HELPERS(smin_fetch) | |
108 | GEN_ATOMIC_HELPERS(umin_fetch) | |
109 | GEN_ATOMIC_HELPERS(smax_fetch) | |
110 | GEN_ATOMIC_HELPERS(umax_fetch) | |
111 | ||
112 | GEN_ATOMIC_HELPERS(xchg) | |
113 | ||
114 | #undef ATOMIC_HELPER | |
115 | #undef GEN_ATOMIC_HELPERS |