https://bugs.kde.org/show_bug.cgi?id=275024

Matt Borgerson <cont...@mborgerson.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |cont...@mborgerson.com

--- Comment #1 from Matt Borgerson <cont...@mborgerson.com> ---
I've rediscovered this problem (at least for cmpxchg) after running some QEMU
differential tests. Here's a patch for recent Valgrind to fix cmpxchg behavior.
I've not tried the other instructions mentioned yet.

>From d289e1032501fb8cf9109b7f11350d8cb326b2e5 Mon Sep 17 00:00:00 2001
From: Matt Borgerson <cont...@mborgerson.com>
Date: Tue, 10 Sep 2024 15:31:58 -0700
Subject: [PATCH] amd64: Fix 32b cmpxchg unmodified register writeback

32b register writes are zero-extended. In case a register should not be
modified by cmpxchg, preserve the entire 64b value.
---
 VEX/priv/guest_amd64_toIR.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c
index 57a8a434b..a55058c2e 100644
--- a/VEX/priv/guest_amd64_toIR.c
+++ b/VEX/priv/guest_amd64_toIR.c
@@ -8615,10 +8615,25 @@ ULong dis_cmpxchg_G_E ( /*OUT*/Bool* ok,
       assign( acc, getIRegRAX(size) );
       setFlags_DEP1_DEP2(Iop_Sub8, acc, dest, ty);
       assign( cond, mk_amd64g_calculate_condition(AMD64CondZ) );
-      assign( dest2, IRExpr_ITE(mkexpr(cond), mkexpr(src), mkexpr(dest)) );
-      assign( acc2,  IRExpr_ITE(mkexpr(cond), mkexpr(acc), mkexpr(dest)) );
-      putIRegRAX(size, mkexpr(acc2));
-      putIRegE(size, pfx, rm, mkexpr(dest2));
+
+      if (size == 4) {
+         /* Preserve upper 32b when register should be unmodified. */
+         IRTemp acc64  = newTemp(Ity_I64);
+         IRTemp dest64 = newTemp(Ity_I64);
+         assign( dest64, IRExpr_ITE(mkexpr(cond),
+                                    unop(Iop_32Uto64, mkexpr(src)),
+                                    getIRegE(8, pfx, rm)) );
+         assign( acc64, IRExpr_ITE(mkexpr(cond),
+                                   getIRegRAX(8),
+                                   unop(Iop_32Uto64, mkexpr(dest))) );
+         putIRegRAX(8, mkexpr(acc64));
+         putIRegE(8, pfx, rm, mkexpr(dest64));
+      } else {
+         assign( dest2, IRExpr_ITE(mkexpr(cond), mkexpr(src), mkexpr(dest)) );
+         assign( acc2,  IRExpr_ITE(mkexpr(cond), mkexpr(acc), mkexpr(dest)) );
+         putIRegRAX(size, mkexpr(acc2));
+         putIRegE(size, pfx, rm, mkexpr(dest2));
+      }
       DIP("cmpxchg%c %s,%s\n", nameISize(size),
                                nameIRegG(size,pfx,rm),
                                nameIRegE(size,pfx,rm) );
-- 
2.43.0

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to