diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2019-02-11 16:09:23 +0100 |
---|---|---|
committer | Aleksandar Markovic <amarkovic@wavecomp.com> | 2019-02-14 17:47:28 +0100 |
commit | 33a07fa2db66376e6ee780d4a8b064dc5118cf34 (patch) | |
tree | 67abf3dfc5fb163e7437f697480eeccb489cf536 /linux-user | |
parent | c7c7e1e9a5e3f0a8a1dbff6e4ccfd21c2dc9f845 (diff) |
target/mips: reimplement SC instruction emulation and use cmpxchg
Completely rewrite conditional stores handling. Use cmpxchg.
This eliminates need for separate implementations of SC instruction
emulation for user and system emulation.
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/mips/cpu_loop.c | 73 |
1 files changed, 0 insertions, 73 deletions
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c index d0f62ec9b6..61dc90d51c 100644 --- a/linux-user/mips/cpu_loop.c +++ b/linux-user/mips/cpu_loop.c @@ -392,70 +392,6 @@ static const uint8_t mips_syscall_args[] = { # undef MIPS_SYS # endif /* O32 */ -static int do_store_exclusive(CPUMIPSState *env) -{ - target_ulong addr; - target_ulong page_addr; - target_ulong val; - uint32_t val_wp = 0; - uint32_t llnewval_wp = 0; - int flags; - int segv = 0; - int reg; - int d; - int wp; - - addr = env->lladdr; - page_addr = addr & TARGET_PAGE_MASK; - start_exclusive(); - mmap_lock(); - flags = page_get_flags(page_addr); - if ((flags & PAGE_READ) == 0) { - segv = 1; - } else { - reg = env->llreg & 0x1f; - d = (env->llreg & 0x20) != 0; - wp = (env->llreg & 0x40) != 0; - if (!wp) { - if (d) { - segv = get_user_s64(val, addr); - } else { - segv = get_user_s32(val, addr); - } - } else { - segv = get_user_s32(val, addr); - segv |= get_user_s32(val_wp, addr); - llnewval_wp = env->llnewval_wp; - } - if (!segv) { - if (val != env->llval && val_wp == llnewval_wp) { - env->active_tc.gpr[reg] = 0; - } else { - if (!wp) { - if (d) { - segv = put_user_u64(env->llnewval, addr); - } else { - segv = put_user_u32(env->llnewval, addr); - } - } else { - segv = put_user_u32(env->llnewval, addr); - segv |= put_user_u32(env->llnewval_wp, addr + 4); - } - if (!segv) { - env->active_tc.gpr[reg] = 1; - } - } - } - } - env->lladdr = -1; - if (!segv) { - env->active_tc.PC += 4; - } - mmap_unlock(); - end_exclusive(); - return segv; -} - /* Break codes */ enum { BRK_OVERFLOW = 6, @@ -597,15 +533,6 @@ done_syscall: info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; - case EXCP_SC: - if (do_store_exclusive(env)) { - info.si_signo = TARGET_SIGSEGV; - info.si_errno = 0; - info.si_code = TARGET_SEGV_MAPERR; - info._sifields._sigfault._addr = env->active_tc.PC; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } - break; case EXCP_DSPDIS: info.si_signo = TARGET_SIGILL; info.si_errno = 0; |