Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- accel/tcg/atomic_template.h | 80 +++++++++++++++++++++++++++-- include/accel/tcg/cpu-ldst-common.h | 13 +++-- 2 files changed, 86 insertions(+), 7 deletions(-)
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h index 08a475c10c..ae5203b439 100644 --- a/accel/tcg/atomic_template.h +++ b/accel/tcg/atomic_template.h @@ -100,7 +100,6 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, vaddr addr, return ret; } -#if DATA_SIZE < 16 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) { @@ -108,7 +107,11 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, DATA_SIZE, retaddr); DATA_TYPE ret; +#if DATA_SIZE == 16 + ret = atomic16_xchg(haddr, val); +#else ret = qatomic_xchg__nocheck(haddr, val); +#endif ATOMIC_MMU_CLEANUP; atomic_trace_rmw_post(env, addr, VALUE_LOW(ret), @@ -119,6 +122,39 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, return ret; } +#if DATA_SIZE == 16 +ABI_TYPE ATOMIC_NAME(fetch_and)(CPUArchState *env, vaddr addr, ABI_TYPE val, + MemOpIdx oi, uintptr_t retaddr) +{ + DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, + DATA_SIZE, retaddr); + DATA_TYPE ret = atomic16_fetch_and(haddr, val); + ATOMIC_MMU_CLEANUP; + atomic_trace_rmw_post(env, addr, + VALUE_LOW(ret), + VALUE_HIGH(ret), + VALUE_LOW(val), + VALUE_HIGH(val), + oi); + return ret; +} + +ABI_TYPE ATOMIC_NAME(fetch_or)(CPUArchState *env, vaddr addr, ABI_TYPE val, + MemOpIdx oi, uintptr_t retaddr) +{ + DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, + DATA_SIZE, retaddr); + DATA_TYPE ret = atomic16_fetch_or(haddr, val); + ATOMIC_MMU_CLEANUP; + atomic_trace_rmw_post(env, addr, + VALUE_LOW(ret), + VALUE_HIGH(ret), + VALUE_LOW(val), + VALUE_HIGH(val), + oi); + return ret; +} +#else #define GEN_ATOMIC_HELPER(X) \ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, vaddr addr, \ ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \ @@ -188,7 +224,7 @@ GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new) GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new) #undef GEN_ATOMIC_HELPER_FN -#endif /* DATA SIZE < 16 */ +#endif /* DATA SIZE == 16 */ #undef END @@ -225,7 +261,6 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, vaddr addr, return BSWAP(ret); } -#if DATA_SIZE < 16 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) { @@ -233,7 +268,11 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, DATA_SIZE, retaddr); ABI_TYPE ret; +#if DATA_SIZE == 16 + ret = atomic16_xchg(haddr, BSWAP(val)); +#else ret = qatomic_xchg__nocheck(haddr, BSWAP(val)); +#endif ATOMIC_MMU_CLEANUP; atomic_trace_rmw_post(env, addr, VALUE_LOW(ret), @@ -244,6 +283,39 @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, vaddr addr, ABI_TYPE val, return BSWAP(ret); } +#if DATA_SIZE == 16 +ABI_TYPE ATOMIC_NAME(fetch_and)(CPUArchState *env, vaddr addr, ABI_TYPE val, + MemOpIdx oi, uintptr_t retaddr) +{ + DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, + DATA_SIZE, retaddr); + DATA_TYPE ret = atomic16_fetch_and(haddr, BSWAP(val)); + ATOMIC_MMU_CLEANUP; + atomic_trace_rmw_post(env, addr, + VALUE_LOW(ret), + VALUE_HIGH(ret), + VALUE_LOW(val), + VALUE_HIGH(val), + oi); + return BSWAP(ret); +} + +ABI_TYPE ATOMIC_NAME(fetch_or)(CPUArchState *env, vaddr addr, ABI_TYPE val, + MemOpIdx oi, uintptr_t retaddr) +{ + DATA_TYPE *haddr = atomic_mmu_lookup(env_cpu(env), addr, oi, + DATA_SIZE, retaddr); + DATA_TYPE ret = atomic16_fetch_or(haddr, BSWAP(val)); + ATOMIC_MMU_CLEANUP; + atomic_trace_rmw_post(env, addr, + VALUE_LOW(ret), + VALUE_HIGH(ret), + VALUE_LOW(val), + VALUE_HIGH(val), + oi); + return BSWAP(ret); +} +#else #define GEN_ATOMIC_HELPER(X) \ ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, vaddr addr, \ ABI_TYPE val, MemOpIdx oi, uintptr_t retaddr) \ @@ -317,7 +389,7 @@ GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new) #undef ADD #undef GEN_ATOMIC_HELPER_FN -#endif /* DATA_SIZE < 16 */ +#endif /* DATA_SIZE == 16 */ #undef END #endif /* DATA_SIZE > 1 */ diff --git a/include/accel/tcg/cpu-ldst-common.h b/include/accel/tcg/cpu-ldst-common.h index 8bf17c2fab..17a3250ded 100644 --- a/include/accel/tcg/cpu-ldst-common.h +++ b/include/accel/tcg/cpu-ldst-common.h @@ -100,9 +100,6 @@ GEN_ATOMIC_HELPER_ALL(umax_fetch) GEN_ATOMIC_HELPER_ALL(xchg) -#undef GEN_ATOMIC_HELPER_ALL -#undef GEN_ATOMIC_HELPER - Int128 cpu_atomic_cmpxchgo_le_mmu(CPUArchState *env, vaddr addr, Int128 cmpv, Int128 newv, MemOpIdx oi, uintptr_t retaddr); @@ -110,6 +107,16 @@ Int128 cpu_atomic_cmpxchgo_be_mmu(CPUArchState *env, vaddr addr, Int128 cmpv, Int128 newv, MemOpIdx oi, uintptr_t retaddr); +GEN_ATOMIC_HELPER(xchg, Int128, o_le) +GEN_ATOMIC_HELPER(xchg, Int128, o_be) +GEN_ATOMIC_HELPER(fetch_and, Int128, o_le) +GEN_ATOMIC_HELPER(fetch_and, Int128, o_be) +GEN_ATOMIC_HELPER(fetch_or, Int128, o_le) +GEN_ATOMIC_HELPER(fetch_or, Int128, o_be) + +#undef GEN_ATOMIC_HELPER_ALL +#undef GEN_ATOMIC_HELPER + uint8_t cpu_ldb_code_mmu(CPUArchState *env, vaddr addr, MemOpIdx oi, uintptr_t ra); uint16_t cpu_ldw_code_mmu(CPUArchState *env, vaddr addr, -- 2.43.0