summary refs log tree commit diff stats
path: root/linux-user/mips
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2019-02-11 16:09:23 +0100
committerAleksandar Markovic <amarkovic@wavecomp.com>2019-02-14 17:47:28 +0100
commit33a07fa2db66376e6ee780d4a8b064dc5118cf34 (patch)
tree67abf3dfc5fb163e7437f697480eeccb489cf536 /linux-user/mips
parentc7c7e1e9a5e3f0a8a1dbff6e4ccfd21c2dc9f845 (diff)
downloadfocaccia-qemu-33a07fa2db66376e6ee780d4a8b064dc5118cf34.tar.gz
focaccia-qemu-33a07fa2db66376e6ee780d4a8b064dc5118cf34.zip
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/mips')
-rw-r--r--linux-user/mips/cpu_loop.c73
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;