From 41706d3e72d651edb03b4a06b02b490bec8a3ddf Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 2 Dec 2025 16:40:52 -0800 Subject: [PATCH 1/6] tcg: Zero extend 32-bit addresses for TCI For native code generation, zero-extending 32-bit addresses for the slow path helpers happens in tcg_out_{ld,st}_helper_args, but there isn't really a slow path for TCI, so that didn't happen. Make the extension for TCI explicit in the opcode stream, much like we already do for plugins and atomic helpers. Cc: qemu-stable@nongnu.org Fixes: 24e46e6c9d9 ("accel/tcg: Widen tcg-ldst.h addresses to uint64_t") Signed-off-by: Richard Henderson --- tcg/tcg-op-ldst.c | 72 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c index 67c15fd4d0..1c0b06dbc7 100644 --- a/tcg/tcg-op-ldst.c +++ b/tcg/tcg-op-ldst.c @@ -135,6 +135,30 @@ static void tcg_gen_req_mo(TCGBar type) } } +static TCGTemp *tci_extend_addr(TCGTemp *addr) +{ +#ifdef CONFIG_TCG_INTERPRETER + /* + * 64-bit interpreter requires 64-bit addresses. + * Compare to the extension performed by tcg_out_{ld,st}_helper_args + * for native code generation. + */ + if (TCG_TARGET_REG_BITS == 64 && tcg_ctx->addr_type == TCG_TYPE_I32) { + TCGv_i64 temp = tcg_temp_ebb_new_i64(); + tcg_gen_extu_i32_i64(temp, temp_tcgv_i32(addr)); + return tcgv_i64_temp(temp); + } +#endif + return addr; +} + +static void maybe_free_addr(TCGTemp *addr, TCGTemp *copy) +{ + if (addr != copy) { + tcg_temp_free_internal(copy); + } +} + /* Only required for loads, where value might overlap addr. */ static TCGv_i64 plugin_maybe_preserve_addr(TCGTemp *addr) { @@ -234,6 +258,7 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr, MemOp orig_memop; MemOpIdx orig_oi, oi; TCGv_i64 copy_addr; + TCGTemp *addr_new; tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); orig_memop = memop = tcg_canonicalize_memop(memop, 0, 0); @@ -248,10 +273,12 @@ static void tcg_gen_qemu_ld_i32_int(TCGv_i32 val, TCGTemp *addr, oi = make_memop_idx(memop, idx); } + addr_new = tci_extend_addr(addr); copy_addr = plugin_maybe_preserve_addr(addr); - gen_ldst1(INDEX_op_qemu_ld, TCG_TYPE_I32, tcgv_i32_temp(val), addr, oi); + gen_ldst1(INDEX_op_qemu_ld, TCG_TYPE_I32, tcgv_i32_temp(val), addr_new, oi); plugin_gen_mem_callbacks_i32(val, copy_addr, addr, orig_oi, QEMU_PLUGIN_MEM_R); + maybe_free_addr(addr, addr_new); if ((orig_memop ^ memop) & MO_BSWAP) { switch (orig_memop & MO_SIZE) { @@ -282,6 +309,7 @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr, { TCGv_i32 swap = NULL; MemOpIdx orig_oi, oi; + TCGTemp *addr_new; tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); memop = tcg_canonicalize_memop(memop, 0, 1); @@ -304,8 +332,10 @@ static void tcg_gen_qemu_st_i32_int(TCGv_i32 val, TCGTemp *addr, oi = make_memop_idx(memop, idx); } - gen_ldst1(INDEX_op_qemu_st, TCG_TYPE_I32, tcgv_i32_temp(val), addr, oi); + addr_new = tci_extend_addr(addr); + gen_ldst1(INDEX_op_qemu_st, TCG_TYPE_I32, tcgv_i32_temp(val), addr_new, oi); plugin_gen_mem_callbacks_i32(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W); + maybe_free_addr(addr, addr_new); if (swap) { tcg_temp_free_i32(swap); @@ -326,6 +356,7 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr, MemOp orig_memop; MemOpIdx orig_oi, oi; TCGv_i64 copy_addr; + TCGTemp *addr_new; if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_ld_i32_int(TCGV_LOW(val), addr, idx, memop); @@ -350,10 +381,12 @@ static void tcg_gen_qemu_ld_i64_int(TCGv_i64 val, TCGTemp *addr, oi = make_memop_idx(memop, idx); } + addr_new = tci_extend_addr(addr); copy_addr = plugin_maybe_preserve_addr(addr); - gen_ld_i64(val, addr, oi); + gen_ld_i64(val, addr_new, oi); plugin_gen_mem_callbacks_i64(val, copy_addr, addr, orig_oi, QEMU_PLUGIN_MEM_R); + maybe_free_addr(addr, addr_new); if ((orig_memop ^ memop) & MO_BSWAP) { int flags = (orig_memop & MO_SIGN @@ -388,6 +421,7 @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr, { TCGv_i64 swap = NULL; MemOpIdx orig_oi, oi; + TCGTemp *addr_new; if (TCG_TARGET_REG_BITS == 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_st_i32_int(TCGV_LOW(val), addr, idx, memop); @@ -418,8 +452,10 @@ static void tcg_gen_qemu_st_i64_int(TCGv_i64 val, TCGTemp *addr, oi = make_memop_idx(memop, idx); } - gen_st_i64(val, addr, oi); + addr_new = tci_extend_addr(addr); + gen_st_i64(val, addr_new, oi); plugin_gen_mem_callbacks_i64(val, NULL, addr, orig_oi, QEMU_PLUGIN_MEM_W); + maybe_free_addr(addr, addr_new); if (swap) { tcg_temp_free_i64(swap); @@ -530,6 +566,7 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr, { MemOpIdx orig_oi; TCGv_i64 ext_addr = NULL; + TCGTemp *addr_new; check_max_alignment(memop_alignment_bits(memop)); tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); @@ -557,8 +594,10 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr, hi = TCGV128_HIGH(val); } + addr_new = tci_extend_addr(addr); gen_ldst2(INDEX_op_qemu_ld2, TCG_TYPE_I128, tcgv_i64_temp(lo), - tcgv_i64_temp(hi), addr, oi); + tcgv_i64_temp(hi), addr_new, oi); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_gen_bswap64_i64(lo, lo); @@ -586,7 +625,9 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr, y = TCGV128_LOW(val); } - gen_ld_i64(x, addr, make_memop_idx(mop[0], idx)); + addr_new = tci_extend_addr(addr); + gen_ld_i64(x, addr_new, make_memop_idx(mop[0], idx)); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_gen_bswap64_i64(x, x); @@ -602,7 +643,9 @@ static void tcg_gen_qemu_ld_i128_int(TCGv_i128 val, TCGTemp *addr, addr_p8 = tcgv_i64_temp(t); } - gen_ld_i64(y, addr_p8, make_memop_idx(mop[1], idx)); + addr_new = tci_extend_addr(addr_p8); + gen_ld_i64(y, addr_new, make_memop_idx(mop[1], idx)); + maybe_free_addr(addr_p8, addr_new); tcg_temp_free_internal(addr_p8); if (need_bswap) { @@ -636,6 +679,7 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr, { MemOpIdx orig_oi; TCGv_i64 ext_addr = NULL; + TCGTemp *addr_new; check_max_alignment(memop_alignment_bits(memop)); tcg_gen_req_mo(TCG_MO_ST_LD | TCG_MO_ST_ST); @@ -666,8 +710,10 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr, hi = TCGV128_HIGH(val); } + addr_new = tci_extend_addr(addr); gen_ldst2(INDEX_op_qemu_st2, TCG_TYPE_I128, - tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr, oi); + tcgv_i64_temp(lo), tcgv_i64_temp(hi), addr_new, oi); + maybe_free_addr(addr, addr_new); if (need_bswap) { tcg_temp_free_i64(lo); @@ -694,7 +740,9 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr, x = b; } - gen_st_i64(x, addr, make_memop_idx(mop[0], idx)); + addr_new = tci_extend_addr(addr); + gen_st_i64(x, addr_new, make_memop_idx(mop[0], idx)); + maybe_free_addr(addr, addr_new); if (tcg_ctx->addr_type == TCG_TYPE_I32) { TCGv_i32 t = tcg_temp_ebb_new_i32(); @@ -706,13 +754,15 @@ static void tcg_gen_qemu_st_i128_int(TCGv_i128 val, TCGTemp *addr, addr_p8 = tcgv_i64_temp(t); } + addr_new = tci_extend_addr(addr_p8); if (b) { tcg_gen_bswap64_i64(b, y); - gen_st_i64(b, addr_p8, make_memop_idx(mop[1], idx)); + gen_st_i64(b, addr_new, make_memop_idx(mop[1], idx)); tcg_temp_free_i64(b); } else { - gen_st_i64(y, addr_p8, make_memop_idx(mop[1], idx)); + gen_st_i64(y, addr_new, make_memop_idx(mop[1], idx)); } + maybe_free_addr(addr_p8, addr_new); tcg_temp_free_internal(addr_p8); } else { if (tcg_ctx->addr_type == TCG_TYPE_I32) { From 92cf74baf4984e87083474f23021a0c6f4719bea Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Dec 2025 14:02:41 -0800 Subject: [PATCH 2/6] tcg/tci: Introduce INDEX_op_tci_qemu_{ld,st}_rrr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since d182123974c4, the number of bits in a MemOpIdx tops out at 17. which won't fit in the TCI rrm format, thus an assertion failure. Introduce new opcodes that take the MemOpIdx from a register, as we already do for qemu_ld2 and qemu_st2. Fixes: d182123974c4 ("include/exec/memopidx: Adjust for 32 mmu indexes") Tested-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/tci.c | 19 +++++++++++++++++++ tcg/tci/tcg-target-opc.h.inc | 2 ++ tcg/tci/tcg-target.c.inc | 14 ++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/tcg/tci.c b/tcg/tci.c index 700e672616..e15d4e8e08 100644 --- a/tcg/tci.c +++ b/tcg/tci.c @@ -794,12 +794,24 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env, taddr = regs[r1]; regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr); break; + case INDEX_op_tci_qemu_ld_rrr: + tci_args_rrr(insn, &r0, &r1, &r2); + taddr = regs[r1]; + oi = regs[r2]; + regs[r0] = tci_qemu_ld(env, taddr, oi, tb_ptr); + break; case INDEX_op_qemu_st: tci_args_rrm(insn, &r0, &r1, &oi); taddr = regs[r1]; tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr); break; + case INDEX_op_tci_qemu_st_rrr: + tci_args_rrr(insn, &r0, &r1, &r2); + taddr = regs[r1]; + oi = regs[r2]; + tci_qemu_st(env, taddr, regs[r0], oi, tb_ptr); + break; case INDEX_op_qemu_ld2: tcg_debug_assert(TCG_TARGET_REG_BITS == 32); @@ -1050,6 +1062,13 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info) op_name, str_r(r0), str_r(r1), oi); break; + case INDEX_op_tci_qemu_ld_rrr: + case INDEX_op_tci_qemu_st_rrr: + tci_args_rrr(insn, &r0, &r1, &r2); + info->fprintf_func(info->stream, "%-12s %s, %s, %s", + op_name, str_r(r0), str_r(r1), str_r(r2)); + break; + case INDEX_op_qemu_ld2: case INDEX_op_qemu_st2: tci_args_rrrr(insn, &r0, &r1, &r2, &r3); diff --git a/tcg/tci/tcg-target-opc.h.inc b/tcg/tci/tcg-target-opc.h.inc index 4eb32ed736..f8bfffc125 100644 --- a/tcg/tci/tcg-target-opc.h.inc +++ b/tcg/tci/tcg-target-opc.h.inc @@ -13,3 +13,5 @@ DEF(tci_rotl32, 1, 2, 0, TCG_OPF_NOT_PRESENT) DEF(tci_rotr32, 1, 2, 0, TCG_OPF_NOT_PRESENT) DEF(tci_setcond32, 1, 2, 1, TCG_OPF_NOT_PRESENT) DEF(tci_movcond32, 1, 2, 1, TCG_OPF_NOT_PRESENT) +DEF(tci_qemu_ld_rrr, 1, 2, 0, TCG_OPF_NOT_PRESENT) +DEF(tci_qemu_st_rrr, 0, 3, 0, TCG_OPF_NOT_PRESENT) diff --git a/tcg/tci/tcg-target.c.inc b/tcg/tci/tcg-target.c.inc index 35c66a4836..532f87262c 100644 --- a/tcg/tci/tcg-target.c.inc +++ b/tcg/tci/tcg-target.c.inc @@ -1188,7 +1188,12 @@ static const TCGOutOpStore outop_st = { static void tgen_qemu_ld(TCGContext *s, TCGType type, TCGReg data, TCGReg addr, MemOpIdx oi) { - tcg_out_op_rrm(s, INDEX_op_qemu_ld, data, addr, oi); + if (oi & ~0xffff) { + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, oi); + tcg_out_op_rrr(s, INDEX_op_tci_qemu_ld_rrr, data, addr, TCG_REG_TMP); + } else { + tcg_out_op_rrm(s, INDEX_op_qemu_ld, data, addr, oi); + } } static const TCGOutOpQemuLdSt outop_qemu_ld = { @@ -1213,7 +1218,12 @@ static const TCGOutOpQemuLdSt2 outop_qemu_ld2 = { static void tgen_qemu_st(TCGContext *s, TCGType type, TCGReg data, TCGReg addr, MemOpIdx oi) { - tcg_out_op_rrm(s, INDEX_op_qemu_st, data, addr, oi); + if (oi & ~0xffff) { + tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP, oi); + tcg_out_op_rrr(s, INDEX_op_tci_qemu_st_rrr, data, addr, TCG_REG_TMP); + } else { + tcg_out_op_rrm(s, INDEX_op_qemu_st, data, addr, oi); + } } static const TCGOutOpQemuLdSt outop_qemu_st = { From 93fa8293442fcb1f297d0ee7c669539cd009cf26 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 2 Dec 2025 07:47:24 -0800 Subject: [PATCH 3/6] tcg: Remove duplicate test from plugin_gen_mem_callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All callers have already tested tcg_ctx->plugin_insn. Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- tcg/tcg-op-ldst.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c index 1c0b06dbc7..7716c3ad7c 100644 --- a/tcg/tcg-op-ldst.c +++ b/tcg/tcg-op-ldst.c @@ -182,23 +182,21 @@ static void plugin_gen_mem_callbacks(TCGv_i64 copy_addr, TCGTemp *orig_addr, MemOpIdx oi, enum qemu_plugin_mem_rw rw) { - if (tcg_ctx->plugin_insn != NULL) { - qemu_plugin_meminfo_t info = make_plugin_meminfo(oi, rw); + qemu_plugin_meminfo_t info = make_plugin_meminfo(oi, rw); - if (tcg_ctx->addr_type == TCG_TYPE_I32) { - if (!copy_addr) { - copy_addr = tcg_temp_ebb_new_i64(); - tcg_gen_extu_i32_i64(copy_addr, temp_tcgv_i32(orig_addr)); - } + if (tcg_ctx->addr_type == TCG_TYPE_I32) { + if (!copy_addr) { + copy_addr = tcg_temp_ebb_new_i64(); + tcg_gen_extu_i32_i64(copy_addr, temp_tcgv_i32(orig_addr)); + } + tcg_gen_plugin_mem_cb(copy_addr, info); + tcg_temp_free_i64(copy_addr); + } else { + if (copy_addr) { tcg_gen_plugin_mem_cb(copy_addr, info); tcg_temp_free_i64(copy_addr); } else { - if (copy_addr) { - tcg_gen_plugin_mem_cb(copy_addr, info); - tcg_temp_free_i64(copy_addr); - } else { - tcg_gen_plugin_mem_cb(temp_tcgv_i64(orig_addr), info); - } + tcg_gen_plugin_mem_cb(temp_tcgv_i64(orig_addr), info); } } } From 8c00f56fcaf60f42474ca277e86c95f55941aa0d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 3 Dec 2025 14:04:21 +0000 Subject: [PATCH 4/6] tcg/tci: Disable -Wundef FFI_GO_CLOSURES warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we build TCI with FFI (commit 22f15579fa1 "tcg: Build ffi data structures for helpers") we get on Darwin: In file included from ../../tcg/tci.c:22: In file included from include/tcg/helper-info.h:13: /Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk/usr/include/ffi/ffi.h:483:5: warning: 'FFI_GO_CLOSURES' is not defined, evaluates to 0 [-Wundef] 483 | #if FFI_GO_CLOSURES | ^ 1 warning generated. This was fixed in upstream libffi in 2023, but not backported to MacOSX. Simply disable the warning locally. Reported-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- include/tcg/helper-info.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/tcg/helper-info.h b/include/tcg/helper-info.h index 909fe73afa..49a27e4eae 100644 --- a/include/tcg/helper-info.h +++ b/include/tcg/helper-info.h @@ -10,7 +10,19 @@ #define TCG_HELPER_INFO_H #ifdef CONFIG_TCG_INTERPRETER +/* + * MacOSX 15 uses an old version of libffi which contains + * #if FFI_GO_CLOSURES + * but does not define that in , included from . + * This was fixed upstream with + * https://github.com/libffi/libffi/commit/c23e9a1c + * We don't care about go closures one way or the other; + * just suppress the warning. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" #include +#pragma GCC diagnostic pop #endif #include "tcg-target-reg-bits.h" From 6833615bfdd7e104fabb7223df50e18dce2d161c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 3 Dec 2025 13:41:45 +0000 Subject: [PATCH 5/6] include/generic/host: Fix atomic128-cas.h.inc for Int128 structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the Int128Alias structure more when we need to convert between Int128 and __int128_t, when Int128 is a struct. Fixes the build on aarch64 host with TCI, which forces the use of the struct. Reported-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- host/include/generic/host/atomic128-cas.h.inc | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/host/include/generic/host/atomic128-cas.h.inc b/host/include/generic/host/atomic128-cas.h.inc index 990162c56f..8bf5f47768 100644 --- a/host/include/generic/host/atomic128-cas.h.inc +++ b/host/include/generic/host/atomic128-cas.h.inc @@ -34,39 +34,45 @@ static inline Int128 ATTRIBUTE_ATOMIC128_OPT atomic16_xchg(Int128 *ptr, Int128 new) { __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16); - Int128 old = *ptr_align; + Int128Alias o, n; - while (!__atomic_compare_exchange_n(ptr_align, &old, new, true, + n.s = new; + o.i = *ptr_align; + while (!__atomic_compare_exchange_n(ptr_align, &o.i, n.i, true, __ATOMIC_SEQ_CST, 0)) { continue; } - return old; + return o.s; } static inline Int128 ATTRIBUTE_ATOMIC128_OPT atomic16_fetch_and(Int128 *ptr, Int128 val) { __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16); - Int128 old = *ptr_align; + Int128Alias o, v; - while (!__atomic_compare_exchange_n(ptr_align, &old, old & val, true, + v.s = val; + o.i = *ptr_align; + while (!__atomic_compare_exchange_n(ptr_align, &o.i, o.i & v.i, true, __ATOMIC_SEQ_CST, 0)) { continue; } - return old; + return o.s; } static inline Int128 ATTRIBUTE_ATOMIC128_OPT atomic16_fetch_or(Int128 *ptr, Int128 val) { __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16); - Int128 old = *ptr_align; + Int128Alias o, v; - while (!__atomic_compare_exchange_n(ptr_align, &old, old | val, true, + v.s = val; + o.i = *ptr_align; + while (!__atomic_compare_exchange_n(ptr_align, &o.i, o.i | v.i, true, __ATOMIC_SEQ_CST, 0)) { continue; } - return old; + return o.s; } # define HAVE_CMPXCHG128 1 #elif defined(CONFIG_CMPXCHG128) From ff633bc5d55a309122d306a83d09a4362de28b65 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 3 Dec 2025 15:19:40 +0000 Subject: [PATCH 6/6] include/aarch64/host: Fix atomic16_fetch_{and,or} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tmp[lh] variables were defined as inputs to the asm rather than outputs, which meant that the compiler rightly diagnosed uninitialized inputs. Reported-by: Philippe Mathieu-Daudé Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Richard Henderson --- host/include/aarch64/host/atomic128-cas.h.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/host/include/aarch64/host/atomic128-cas.h.inc b/host/include/aarch64/host/atomic128-cas.h.inc index aec27df182..52e98a0bdd 100644 --- a/host/include/aarch64/host/atomic128-cas.h.inc +++ b/host/include/aarch64/host/atomic128-cas.h.inc @@ -67,9 +67,9 @@ static inline Int128 atomic16_fetch_and(Int128 *ptr, Int128 new) "stlxp %w[tmp], %[tmpl], %[tmph], %[mem]\n\t" "cbnz %w[tmp], 0b" : [mem] "+m"(*ptr), [tmp] "=&r"(tmp), - [oldl] "=&r"(oldl), [oldh] "=&r"(oldh) - : [newl] "r"(newl), [newh] "r"(newh), - [tmpl] "r"(tmpl), [tmph] "r"(tmph) + [oldl] "=&r"(oldl), [oldh] "=&r"(oldh), + [tmpl] "=&r"(tmpl), [tmph] "=&r"(tmph) + : [newl] "r"(newl), [newh] "r"(newh) : "memory"); return int128_make128(oldl, oldh); @@ -87,9 +87,9 @@ static inline Int128 atomic16_fetch_or(Int128 *ptr, Int128 new) "stlxp %w[tmp], %[tmpl], %[tmph], %[mem]\n\t" "cbnz %w[tmp], 0b" : [mem] "+m"(*ptr), [tmp] "=&r"(tmp), - [oldl] "=&r"(oldl), [oldh] "=&r"(oldh) - : [newl] "r"(newl), [newh] "r"(newh), - [tmpl] "r"(tmpl), [tmph] "r"(tmph) + [oldl] "=&r"(oldl), [oldh] "=&r"(oldh), + [tmpl] "=&r"(tmpl), [tmph] "=&r"(tmph) + : [newl] "r"(newl), [newh] "r"(newh) : "memory"); return int128_make128(oldl, oldh);