diff options
author | Richard Henderson <rth@twiddle.net> | 2017-09-07 11:50:53 -0700 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2017-12-18 23:29:31 +0100 |
commit | f85da3081d001909929a19e530e69cea0487f00e (patch) | |
tree | 411c4cb169d1d71a319ffb03e9beb16021ae2dae /linux-user | |
parent | 6d56fc6cc372284a4571f09b361a9ccd99318103 (diff) |
target/sh4: Use cmpxchg for movco when parallel_cpus
As for other targets, cmpxchg isn't quite right for ll/sc,
suffering from an ABA race, but is sufficient to implement
portable atomic operations.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-Id: <20170907185057.23421-2-richard.henderson@linaro.org>
[aurel32: fix whitespace]
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/main.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index 2fd2a143ed..71696ed33d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2679,6 +2679,8 @@ void cpu_loop(CPUSH4State *env) target_siginfo_t info; while (1) { + bool arch_interrupt = true; + cpu_exec_start(cs); trapnr = cpu_exec(cs); cpu_exec_end(cs); @@ -2710,13 +2712,14 @@ void cpu_loop(CPUSH4State *env) int sig; sig = gdb_handlesig(cs, TARGET_SIGTRAP); - if (sig) - { + if (sig) { info.si_signo = sig; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } + } else { + arch_interrupt = false; + } } break; case 0xa0: @@ -2727,9 +2730,9 @@ void cpu_loop(CPUSH4State *env) info._sifields._sigfault._addr = env->tea; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; - case EXCP_ATOMIC: cpu_exec_step_atomic(cs); + arch_interrupt = false; break; default: printf ("Unhandled trap: 0x%x\n", trapnr); @@ -2737,6 +2740,14 @@ void cpu_loop(CPUSH4State *env) exit(EXIT_FAILURE); } process_pending_signals (env); + + /* Most of the traps imply an exception or interrupt, which + implies an REI instruction has been executed. Which means + that LDST (aka LOK_ADDR) should be cleared. But there are + a few exceptions for traps internal to QEMU. */ + if (arch_interrupt) { + env->lock_addr = -1; + } } } #endif |