@@ -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)
@@ -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;
@@ -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)
{
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(+)