]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 495817 - s390x: Fix disassembly for BC[R], BR[C]L, and BIC
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 15:54:48 +0000 (16:54 +0100)
The disassembly of the conditional branch insns bc, bcr, brl, brcl, and
bic differs from objdump's output.  Some examples:

*** mismatch VEX: |bic 20,0|               vs objdump: |bic      0,20|
*** mismatch VEX: |bic 20(%r6),0|          vs objdump: |bic      0,20(%r6)|
*** mismatch VEX: |bic 20(%r4),0|          vs objdump: |bic      0,20(%r4,%r0)|
*** mismatch VEX: |bih 20(%r12)|           vs objdump: |bih      20(%r12,%r0)|
*** mismatch VEX: |nopr|                   vs objdump: |nopr     %r6|
*** mismatch VEX: |b         12(%r11)|     vs objdump: |b        12(%r11,%r0)|
*** mismatch VEX: |blh       12(%r11)|     vs objdump: |blh      12(%r11,%r0)|
*** mismatch VEX: |brc       0,.+0|        vs objdump: |jnop     c|
*** mismatch VEX: |brcl      0,.+0|        vs objdump: |jgnop    c|

All fixed with this patch.

Note that the issue with the base register sometimes being suppressed
affects various other insns as well.

VEX/priv/s390_disasm.c

index 67b5c2bc3cb8319e7525412177e7562d86d66f59..77f7bd7e8b480239370579ac84beb456cf8c92db 100644 (file)
@@ -219,7 +219,7 @@ bc_operand(UInt m1)
 static const HChar *
 brc_operand(UInt m1)
 {
-   if (m1 == 0)  return "brc";
+   if (m1 == 0)  return "jnop";
    if (m1 == 15) return "j";
 
    return construct_mnemonic("j", "", m1);
@@ -230,7 +230,7 @@ brc_operand(UInt m1)
 static const HChar *
 brcl_operand(UInt m1)
 {
-   if (m1 == 0)  return "brcl";
+   if (m1 == 0)  return "jgnop";
    if (m1 == 15) return "jg";
 
    return construct_mnemonic("jg", "", m1);
@@ -259,11 +259,7 @@ dxb_operand(HChar *p, UInt d, UInt x, UInt b, Bool displacement_is_signed)
       p += vex_sprintf(p, "%u", d);
    }
    if (x != 0) {
-      p += vex_sprintf(p, "(%s", gpr_operand(x));
-      if (b != 0) {
-         p += vex_sprintf(p, ",%s", gpr_operand(b));
-      }
-      p += vex_sprintf(p, ")");
+      p += vex_sprintf(p, "(%s,%s)", gpr_operand(x), gpr_operand(b));
    } else {
       if (b != 0) {
          p += vex_sprintf(p, "(%s)", gpr_operand(b));
@@ -373,8 +369,6 @@ s390_disasm(UInt command, ...)
             mask = va_arg(args, UInt);
             mnm = kind == S390_XMNM_BCR ? bcr_operand(mask) : bc_operand(mask);
             p  += vex_sprintf(p, "%s", mnemonic(mnm));
-            /* mask == 0 is a NOP and has no argument */
-            if (mask == 0) goto done;
             break;
 
          case S390_XMNM_BRC:
@@ -382,12 +376,6 @@ s390_disasm(UInt command, ...)
             mask = va_arg(args, UInt);
             mnm = kind == S390_XMNM_BRC ? brc_operand(mask) : brcl_operand(mask);
             p  += vex_sprintf(p, "%s", mnemonic(mnm));
-
-            /* mask == 0 has no special mnemonic */
-            if (mask == 0) {
-               p += vex_sprintf(p, " 0");
-               separator = ',';
-            }
             break;
 
          case S390_XMNM_CAB:
@@ -409,8 +397,8 @@ s390_disasm(UInt command, ...)
             mask = va_arg(args, UInt);
             if (mask == 0) {
                /* There is no special opcode when mask == 0. */
-               p  += vex_sprintf(p, "bic");
-               mask_suffix = mask;
+               p  += vex_sprintf(p, "%s", mnemonic("bic"));
+               p  += vex_sprintf(p, "%u,", mask);
             } else {
                p  += vex_sprintf(p, "%s", construct_mnemonic("bi", "", mask));
             }