Commit 2c9adbda authored by Peter Maydell's avatar Peter Maydell
Browse files

ARM: fix ldrexd/strexd

Correct ldrexd and strexd code to always read and write the
high word of the 64-bit value from addr+4.
Also make ldrexd and strexd agree that for a 64 bit value the
address in env->exclusive_addr is that of the low word.

This fixes the issues reported in
https://bugs.launchpad.net/qemu/+bug/670883

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarNathan Froyd <froydnj@codesourcery.com>
parent 49e14940
......@@ -589,7 +589,7 @@ static int do_strex(CPUARMState *env)
}
if (size == 3) {
val = env->regs[(env->exclusive_info >> 12) & 0xf];
segv = put_user_u32(val, addr);
segv = put_user_u32(val, addr + 4);
if (segv) {
env->cp15.c6_data = addr + 4;
goto done;
......
......@@ -5926,8 +5926,10 @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
tcg_gen_mov_i32(cpu_exclusive_val, tmp);
store_reg(s, rt, tmp);
if (size == 3) {
tcg_gen_addi_i32(addr, addr, 4);
tmp = gen_ld32(addr, IS_USER(s));
TCGv tmp2 = new_tmp();
tcg_gen_addi_i32(tmp2, addr, 4);
tmp = gen_ld32(tmp2, IS_USER(s));
dead_tmp(tmp2);
tcg_gen_mov_i32(cpu_exclusive_high, tmp);
store_reg(s, rt2, tmp);
}
......@@ -5987,7 +5989,7 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
if (size == 3) {
TCGv tmp2 = new_tmp();
tcg_gen_addi_i32(tmp2, addr, 4);
tmp = gen_ld32(addr, IS_USER(s));
tmp = gen_ld32(tmp2, IS_USER(s));
dead_tmp(tmp2);
tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
dead_tmp(tmp);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment