diff options
author | Edgar E. Iglesias <edgar.iglesias@xilinx.com> | 2020-08-14 14:39:35 +0200 |
---|---|---|
committer | Edgar E. Iglesias <edgar.iglesias@xilinx.com> | 2020-08-24 10:47:27 +0200 |
commit | 071cdc67db6285d1c934099e71f905125baefa1b (patch) | |
tree | 306a5f057531c4a2bcafd8c017e45601d43787f7 /target/microblaze | |
parent | 3f17274491cff2c8bfef74ceeccb037ecbd52705 (diff) |
target/microblaze: swx: Use atomic_cmpxchg
Use atomic_cmpxchg to implement the atomic cmpxchg sequence.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Diffstat (limited to 'target/microblaze')
-rw-r--r-- | target/microblaze/translate.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index c58f334a0f..530c15e5ad 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -1075,14 +1075,16 @@ static void dec_store(DisasContext *dc) swx_skip = gen_new_label(); tcg_gen_brcond_tl(TCG_COND_NE, env_res_addr, addr, swx_skip); - /* Compare the value loaded at lwx with current contents of - the reserved location. - FIXME: This only works for system emulation where we can expect - this compare and the following write to be atomic. For user - emulation we need to add atomicity between threads. */ + /* + * Compare the value loaded at lwx with current contents of + * the reserved location. + */ tval = tcg_temp_new_i32(); - tcg_gen_qemu_ld_i32(tval, addr, cpu_mmu_index(&dc->cpu->env, false), - MO_TEUL); + + tcg_gen_atomic_cmpxchg_i32(tval, addr, env_res_val, + cpu_R[dc->rd], mem_index, + mop); + tcg_gen_brcond_i32(TCG_COND_NE, env_res_val, tval, swx_skip); write_carryi(dc, 0); tcg_temp_free_i32(tval); @@ -1108,7 +1110,10 @@ static void dec_store(DisasContext *dc) break; } } - tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop); + + if (!ex) { + tcg_gen_qemu_st_i32(cpu_R[dc->rd], addr, mem_index, mop); + } /* Verify alignment if needed. */ if (dc->cpu->cfg.unaligned_exceptions && size > 1) { |