From: Florian Krohm Date: Wed, 4 Dec 2024 15:53:17 +0000 (+0100) Subject: Bug 495817 - s390x: Fix disassembly for BC[R], BR[C]L, and BIC X-Git-Tag: VALGRIND_3_25_0~209 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d7e5f4ca5fcea86f4cbcd84494b68317adf2fbdc;p=thirdparty%2Fvalgrind.git Bug 495817 - s390x: Fix disassembly for BC[R], BR[C]L, and BIC 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. --- diff --git a/VEX/priv/s390_disasm.c b/VEX/priv/s390_disasm.c index 67b5c2bc3..77f7bd7e8 100644 --- a/VEX/priv/s390_disasm.c +++ b/VEX/priv/s390_disasm.c @@ -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)); }