diff mbox

[RFC,11/30] target-i386: add atomic helpers

Message ID 1467054136-10430-12-git-send-email-cota@braap.org
State New
Headers show

Commit Message

Emilio Cota June 27, 2016, 7:01 p.m. UTC
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 <cota@braap.org>
---
 target-i386/helper.h     | 34 ++++++++++++++++++++++++++++++++++
 target-i386/mem_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
 target-i386/translate.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 117 insertions(+)

Comments

Richard Henderson June 27, 2016, 8:27 p.m. UTC | #1
On 06/27/2016 12:01 PM, Emilio G. Cota wrote:
> 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 <cota@braap.org>
> ---
>  target-i386/helper.h     | 34 ++++++++++++++++++++++++++++++++++
>  target-i386/mem_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
>  target-i386/translate.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 117 insertions(+)


These are bare wrappers around what you've just added to exec/cpu_ldst*.

(1) Is there any reason these shouldn't go into tcg-runtime.h and tcg-runtime.c 
instead?

(2) If so, is there any good reason to add these to cpu_ldst* instead of *only* 
adding them as helpers to tcg-runtime.c?


r~
Emilio Cota June 27, 2016, 9:39 p.m. UTC | #2
On Mon, Jun 27, 2016 at 13:27:35 -0700, Richard Henderson wrote:
> On 06/27/2016 12:01 PM, Emilio G. Cota wrote:
> >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 <cota@braap.org>
> >---
> > target-i386/helper.h     | 34 ++++++++++++++++++++++++++++++++++
> > target-i386/mem_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
> > target-i386/translate.c  | 45 +++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 117 insertions(+)
> 
> 
> These are bare wrappers around what you've just added to exec/cpu_ldst*.
> 
> (1) Is there any reason these shouldn't go into tcg-runtime.h and
> tcg-runtime.c instead?
> 
> (2) If so, is there any good reason to add these to cpu_ldst* instead of
> *only* adding them as helpers to tcg-runtime.c?

The only reason is my incompetence :-) I didn't know about tcg-runtime.

Thanks,

		Emilio
diff mbox

Patch

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)
 {