Signed-off-by: Emilio G. Cota <c...@braap.org> --- target-arm/helper-a64.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ target-arm/helper-a64.h | 6 ++++++ 2 files changed, 56 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index 41e48a4..f859e8e 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -19,6 +19,8 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" #include "exec/gdbstub.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" @@ -444,3 +446,51 @@ uint64_t HELPER(crc32c_64)(uint64_t acc, uint64_t val, uint32_t bytes) /* Linux crc32c converts the output to one's complement. */ return crc32c(acc, buf, bytes) ^ 0xffffffff; } + +/* returns 0 on success; 1 otherwise */ +#define GEN_CMPXCHG64(SUFFIX) \ +uint64_t \ +HELPER(glue(cmpxchg64, SUFFIX))(CPUARMState *env, uint64_t addr, uint64_t old, \ + uint64_t new) \ +{ \ + uint64_t read; \ + \ + read = glue(glue(glue(cpu_, cmpxchg), SUFFIX), \ + _data_ra)(env, addr, old, new, GETPC()); \ + return read != old; \ +} + +GEN_CMPXCHG64(b) +GEN_CMPXCHG64(w) +GEN_CMPXCHG64(l) +GEN_CMPXCHG64(q) +#undef GEN_CMPXCHG64 + +/* returns 0 on success; 1 otherwise */ +uint64_t +HELPER(paired_cmpxchg64l)(CPUARMState *env, uint64_t addr, uint64_t old_lo, + uint64_t old_hi, uint64_t new_lo, uint64_t new_hi) +{ + uint64_t old, new; + uint64_t read; + + old = old_hi; + old <<= 32; + old |= old_lo; + + new = new_hi; + new <<= 32; + new |= new_lo; + + read = cpu_cmpxchgq_data_ra(env, addr, old, new, GETPC()); + return read != old; +} + +/* returns 0 on success; 1 otherwise */ +uint64_t +HELPER(paired_cmpxchg64q)(CPUARMState *env, uint64_t addr, uint64_t old_lo, + uint64_t old_hi, uint64_t new_lo, uint64_t new_hi) +{ + return !cpu_cmpxchgo_data_ra(env, addr, &old_lo, &old_hi, new_lo, new_hi, + GETPC()); +} diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h index 1d3d10f..e7880cf 100644 --- a/target-arm/helper-a64.h +++ b/target-arm/helper-a64.h @@ -46,3 +46,9 @@ DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, env) DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) +DEF_HELPER_4(cmpxchg64b, i64, env, i64, i64, i64) +DEF_HELPER_4(cmpxchg64w, i64, env, i64, i64, i64) +DEF_HELPER_4(cmpxchg64l, i64, env, i64, i64, i64) +DEF_HELPER_4(cmpxchg64q, i64, env, i64, i64, i64) +DEF_HELPER_6(paired_cmpxchg64l, i64, env, i64, i64, i64, i64, i64) +DEF_HELPER_6(paired_cmpxchg64q, i64, env, i64, i64, i64, i64, i64) -- 2.5.0