]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Optimize CLC for 1, 2, 4, and 8 bytes
authorAndreas Arnez <arnez@linux.ibm.com>
Fri, 5 May 2023 15:48:31 +0000 (17:48 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Thu, 11 May 2023 14:27:26 +0000 (16:27 +0200)
The CLC instruction compares two memory areas with sizes from 1 up to 256
bytes.  Currently Valgrind always implements it with a bytewise loop.

Add special handling for the sizes 1, 2, 4, and 8.  Realize CLC with an
8-, 16-, 32-, and 64-bit integer comparison, respectively, in those cases.
Apart from a slight optimization this also improves the diagnostics for
uninitialized values since it avoids the manufactured conditional jump
that breaks out of the loop over the individual bytes.

VEX/priv/guest_s390_toIR.c

index 250daeca13bd7ab1419e5afeee7babaccdf8a8eb..39356e088f914c78b0dc36155732908f3e20bbb9 100644 (file)
@@ -12849,11 +12849,28 @@ s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
 static const HChar *
 s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
 {
-   IRTemp len = newTemp(Ity_I64);
-
-   assign(len, mkU64(length));
-   s390_irgen_CLC_EX(len, start1, start2);
+   IRType ty;
+
+   switch (length) {
+   case 0: ty = Ity_I8; break;
+   case 1: ty = Ity_I16; break;
+   case 3: ty = Ity_I32; break;
+   case 7: ty = Ity_I64; break;
+   default: ty = Ity_INVALID;
+   }
+   if (ty != Ity_INVALID) {
+      IRTemp a = newTemp(ty);
+      IRTemp b = newTemp(ty);
+
+      assign(a, load(ty, mkexpr(start1)));
+      assign(b, load(ty, mkexpr(start2)));
+      s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, a, b);
+   } else {
+      IRTemp len = newTemp(Ity_I64);
 
+      assign(len, mkU64(length));
+      s390_irgen_CLC_EX(len, start1, start2);
+   }
    return "clc";
 }