diff options
author | Richard Henderson <rth@twiddle.net> | 2016-06-29 21:10:59 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-10-26 08:29:01 -0700 |
commit | 7ebee43ee3e2fcd7b5063058b7ef74bc43216733 (patch) | |
tree | 366db1d66ff70d8332b6fb38b07085a0f79c6293 /atomic_template.h | |
parent | c482cb117cc418115ca9c6d21a7a2315414c0a40 (diff) |
tcg: Add atomic128 helpers
Force the use of cmpxchg16b on x86_64.
Wikipedia suggests that only very old AMD64 (circa 2004) did not have
this instruction. Further, it's required by Windows 8 so no new cpus
will ever omit it.
If we truely care about these, then we could check this at startup time
and then avoid executing paths that use it.
Reviewed-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'atomic_template.h')
-rw-r--r-- | atomic_template.h | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/atomic_template.h b/atomic_template.h index cf83725403..b400b2a3d3 100644 --- a/atomic_template.h +++ b/atomic_template.h @@ -18,7 +18,11 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#if DATA_SIZE == 8 +#if DATA_SIZE == 16 +# define SUFFIX o +# define DATA_TYPE Int128 +# define BSWAP bswap128 +#elif DATA_SIZE == 8 # define SUFFIX q # define DATA_TYPE uint64_t # define BSWAP bswap64 @@ -61,6 +65,21 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, return atomic_cmpxchg__nocheck(haddr, cmpv, newv); } +#if DATA_SIZE >= 16 +ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS) +{ + DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP; + __atomic_load(haddr, &val, __ATOMIC_RELAXED); + return val; +} + +void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, + ABI_TYPE val EXTRA_ARGS) +{ + DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; + __atomic_store(haddr, &val, __ATOMIC_RELAXED); +} +#else ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val EXTRA_ARGS) { @@ -86,6 +105,8 @@ GEN_ATOMIC_HELPER(or_fetch) GEN_ATOMIC_HELPER(xor_fetch) #undef GEN_ATOMIC_HELPER +#endif /* DATA SIZE >= 16 */ + #undef END #if DATA_SIZE > 1 @@ -105,6 +126,22 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr, return BSWAP(atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv))); } +#if DATA_SIZE >= 16 +ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS) +{ + DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP; + __atomic_load(haddr, &val, __ATOMIC_RELAXED); + return BSWAP(val); +} + +void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr, + ABI_TYPE val EXTRA_ARGS) +{ + DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; + val = BSWAP(val); + __atomic_store(haddr, &val, __ATOMIC_RELAXED); +} +#else ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr, ABI_TYPE val EXTRA_ARGS) { @@ -166,6 +203,7 @@ ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr, ldo = ldn; } } +#endif /* DATA_SIZE >= 16 */ #undef END #endif /* DATA_SIZE > 1 */ |