[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 11/30] target-i386: add atomic helpers
From: |
Emilio G. Cota |
Subject: |
[Qemu-devel] [RFC 11/30] target-i386: add atomic helpers |
Date: |
Mon, 27 Jun 2016 15:01:57 -0400 |
This patch only adds the helpers. Functions to invoke the helpers
from translated code are generated in subsequent patches.
Signed-off-by: Emilio G. Cota <address@hidden>
---
target-i386/helper.h | 34 ++++++++++++++++++++++++++++++++++
target-i386/mem_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
target-i386/translate.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 117 insertions(+)
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 2bb0d1f..df68204 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -84,6 +84,40 @@ 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
+
+/*
+ * Use glue(foo, glue(bar, baz)) instead of glue(glue(foo, bar), baz),
otherwise
+ * some gcc's (e.g. v4.6.3) can get confused with the surrounding DEF_HELPER.
+ */
+#ifndef TARGET_X86_64
+#define DEF_ATOMIC_ALL(NAME) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, b)), tl, env, tl, tl) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, w)), tl, env, tl, tl) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, l)), tl, env, tl, tl)
+#else /* 64-bit */
+#define DEF_ATOMIC_ALL(NAME) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, b)), tl, env, tl, tl) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, w)), tl, env, tl, tl) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, l)), tl, env, tl, tl) \
+ DEF_HELPER_3(glue(atomic_, glue(NAME, q)), tl, env, tl, tl)
+#endif
+
+DEF_ATOMIC_ALL(fetch_add)
+DEF_ATOMIC_ALL(fetch_and)
+DEF_ATOMIC_ALL(fetch_or)
+DEF_ATOMIC_ALL(fetch_sub)
+DEF_ATOMIC_ALL(fetch_xor)
+
+DEF_ATOMIC_ALL(add_fetch)
+DEF_ATOMIC_ALL(and_fetch)
+DEF_ATOMIC_ALL(or_fetch)
+DEF_ATOMIC_ALL(sub_fetch)
+DEF_ATOMIC_ALL(xor_fetch)
+
+DEF_ATOMIC_ALL(xchg)
+
+#undef DEF_ATOMIC_ALL
+
DEF_HELPER_1(single_step, void, env)
DEF_HELPER_1(cpuid, void, env)
DEF_HELPER_1(rdtsc, void, env)
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index b002aba..13f4f3b 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -170,6 +170,44 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
}
#endif
+#define GEN_ATOMIC_HELPER(NAME) \
+target_ulong \
+glue(helper_atomic_, \
+ NAME)(CPUArchState *env, target_ulong addr, target_ulong val) \
+{ \
+ return glue(glue(cpu_atomic_, NAME), _data_ra)(env, addr, val, GETPC()); \
+}
+
+#ifndef TARGET_X86_64
+#define GEN_ATOMIC_HELPER_ALL(NAME) \
+ GEN_ATOMIC_HELPER(glue(NAME, b)) \
+ GEN_ATOMIC_HELPER(glue(NAME, w)) \
+ GEN_ATOMIC_HELPER(glue(NAME, l))
+#else /* 64-bit */
+#define GEN_ATOMIC_HELPER_ALL(NAME) \
+ GEN_ATOMIC_HELPER(glue(NAME, b)) \
+ GEN_ATOMIC_HELPER(glue(NAME, w)) \
+ GEN_ATOMIC_HELPER(glue(NAME, l)) \
+ GEN_ATOMIC_HELPER(glue(NAME, q))
+#endif /* TARGET_X86_64 */
+
+GEN_ATOMIC_HELPER_ALL(fetch_add)
+GEN_ATOMIC_HELPER_ALL(fetch_and)
+GEN_ATOMIC_HELPER_ALL(fetch_or)
+GEN_ATOMIC_HELPER_ALL(fetch_sub)
+GEN_ATOMIC_HELPER_ALL(fetch_xor)
+
+GEN_ATOMIC_HELPER_ALL(add_fetch)
+GEN_ATOMIC_HELPER_ALL(and_fetch)
+GEN_ATOMIC_HELPER_ALL(or_fetch)
+GEN_ATOMIC_HELPER_ALL(sub_fetch)
+GEN_ATOMIC_HELPER_ALL(xor_fetch)
+
+GEN_ATOMIC_HELPER_ALL(xchg)
+
+#undef GEN_ATOMIC_HELPER
+#undef GEN_ATOMIC_HELPER_ALL
+
void helper_boundw(CPUX86State *env, target_ulong a0, int v)
{
int low, high;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 9abd82f..eead9d7 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1271,6 +1271,51 @@ static void gen_cmpxchg(TCGv ret, TCGv addr, TCGv old,
TCGv new, TCGMemOp ot)
}
}
+#ifndef TARGET_X86_64
+#define GEN_ATOMIC_HELPER(NAME) \
+static void \
+glue(gen_atomic_, NAME)(TCGv ret, TCGv addr, TCGv reg, TCGMemOp ot) \
+{ \
+ switch (ot & 3) { \
+ case 0: \
+ glue(glue(gen_helper_atomic_, NAME), b)(ret, cpu_env, addr, reg); \
+ break; \
+ case 1: \
+ glue(glue(gen_helper_atomic_, NAME), w)(ret, cpu_env, addr, reg); \
+ break; \
+ case 2: \
+ glue(glue(gen_helper_atomic_, NAME), l)(ret, cpu_env, addr, reg); \
+ break; \
+ default: \
+ tcg_abort(); \
+ } \
+}
+#else /* 64-bit */
+#define GEN_ATOMIC_HELPER(NAME) \
+static void \
+glue(gen_atomic_, NAME)(TCGv ret, TCGv addr, TCGv reg, TCGMemOp ot) \
+{ \
+ switch (ot & 3) { \
+ case 0: \
+ glue(glue(gen_helper_atomic_, NAME), b)(ret, cpu_env, addr, reg); \
+ break; \
+ case 1: \
+ glue(glue(gen_helper_atomic_, NAME), w)(ret, cpu_env, addr, reg); \
+ break; \
+ case 2: \
+ glue(glue(gen_helper_atomic_, NAME), l)(ret, cpu_env, addr, reg); \
+ break; \
+ case 3: \
+ glue(glue(gen_helper_atomic_, NAME), q)(ret, cpu_env, addr, reg); \
+ break; \
+ default: \
+ tcg_abort(); \
+ } \
+}
+#endif /* TARGET_X86_64 */
+
+#undef GEN_ATOMIC_HELPER
+
/* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d)
{
--
2.5.0
- [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 <=
- [Qemu-devel] [RFC 06/30] target-i386: emulate LOCK'ed cmpxchg8b/16b using cmpxchg helpers, Emilio G. Cota, 2016/06/27
- [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