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