All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, "Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PULL 39/40] target/i386: Inline cmpxchg16b
Date: Sat,  4 Feb 2023 06:33:09 -1000	[thread overview]
Message-ID: <20230204163310.815536-40-richard.henderson@linaro.org> (raw)
In-Reply-To: <20230204163310.815536-1-richard.henderson@linaro.org>

Use tcg_gen_atomic_cmpxchg_i128 for the atomic case,
and tcg_gen_qemu_ld/st_i128 otherwise.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h         |  4 ---
 target/i386/tcg/mem_helper.c | 69 ------------------------------------
 target/i386/tcg/translate.c  | 44 ++++++++++++++++++++---
 3 files changed, 39 insertions(+), 78 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 2df8049f91..e627a93107 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -66,10 +66,6 @@ DEF_HELPER_1(rsm, void, env)
 #endif /* !CONFIG_USER_ONLY */
 
 DEF_HELPER_2(into, void, env, int)
-#ifdef TARGET_X86_64
-DEF_HELPER_2(cmpxchg16b_unlocked, void, env, tl)
-DEF_HELPER_2(cmpxchg16b, void, env, tl)
-#endif
 DEF_HELPER_FLAGS_1(single_step, TCG_CALL_NO_WG, noreturn, env)
 DEF_HELPER_1(rechecking_single_step, void, env)
 DEF_HELPER_1(cpuid, void, env)
diff --git a/target/i386/tcg/mem_helper.c b/target/i386/tcg/mem_helper.c
index 814786bb87..3ef84e90d9 100644
--- a/target/i386/tcg/mem_helper.c
+++ b/target/i386/tcg/mem_helper.c
@@ -27,75 +27,6 @@
 #include "tcg/tcg.h"
 #include "helper-tcg.h"
 
-#ifdef TARGET_X86_64
-void helper_cmpxchg16b_unlocked(CPUX86State *env, target_ulong a0)
-{
-    uintptr_t ra = GETPC();
-    Int128 oldv, cmpv, newv;
-    uint64_t o0, o1;
-    int eflags;
-    bool success;
-
-    if ((a0 & 0xf) != 0) {
-        raise_exception_ra(env, EXCP0D_GPF, GETPC());
-    }
-    eflags = cpu_cc_compute_all(env, CC_OP);
-
-    cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
-    newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]);
-
-    o0 = cpu_ldq_data_ra(env, a0 + 0, ra);
-    o1 = cpu_ldq_data_ra(env, a0 + 8, ra);
-
-    oldv = int128_make128(o0, o1);
-    success = int128_eq(oldv, cmpv);
-    if (!success) {
-        newv = oldv;
-    }
-
-    cpu_stq_data_ra(env, a0 + 0, int128_getlo(newv), ra);
-    cpu_stq_data_ra(env, a0 + 8, int128_gethi(newv), ra);
-
-    if (success) {
-        eflags |= CC_Z;
-    } else {
-        env->regs[R_EAX] = int128_getlo(oldv);
-        env->regs[R_EDX] = int128_gethi(oldv);
-        eflags &= ~CC_Z;
-    }
-    CC_SRC = eflags;
-}
-
-void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
-{
-    uintptr_t ra = GETPC();
-
-    if ((a0 & 0xf) != 0) {
-        raise_exception_ra(env, EXCP0D_GPF, ra);
-    } else if (HAVE_CMPXCHG128) {
-        int eflags = cpu_cc_compute_all(env, CC_OP);
-
-        Int128 cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
-        Int128 newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]);
-
-        int mem_idx = cpu_mmu_index(env, false);
-        MemOpIdx oi = make_memop_idx(MO_TE | MO_128 | MO_ALIGN, mem_idx);
-        Int128 oldv = cpu_atomic_cmpxchgo_le_mmu(env, a0, cmpv, newv, oi, ra);
-
-        if (int128_eq(oldv, cmpv)) {
-            eflags |= CC_Z;
-        } else {
-            env->regs[R_EAX] = int128_getlo(oldv);
-            env->regs[R_EDX] = int128_gethi(oldv);
-            eflags &= ~CC_Z;
-        }
-        CC_SRC = eflags;
-    } else {
-        cpu_loop_exit_atomic(env_cpu(env), ra);
-    }
-}
-#endif
-
 void helper_boundw(CPUX86State *env, target_ulong a0, int v)
 {
     int low, high;
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index b542b084a6..9d9392b009 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -3053,15 +3053,49 @@ static void gen_cmpxchg8b(DisasContext *s, CPUX86State *env, int modrm)
 #ifdef TARGET_X86_64
 static void gen_cmpxchg16b(DisasContext *s, CPUX86State *env, int modrm)
 {
+    MemOp mop = MO_TE | MO_128 | MO_ALIGN;
+    TCGv_i64 t0, t1;
+    TCGv_i128 cmp, val;
+
     gen_lea_modrm(env, s, modrm);
 
-    if ((s->prefix & PREFIX_LOCK) &&
-        (tb_cflags(s->base.tb) & CF_PARALLEL)) {
-        gen_helper_cmpxchg16b(cpu_env, s->A0);
+    cmp = tcg_temp_new_i128();
+    val = tcg_temp_new_i128();
+    tcg_gen_concat_i64_i128(cmp, cpu_regs[R_EAX], cpu_regs[R_EDX]);
+    tcg_gen_concat_i64_i128(val, cpu_regs[R_EBX], cpu_regs[R_ECX]);
+
+    /* Only require atomic with LOCK; non-parallel handled in generator. */
+    if (s->prefix & PREFIX_LOCK) {
+        tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
     } else {
-        gen_helper_cmpxchg16b_unlocked(cpu_env, s->A0);
+        tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
     }
-    set_cc_op(s, CC_OP_EFLAGS);
+
+    tcg_gen_extr_i128_i64(s->T0, s->T1, val);
+    tcg_temp_free_i128(cmp);
+    tcg_temp_free_i128(val);
+
+    /* Determine success after the fact. */
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+    tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]);
+    tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]);
+    tcg_gen_or_i64(t0, t0, t1);
+    tcg_temp_free_i64(t1);
+
+    /* Update Z. */
+    gen_compute_eflags(s);
+    tcg_gen_setcondi_i64(TCG_COND_EQ, t0, t0, 0);
+    tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, t0, ctz32(CC_Z), 1);
+    tcg_temp_free_i64(t0);
+
+    /*
+     * Extract the result values for the register pair.  We may do this
+     * unconditionally, because on success (Z=1), the old value matches
+     * the previous value in RDX:RAX.
+     */
+    tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0);
+    tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1);
 }
 #endif
 
-- 
2.34.1



  parent reply	other threads:[~2023-02-04 16:37 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-04 16:32 [PULL 00/40] tcg patch queue Richard Henderson
2023-02-04 16:32 ` [PULL 01/40] accel/tcg: Test CPUJumpCache in tb_jmp_cache_clear_page Richard Henderson
2023-02-04 16:32 ` [PULL 02/40] tcg: Init temp_subindex in liveness_pass_2 Richard Henderson
2023-02-04 16:32 ` [PULL 03/40] tcg: Define TCG_TYPE_I128 and related helper macros Richard Henderson
2023-02-04 16:32 ` [PULL 04/40] tcg: Handle dh_typecode_i128 with TCG_CALL_{RET, ARG}_NORMAL Richard Henderson
2023-02-04 16:32 ` [PULL 05/40] tcg: Allocate objects contiguously in temp_allocate_frame Richard Henderson
2023-02-04 16:32 ` [PULL 06/40] tcg: Introduce tcg_out_addi_ptr Richard Henderson
2023-02-04 16:32 ` [PULL 07/40] tcg: Add TCG_CALL_{RET,ARG}_BY_REF Richard Henderson
2023-02-04 16:32 ` [PULL 08/40] tcg: Introduce tcg_target_call_oarg_reg Richard Henderson
2023-02-04 16:32 ` [PULL 09/40] tcg: Add TCG_CALL_RET_BY_VEC Richard Henderson
2023-02-04 16:32 ` [PULL 10/40] include/qemu/int128: Use Int128 structure for TCI Richard Henderson
2023-02-04 16:32 ` [PULL 11/40] tcg/i386: Add TCG_TARGET_CALL_{RET,ARG}_I128 Richard Henderson
2023-02-04 16:32 ` [PULL 12/40] tcg/tci: Fix big-endian return register ordering Richard Henderson
2023-02-04 16:32 ` [PULL 13/40] tcg/tci: Add TCG_TARGET_CALL_{RET,ARG}_I128 Richard Henderson
2023-02-04 16:32 ` [PULL 14/40] tcg: " Richard Henderson
2023-02-04 16:32 ` [PULL 15/40] tcg: Add temp allocation for TCGv_i128 Richard Henderson
2023-02-04 16:32 ` [PULL 16/40] tcg: Add basic data movement " Richard Henderson
2023-02-04 16:32 ` [PULL 17/40] tcg: Add guest load/store primitives " Richard Henderson
2023-02-04 16:32 ` [PULL 18/40] tcg: Add tcg_gen_{non}atomic_cmpxchg_i128 Richard Henderson
2023-02-04 16:32 ` [PULL 19/40] tcg: Split out tcg_gen_nonatomic_cmpxchg_i{32,64} Richard Henderson
2023-02-04 16:32 ` [PULL 20/40] target/arm: Use tcg_gen_atomic_cmpxchg_i128 for STXP Richard Henderson
2023-02-04 16:32 ` [PULL 21/40] target/arm: Use tcg_gen_atomic_cmpxchg_i128 for CASP Richard Henderson
2023-02-04 16:32 ` [PULL 22/40] target/ppc: Use tcg_gen_atomic_cmpxchg_i128 for STQCX Richard Henderson
2023-02-04 16:32 ` [PULL 23/40] tests/tcg/s390x: Add div.c Richard Henderson
2023-02-04 16:32 ` [PULL 24/40] tests/tcg/s390x: Add clst.c Richard Henderson
2023-02-04 16:32 ` [PULL 25/40] tests/tcg/s390x: Add long-double.c Richard Henderson
2023-02-04 16:32 ` [PULL 26/40] tests/tcg/s390x: Add cdsg.c Richard Henderson
2023-02-04 16:32 ` [PULL 27/40] target/s390x: Use a single return for helper_divs32/u32 Richard Henderson
2023-02-04 16:32 ` [PULL 28/40] target/s390x: Use a single return for helper_divs64/u64 Richard Henderson
2023-02-04 16:32 ` [PULL 29/40] target/s390x: Use Int128 for return from CLST Richard Henderson
2023-02-04 16:33 ` [PULL 30/40] target/s390x: Use Int128 for return from CKSM Richard Henderson
2023-02-04 16:33 ` [PULL 31/40] target/s390x: Use Int128 for return from TRE Richard Henderson
2023-02-04 16:33 ` [PULL 32/40] target/s390x: Copy wout_x1 to wout_x1_P Richard Henderson
2023-02-04 16:33 ` [PULL 33/40] target/s390x: Use Int128 for returning float128 Richard Henderson
2023-02-04 16:33 ` [PULL 34/40] target/s390x: Use Int128 for passing float128 Richard Henderson
2023-02-04 16:33 ` [PULL 35/40] target/s390x: Use tcg_gen_atomic_cmpxchg_i128 for CDSG Richard Henderson
2023-02-04 16:33 ` [PULL 36/40] target/s390x: Implement CC_OP_NZ in gen_op_calc_cc Richard Henderson
2023-02-04 16:33 ` [PULL 37/40] target/i386: Split out gen_cmpxchg8b, gen_cmpxchg16b Richard Henderson
2023-02-04 16:33 ` [PULL 38/40] target/i386: Inline cmpxchg8b Richard Henderson
2023-02-04 16:33 ` Richard Henderson [this message]
2023-02-04 16:33 ` [PULL 40/40] tcg/aarch64: Fix patching of LDR in tb_target_set_jmp_target Richard Henderson
2023-02-05 16:48 ` [PULL 00/40] tcg patch queue Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230204163310.815536-40-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.