]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Slightly optimize AND/OR/XOR with immediates
authorAndreas Arnez <arnez@linux.ibm.com>
Wed, 18 Mar 2026 17:27:44 +0000 (18:27 +0100)
committerAndreas Arnez <arnez@linux.ibm.com>
Wed, 18 Mar 2026 18:35:15 +0000 (19:35 +0100)
In host_s390_defs.c, when generating code for AND, OR, or XOR with a
64-bit immediate value, two instructions are emitted: one for each 32-bit
half of the full 64-bit value.  In cases where the value only affects the
low or the high half of the result, one of these instructions becomes a
no-op.

For these cases, just suppress the effective no-op instructions.

VEX/priv/host_s390_defs.c

index 8ff386cc4ad5ae9e238f6c65e4d13c56d3b99be3..1495b26338514a39c0c8b9d003964e150704ee25 100644 (file)
@@ -7517,17 +7517,35 @@ s390_insn_alu_emit(UChar *buf, const s390_insn *insn)
             return s390_emit_MSGR(buf, dst, R0);
 
             /* Do it in two steps: upper half [0:31] and lower half [32:63] */
-         case S390_ALU_AND:
-            buf  = s390_emit_NIHF(buf, dst, value >> 32);
-            return s390_emit_NILF(buf, dst, value & 0xFFFFFFFF);
+         case S390_ALU_AND: {
+            UInt high = value >> 32;
+            UInt low  = value & 0xffffffff;
+            if (high != 0xffffffff)
+               buf = s390_emit_NIHF(buf, dst, high);
+            if (low != 0xffffffff)
+               buf = s390_emit_NILF(buf, dst, low);
+            return buf;
+         }
 
-         case S390_ALU_OR:
-            buf  = s390_emit_OIHF(buf, dst, value >> 32);
-            return s390_emit_OILF(buf, dst, value & 0xFFFFFFFF);
+         case S390_ALU_OR: {
+            UInt high = value >> 32;
+            UInt low  = value & 0xffffffff;
+            if (high != 0)
+               buf = s390_emit_OIHF(buf, dst, high);
+            if (low != 0)
+               buf = s390_emit_OILF(buf, dst, low);
+            return buf;
+         }
 
-         case S390_ALU_XOR:
-            buf  = s390_emit_XIHF(buf, dst, value >> 32);
-            return s390_emit_XILF(buf, dst, value & 0xFFFFFFFF);
+         case S390_ALU_XOR: {
+            UInt high = value >> 32;
+            UInt low  = value & 0xffffffff;
+            if (high != 0)
+               buf = s390_emit_XIHF(buf, dst, high);
+            if (low != 0)
+               buf = s390_emit_XILF(buf, dst, low);
+            return buf;
+         }
 
             /* No special considerations for long displacement here. Only the six
                least significant bits of VALUE will be taken; all other bits are