qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]