]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 495817 - s390x: Fix disassembly for compare-and-branch/trap insns
authorFlorian Krohm <flo2030@eich-krohm.de>
Wed, 4 Dec 2024 15:53:17 +0000 (16:53 +0100)
committerAndreas Arnez <arnez@linux.ibm.com>
Wed, 4 Dec 2024 16:02:33 +0000 (17:02 +0100)
The insns C[L][G]R[BJ], C[L][G]I[BJ], CL[G]T, and CL[FG]IT are
disassembled incorrectly.  Fix this.

Replace s390_format_RIEv1 with s390_format_R0UU and s390_format_R0IU.
Handling both a signed and unsigned immediate constant field with the same
s390_format_... function does not work.

Add function s390_format_RSY_R0RD for CLT and CLGT.  Those opcodes have
extended mnemonics.  So adjusting the formerly used s390_format_RSY_RURD
wasn't an option as that function is also used for CLM[HY], STCM[HY], and
ICM[HY] which don't have extended mnemonics.

VEX/priv/guest_s390_toIR.c
VEX/priv/s390_disasm.c

index 7f077efd230fa8b72b7e0fefe56491a62ac10d9d..1d889ac32c60cc490428345f1ba3305da854f520 100644 (file)
@@ -141,9 +141,9 @@ typedef enum {
 #define RIE_RRUUU_i3(insn) (((insn) >> 40) & 0xff)
 #define RIE_RRUUU_i4(insn) (((insn) >> 32) & 0xff)
 #define RIE_RRUUU_i5(insn) (((insn) >> 24) & 0xff)
-#define RIEv1_r1(insn) (((insn) >> 52) & 0xf)
-#define RIEv1_i2(insn) (((insn) >> 32) & 0xffff)
-#define RIEv1_m3(insn) (((insn) >> 28) & 0xf)
+#define RIE_R0xU_r1(insn) (((insn) >> 52) & 0xf)
+#define RIE_R0xU_i2(insn) (((insn) >> 32) & 0xffff)
+#define RIE_R0xU_m3(insn) (((insn) >> 28) & 0xf)
 #define RIE_RRPU_r1(insn) (((insn) >> 52) & 0xf)
 #define RIE_RRPU_r2(insn) (((insn) >> 48) & 0xf)
 #define RIE_RRPU_i4(insn) (((insn) >> 32) & 0xffff)
@@ -2796,13 +2796,25 @@ s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
 }
 
 static void
-s390_format_RIEv1(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
-                  UChar r1, UShort i2, UChar m3)
+s390_format_R0UU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
+                 UChar r1, UShort i2, UChar m3)
 {
    const HChar *mnm = irgen(r1, i2, m3);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
-      s390_disasm(ENC4(MNM, GPR, UINT, UINT), mnm, r1, i2, m3);
+      s390_disasm(ENC4(XMNM, GPR, INT, CABM), S390_XMNM_CAB, mnm, m3, r1,
+                  i2, m3);
+}
+
+static void
+s390_format_R0IU(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3),
+                 UChar r1, UShort i2, UChar m3)
+{
+   const HChar *mnm = irgen(r1, i2, m3);
+
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
+      s390_disasm(ENC4(XMNM, GPR, INT, CABM), S390_XMNM_CAB, mnm, m3, r1,
+                  (Int)(Short)i2, m3);
 }
 
 static void
@@ -3333,6 +3345,25 @@ s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
       s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
 }
 
+static void
+s390_format_RSY_R0RD(const HChar *(*irgen)(UChar r1, UChar m3, IRTemp op2addr),
+                     UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
+{
+   const HChar *mnm;
+   IRTemp op2addr = newTemp(Ity_I64);
+   IRTemp d2 = newTemp(Ity_I64);
+
+   assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
+   assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
+          mkU64(0)));
+
+   mnm = irgen(r1, m3, op2addr);
+
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
+      s390_disasm(ENC4(XMNM, GPR, CABM, SDXB), S390_XMNM_CAB, mnm, m3, r1, m3,
+                  dh2, dl2, 0, b2);
+}
+
 static void
 s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
                      UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2)
@@ -22121,7 +22152,7 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RSY_r3(ovl), RSY_b2(ovl),
                                                 RSY_dl2(ovl),
                                                 RSY_dh2(ovl));  goto ok;
-   case 0xeb0000000023ULL: s390_format_RSY_RURD(s390_irgen_CLT, RSY_r1(ovl),
+   case 0xeb0000000023ULL: s390_format_RSY_R0RD(s390_irgen_CLT, RSY_r1(ovl),
                                                 RSY_r3(ovl), RSY_b2(ovl),
                                                 RSY_dl2(ovl),
                                                 RSY_dh2(ovl));  goto ok;
@@ -22134,7 +22165,7 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RSY_r3(ovl), RSY_b2(ovl),
                                                 RSY_dl2(ovl),
                                                 RSY_dh2(ovl));  goto ok;
-   case 0xeb000000002bULL: s390_format_RSY_RURD(s390_irgen_CLGT, RSY_r1(ovl),
+   case 0xeb000000002bULL: s390_format_RSY_R0RD(s390_irgen_CLGT, RSY_r1(ovl),
                                                 RSY_r3(ovl), RSY_b2(ovl),
                                                 RSY_dl2(ovl),
                                                 RSY_dh2(ovl));  goto ok;
@@ -22390,22 +22421,22 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RIE_RRPU_r2(ovl),
                                                 RIE_RRPU_i4(ovl),
                                                 RIE_RRPU_m3(ovl));  goto ok;
-   case 0xec0000000070ULL: s390_format_RIEv1(s390_irgen_CGIT,
-                                             RIEv1_r1(ovl),
-                                             RIEv1_i2(ovl),
-                                             RIEv1_m3(ovl)); goto ok;
-   case 0xec0000000071ULL: s390_format_RIEv1(s390_irgen_CLGIT,
-                                             RIEv1_r1(ovl),
-                                             RIEv1_i2(ovl),
-                                             RIEv1_m3(ovl)); goto ok;
-   case 0xec0000000072ULL: s390_format_RIEv1(s390_irgen_CIT,
-                                             RIEv1_r1(ovl),
-                                             RIEv1_i2(ovl),
-                                             RIEv1_m3(ovl)); goto ok;
-   case 0xec0000000073ULL: s390_format_RIEv1(s390_irgen_CLFIT,
-                                             RIEv1_r1(ovl),
-                                             RIEv1_i2(ovl),
-                                             RIEv1_m3(ovl)); goto ok;
+   case 0xec0000000070ULL: s390_format_R0IU(s390_irgen_CGIT,
+                                            RIE_R0xU_r1(ovl),
+                                            RIE_R0xU_i2(ovl),
+                                            RIE_R0xU_m3(ovl)); goto ok;
+   case 0xec0000000071ULL: s390_format_R0UU(s390_irgen_CLGIT,
+                                            RIE_R0xU_r1(ovl),
+                                            RIE_R0xU_i2(ovl),
+                                            RIE_R0xU_m3(ovl)); goto ok;
+   case 0xec0000000072ULL: s390_format_R0IU(s390_irgen_CIT,
+                                            RIE_R0xU_r1(ovl),
+                                            RIE_R0xU_i2(ovl),
+                                            RIE_R0xU_m3(ovl)); goto ok;
+   case 0xec0000000073ULL: s390_format_R0UU(s390_irgen_CLFIT,
+                                            RIE_R0xU_r1(ovl),
+                                            RIE_R0xU_i2(ovl),
+                                            RIE_R0xU_m3(ovl)); goto ok;
    case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
                                                 RIE_RRPU_r1(ovl),
                                                 RIE_RRPU_r2(ovl),
index 77f7bd7e8b480239370579ac84beb456cf8c92db..b4ff13c23d2ef5e00dff55f0d3202657d0303c82 100644 (file)
@@ -124,8 +124,10 @@ cab_operand(const HChar *base, UInt mask)
       *to = *from;
    }
    /* strcat(buf, suffix); */
-   for (from = suffix[mask >> 1]; *from; ++from, ++to) {
-      *to = *from;
+   if (! (mask & 0x1)) {
+      for (from = suffix[mask >> 1]; *from; ++from, ++to) {
+         *to = *from;
+      }
    }
    *to = '\0';
 
@@ -424,7 +426,7 @@ s390_disasm(UInt command, ...)
          break;
 
       case S390_ARG_INT:
-         p += vex_sprintf(p, "%d", (Int)(va_arg(args, UInt)));
+         p += vex_sprintf(p, "%d", va_arg(args, Int));
          break;
 
       case S390_ARG_PCREL: {
@@ -478,8 +480,8 @@ s390_disasm(UInt command, ...)
       case S390_ARG_CABM: {
          UInt mask;
 
-         mask = va_arg(args, UInt) & 0xE;
-         if (mask == 0 || mask == 14) {
+         mask = va_arg(args, UInt);
+         if (mask == 0 || mask == 14 || (mask & 0x1)) {
             p += vex_sprintf(p, ",%u", mask);
          }
          break;