Skip to content

Commit

Permalink
tcg: Reduce serial context atomicity earlier
Browse files Browse the repository at this point in the history
Reduce atomicity while emitting opcodes, instead of later
during code generation.  This ensures that any helper called
also sees the reduced atomicity requirement.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2034
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20231212193542.149117-1-richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Dec 12, 2023
1 parent b5e0d5d commit cbb1455
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
28 changes: 24 additions & 4 deletions tcg/tcg-op-ldst.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ static MemOp tcg_canonicalize_memop(MemOp op, bool is64, bool st)
if (st) {
op &= ~MO_SIGN;
}

/* In serial mode, reduce atomicity. */
if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
op &= ~MO_ATOM_MASK;
op |= MO_ATOM_NONE;
}

return op;
}

Expand Down Expand Up @@ -428,8 +435,7 @@ static bool use_two_i64_for_i128(MemOp mop)
case MO_ATOM_SUBALIGN:
case MO_ATOM_WITHIN16:
case MO_ATOM_WITHIN16_PAIR:
/* In a serialized context, no atomicity is required. */
return !(tcg_ctx->gen_tb->cflags & CF_PARALLEL);
return false;
default:
g_assert_not_reached();
}
Expand Down Expand Up @@ -499,13 +505,20 @@ static void maybe_free_addr64(TCGv_i64 a64)
static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr,
TCGArg idx, MemOp memop)
{
const MemOpIdx orig_oi = make_memop_idx(memop, idx);
MemOpIdx orig_oi;
TCGv_i64 ext_addr = NULL;
TCGOpcode opc;

check_max_alignment(get_alignment_bits(memop));
tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);

/* In serial mode, reduce atomicity. */
if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
memop &= ~MO_ATOM_MASK;
memop |= MO_ATOM_NONE;
}
orig_oi = make_memop_idx(memop, idx);

/* TODO: For now, force 32-bit hosts to use the helper. */
if (TCG_TARGET_HAS_qemu_ldst_i128 && TCG_TARGET_REG_BITS == 64) {
TCGv_i64 lo, hi;
Expand Down Expand Up @@ -608,13 +621,20 @@ void tcg_gen_qemu_ld_i128_chk(TCGv_i128 val, TCGTemp *addr, TCGArg idx,
static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr,
TCGArg idx, MemOp memop)
{
const MemOpIdx orig_oi = make_memop_idx(memop, idx);
MemOpIdx orig_oi;
TCGv_i64 ext_addr = NULL;
TCGOpcode opc;

check_max_alignment(get_alignment_bits(memop));
tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST);

/* In serial mode, reduce atomicity. */
if (!(tcg_ctx->gen_tb->cflags & CF_PARALLEL)) {
memop &= ~MO_ATOM_MASK;
memop |= MO_ATOM_NONE;
}
orig_oi = make_memop_idx(memop, idx);

/* TODO: For now, force 32-bit hosts to use the helper. */

if (TCG_TARGET_HAS_qemu_ldst_i128 && TCG_TARGET_REG_BITS == 64) {
Expand Down
9 changes: 1 addition & 8 deletions tcg/tcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -5440,15 +5440,8 @@ static TCGAtomAlign atom_and_align_for_opc(TCGContext *s, MemOp opc,
MemOp align = get_alignment_bits(opc);
MemOp size = opc & MO_SIZE;
MemOp half = size ? size - 1 : 0;
MemOp atom = opc & MO_ATOM_MASK;
MemOp atmax;
MemOp atom;

/* When serialized, no further atomicity required. */
if (s->gen_tb->cflags & CF_PARALLEL) {
atom = opc & MO_ATOM_MASK;
} else {
atom = MO_ATOM_NONE;
}

switch (atom) {
case MO_ATOM_NONE:
Expand Down

0 comments on commit cbb1455

Please sign in to comment.