Signed-off-by: Emilio G. Cota <c...@braap.org> --- include/exec/cpu_atomic_template.h | 56 +++++++++++++++++++++++++++++ include/exec/cpu_atomic_useronly_template.h | 39 ++++++++++++++++++++ include/exec/cpu_ldst_template.h | 2 ++ include/exec/cpu_ldst_useronly_template.h | 2 ++ 4 files changed, 99 insertions(+) create mode 100644 include/exec/cpu_atomic_template.h create mode 100644 include/exec/cpu_atomic_useronly_template.h
diff --git a/include/exec/cpu_atomic_template.h b/include/exec/cpu_atomic_template.h new file mode 100644 index 0000000..13f4ffd --- /dev/null +++ b/include/exec/cpu_atomic_template.h @@ -0,0 +1,56 @@ +#include "tcg/tcg.h" + +static inline DATA_TYPE +glue(glue(glue(cpu_cmpxchg, SUFFIX), MEMSUFFIX), + _ra)(CPUArchState *env, target_ulong ptr, DATA_TYPE old, DATA_TYPE new, + uintptr_t ra) +{ + target_ulong addr; + TCGMemOpIdx oi; + int page_index; + DATA_TYPE ret; + int mmu_idx; + + addr = ptr; + page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + mmu_idx = CPU_MMU_INDEX; + if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != + (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { + oi = make_memop_idx(SHIFT, mmu_idx); + ret = glue(glue(helper_cmpxchg, SUFFIX), MMUSUFFIX)(env, addr, old, new, + oi, ra); + } else { + uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; + + ret = atomic_cmpxchg((DATA_TYPE *)hostaddr, old, new); + } + return ret; +} + +/* define cmpxchgo once ldq and stq have been defined */ +#if DATA_SIZE == 8 +/* returns true on success, false on failure */ +static inline bool +glue(glue(cpu_cmpxchgo, MEMSUFFIX), _ra)(CPUArchState *env, target_ulong ptr, + uint64_t *old_lo, uint64_t *old_hi, + uint64_t new_lo, uint64_t new_hi, + uintptr_t retaddr) +{ + uint64_t orig_lo, orig_hi; + bool ret = true; + + tcg_cmpxchg_lock(ptr); + orig_lo = glue(glue(cpu_ldq, MEMSUFFIX), _ra)(env, ptr, retaddr); + orig_hi = glue(glue(cpu_ldq, MEMSUFFIX), _ra)(env, ptr + 8, retaddr); + if (orig_lo == *old_lo && orig_hi == *old_hi) { + glue(glue(cpu_stq, MEMSUFFIX), _ra)(env, ptr, new_lo, retaddr); + glue(glue(cpu_stq, MEMSUFFIX), _ra)(env, ptr + 8, new_hi, retaddr); + } else { + *old_lo = orig_lo; + *old_hi = orig_hi; + ret = false; + } + tcg_cmpxchg_unlock(); + return ret; +} +#endif diff --git a/include/exec/cpu_atomic_useronly_template.h b/include/exec/cpu_atomic_useronly_template.h new file mode 100644 index 0000000..c7c0a3e --- /dev/null +++ b/include/exec/cpu_atomic_useronly_template.h @@ -0,0 +1,39 @@ +#include "tcg/tcg.h" + +static inline DATA_TYPE +glue(glue(glue(cpu_cmpxchg, SUFFIX), MEMSUFFIX), + _ra)(CPUArchState *env, target_ulong ptr, DATA_TYPE old, DATA_TYPE new, + uintptr_t ra) +{ + DATA_TYPE *hostaddr = g2h(ptr); + + return atomic_cmpxchg(hostaddr, old, new); +} + +/* define cmpxchgo once ldq and stq have been defined */ +#if DATA_SIZE == 8 +/* returns true on success, false on failure */ +static inline bool +glue(glue(cpu_cmpxchgo, MEMSUFFIX), + _ra)(CPUArchState *env, target_ulong ptr, uint64_t *old_lo, + uint64_t *old_hi, uint64_t new_lo, uint64_t new_hi, uintptr_t retaddr) +{ + uint64_t *hostaddr = g2h(ptr); + uint64_t orig_lo, orig_hi; + bool ret = true; + + tcg_cmpxchg_lock(ptr); + orig_lo = *hostaddr; + orig_hi = *(hostaddr + 1); + if (orig_lo == *old_lo && orig_hi == *old_hi) { + *hostaddr = new_lo; + *(hostaddr + 1) = new_hi; + } else { + *old_lo = orig_lo; + *old_hi = orig_hi; + ret = false; + } + tcg_cmpxchg_unlock(); + return ret; +} +#endif diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h index eaf69a1..2329b66 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -194,6 +194,8 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0); } +#include "exec/cpu_atomic_template.h" + #endif /* !SOFTMMU_CODE_ACCESS */ #undef RES_TYPE diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h index b1378bf..e16f892 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -118,6 +118,8 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, { glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v); } + +#include "exec/cpu_atomic_useronly_template.h" #endif #undef RES_TYPE -- 2.5.0