[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 06/30] target-i386: emulate LOCK'ed cmpxchg8b/16b usin
From: |
Emilio G. Cota |
Subject: |
[Qemu-devel] [RFC 06/30] target-i386: emulate LOCK'ed cmpxchg8b/16b using cmpxchg helpers |
Date: |
Mon, 27 Jun 2016 15:01:52 -0400 |
For consistency, rename the existing cmpxchg8b/16b helpers by appending
_unlocked
to them, to stress that they are not atomic.
Signed-off-by: Emilio G. Cota <address@hidden>
---
target-i386/helper.h | 2 ++
target-i386/mem_helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++--
target-i386/translate.c | 12 +++++++++--
3 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/target-i386/helper.h b/target-i386/helper.h
index af84836..2bb0d1f 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -78,9 +78,11 @@ DEF_HELPER_4(cmpxchgb, tl, env, tl, tl, tl)
DEF_HELPER_4(cmpxchgw, tl, env, tl, tl, tl)
DEF_HELPER_4(cmpxchgl, tl, env, tl, tl, tl)
DEF_HELPER_2(cmpxchg8b, void, env, tl)
+DEF_HELPER_2(cmpxchg8b_unlocked, void, env, tl)
#ifdef TARGET_X86_64
DEF_HELPER_4(cmpxchgq, tl, env, tl, tl, tl)
DEF_HELPER_2(cmpxchg16b, void, env, tl)
+DEF_HELPER_2(cmpxchg16b_unlocked, void, env, tl)
#endif
DEF_HELPER_1(single_step, void, env)
DEF_HELPER_1(cpuid, void, env)
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 3b17326..b002aba 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -71,7 +71,7 @@ GEN_CMPXCHG_HELPER(cmpxchgq)
#endif
#undef GEN_CMPXCHG_HELPER
-void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
+void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0)
{
uint64_t d;
int eflags;
@@ -92,8 +92,36 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
CC_SRC = eflags;
}
+void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
+{
+ uint64_t d;
+ uint64_t old;
+ uint64_t new;
+ int eflags;
+
+ old = env->regs[R_EDX];
+ old <<= 32;
+ old |= env->regs[R_EAX];
+
+ new = env->regs[R_ECX];
+ new <<= 32;
+ new |= env->regs[R_EBX];
+
+ eflags = cpu_cc_compute_all(env, CC_OP);
+
+ d = cpu_cmpxchgq_data_ra(env, a0, old, new, GETPC());
+ if (d == old) {
+ eflags |= CC_Z;
+ } else {
+ env->regs[R_EDX] = (uint32_t)(d >> 32);
+ env->regs[R_EAX] = (uint32_t)d;
+ eflags &= ~CC_Z;
+ }
+ CC_SRC = eflags;
+}
+
#ifdef TARGET_X86_64
-void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
+void helper_cmpxchg16b_unlocked(CPUX86State *env, target_ulong a0)
{
uint64_t d0, d1;
int eflags;
@@ -118,6 +146,28 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
}
CC_SRC = eflags;
}
+
+void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
+{
+ uint64_t d0 = env->regs[R_EAX];
+ uint64_t d1 = env->regs[R_EDX];
+ int eflags;
+
+ if ((a0 & 0xf) != 0) {
+ raise_exception_ra(env, EXCP0D_GPF, GETPC());
+ }
+ eflags = cpu_cc_compute_all(env, CC_OP);
+
+ if (cpu_cmpxchgo_data_ra(env, a0, &d0, &d1, env->regs[R_EBX],
+ env->regs[R_ECX], GETPC())) {
+ eflags |= CC_Z;
+ } else {
+ env->regs[R_EDX] = d1;
+ env->regs[R_EAX] = d0;
+ eflags &= ~CC_Z;
+ }
+ CC_SRC = eflags;
+}
#endif
void helper_boundw(CPUX86State *env, target_ulong a0, int v)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index fba90e7..9abd82f 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -5166,14 +5166,22 @@ static target_ulong disas_insn(CPUX86State *env,
DisasContext *s,
if (!(s->cpuid_ext_features & CPUID_EXT_CX16))
goto illegal_op;
gen_lea_modrm(env, s, modrm);
- gen_helper_cmpxchg16b(cpu_env, cpu_A0);
+ if (s->prefix & PREFIX_LOCK) {
+ gen_helper_cmpxchg16b(cpu_env, cpu_A0);
+ } else {
+ gen_helper_cmpxchg16b_unlocked(cpu_env, cpu_A0);
+ }
} else
#endif
{
if (!(s->cpuid_features & CPUID_CX8))
goto illegal_op;
gen_lea_modrm(env, s, modrm);
- gen_helper_cmpxchg8b(cpu_env, cpu_A0);
+ if (s->prefix & PREFIX_LOCK) {
+ gen_helper_cmpxchg8b(cpu_env, cpu_A0);
+ } else {
+ gen_helper_cmpxchg8b_unlocked(cpu_env, cpu_A0);
+ }
}
set_cc_op(s, CC_OP_EFLAGS);
break;
--
2.5.0
- Re: [Qemu-devel] [RFC 02/30] tcg: add tcg_cmpxchg_lock, (continued)
- [Qemu-devel] [RFC 12/30] target-i386: emulate LOCK'ed OP instructions using atomic helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 09/30] softmmu: add atomic helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 07/30] atomics: add atomic_xor, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 08/30] atomics: add atomic_op_fetch variants, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 14/30] target-i386: emulate LOCK'ed NOT using atomic helper, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 10/30] cpu_ldst: add cpu_atomic helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 11/30] target-i386: add atomic helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 06/30] target-i386: emulate LOCK'ed cmpxchg8b/16b using cmpxchg helpers,
Emilio G. Cota <=
- [Qemu-devel] [RFC 05/30] target-i386: emulate LOCK'ed cmpxchg using cmpxchg helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 13/30] target-i386: emulate LOCK'ed INC using atomic helper, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 15/30] target-i386: emulate LOCK'ed NEG using cmpxchg helper, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 27/30] target-arm: emulate aarch64's LL/SC using cmpxchg helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 25/30] helper: add DEF_HELPER_6, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 16/30] target-i386: emulate LOCK'ed XADD using atomic helper, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 23/30] target-arm: add atomic_xchg helper, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 22/30] target-arm: emulate LL/SC using cmpxchg helpers, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 29/30] linux-user: remove handling of aarch64's EXCP_STREX, Emilio G. Cota, 2016/06/27
- [Qemu-devel] [RFC 20/30] target-i386: remove helper_lock(), Emilio G. Cota, 2016/06/27