]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Fix disassembly for BFP/DFP conversion opcodes (BZ 495817)
authorFlorian Krohm <flo2030@eich-krohm.de>
Sat, 29 Mar 2025 22:54:53 +0000 (22:54 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Sat, 29 Mar 2025 22:54:53 +0000 (22:54 +0000)
Specifically:
- BFP convert from/to fixed
- BFP convert from/to logical
- DFP convert from/to fixed
- DFP convert from/to logical

Change function names from e.g. s390_irgen/emit_CEFBR to
s390_irgen/emit_CEFBRA because CFEBR does not have m3 and m4 operands.
Adjust the returned mnemonic accordingly.

New functions fp_convf_disasm and fp_convt_disasm.

Part of fixing https://bugs.kde.org/show_bug.cgi?id=495817

VEX/priv/guest_s390_toIR.c
VEX/priv/host_s390_defs.c
VEX/priv/s390_disasm.c
VEX/priv/s390_disasm.h

index 1ed10acbbb82182b75715e20cf686a31cfe1b7b1..7b029623d63eecac415aba617315b3393480be6d 100644 (file)
@@ -3115,7 +3115,7 @@ s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
    const HChar *mnm = irgen(m3, m4, r1, r2);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
-      S390_DISASM(MNM(mnm), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM(mnm, fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 }
 
 static void
@@ -3126,7 +3126,7 @@ s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
    const HChar *mnm = irgen(m3, m4, r1, r2);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
-      S390_DISASM(MNM(mnm), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM(mnm, fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 }
 
 
@@ -11394,8 +11394,8 @@ s390_irgen_ADB(UChar r1, IRTemp op2addr)
 }
 
 static const HChar *
-s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CEFBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
       emulation_warning(EmWarn_S390X_fpext_rounding);
@@ -11407,24 +11407,24 @@ s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
    put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
                         mkexpr(op2)));
 
-   return "cefbr";
+   return "cefbra";
 }
 
 static const HChar *
-s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
-                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+s390_irgen_CDFBRA(UChar m3 __attribute__((unused)),
+                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I32);
 
    assign(op2, get_gpr_w1(r2));
    put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
 
-   return "cdfbr";
+   return "cdfbra";
 }
 
 static const HChar *
-s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CEGBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
       emulation_warning(EmWarn_S390X_fpext_rounding);
@@ -11436,12 +11436,12 @@ s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
    put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
                         mkexpr(op2)));
 
-   return "cegbr";
+   return "cegbra";
 }
 
 static const HChar *
-s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CDGBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
       emulation_warning(EmWarn_S390X_fpext_rounding);
@@ -11453,7 +11453,7 @@ s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
    put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
                          mkexpr(op2)));
 
-   return "cdgbr";
+   return "cdgbra";
 }
 
 static const HChar *
@@ -11601,8 +11601,8 @@ s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
 }
 
 static const HChar *
-s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CFEBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F32);
    IRTemp result = newTemp(Ity_I32);
@@ -11614,12 +11614,12 @@ s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
 
-   return "cfebr";
+   return "cfebra";
 }
 
 static const HChar *
-s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CFDBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F64);
    IRTemp result = newTemp(Ity_I32);
@@ -11631,12 +11631,12 @@ s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
 
-   return "cfdbr";
+   return "cfdbra";
 }
 
 static const HChar *
-s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CGEBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F32);
    IRTemp result = newTemp(Ity_I64);
@@ -11648,12 +11648,12 @@ s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
 
-   return "cgebr";
+   return "cgebra";
 }
 
 static const HChar *
-s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CGDBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F64);
    IRTemp result = newTemp(Ity_I64);
@@ -11665,7 +11665,7 @@ s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
 
-   return "cgdbr";
+   return "cgdbra";
 }
 
 static const HChar *
@@ -12111,12 +12111,12 @@ s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
       put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
                             mkexpr(op2)));
    }
-   return (m3 == 0) ? "cdgtr" : "cdgtra";
+   return "cdgtra";
 }
 
 static const HChar *
-s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
-                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+s390_irgen_CXGTRA(UChar m3 __attribute__((unused)),
+                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    if (! s390_host_has_dfp) {
       emulation_failure(EmFail_S390X_DFP_insn);
@@ -12129,7 +12129,7 @@ s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
       assign(op2, get_gpr_dw0(r2));
       put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
    }
-   return "cxgtr";
+   return "cxgtra";
 }
 
 static const HChar *
@@ -12236,7 +12236,7 @@ s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
 
 static const HChar *
 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_dfp) {
       emulation_failure(EmFail_S390X_DFP_insn);
@@ -12260,8 +12260,8 @@ s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
 }
 
 static const HChar *
-s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CGDTRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_dfp) {
       emulation_failure(EmFail_S390X_DFP_insn);
@@ -12280,12 +12280,12 @@ s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
       put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
       s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
    }
-   return "cgdtr";
+   return "cgdtra";
 }
 
 static const HChar *
-s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CGXTRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    if (! s390_host_has_dfp) {
       emulation_failure(EmFail_S390X_DFP_insn);
@@ -12303,7 +12303,7 @@ s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
       put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
       s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
    }
-   return "cgxtr";
+   return "cgxtra";
 }
 
 static const HChar *
@@ -14643,15 +14643,15 @@ s390_irgen_KDB(UChar r1, IRTemp op2addr)
 }
 
 static const HChar *
-s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
-                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+s390_irgen_CXFBRA(UChar m3 __attribute__((unused)),
+                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I32);
 
    assign(op2, get_gpr_w1(r2));
    put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
 
-   return "cxfbr";
+   return "cxfbra";
 }
 
 static const HChar *
@@ -14671,15 +14671,15 @@ s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
 
 
 static const HChar *
-s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
-                 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
+s390_irgen_CXGBRA(UChar m3 __attribute__((unused)),
+                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
    IRTemp op2 = newTemp(Ity_I64);
 
    assign(op2, get_gpr_dw0(r2));
    put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
 
-   return "cxgbr";
+   return "cxgbra";
 }
 
 static const HChar *
@@ -14698,8 +14698,8 @@ s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
 }
 
 static const HChar *
-s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CFXBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F128);
    IRTemp result = newTemp(Ity_I32);
@@ -14711,7 +14711,7 @@ s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_w1(r1, mkexpr(result));
    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
 
-   return "cfxbr";
+   return "cfxbra";
 }
 
 static const HChar *
@@ -14736,8 +14736,8 @@ s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
 
 
 static const HChar *
-s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
-                 UChar r1, UChar r2)
+s390_irgen_CGXBRA(UChar m3, UChar m4 __attribute__((unused)),
+                  UChar r1, UChar r2)
 {
    IRTemp op = newTemp(Ity_F128);
    IRTemp result = newTemp(Ity_I64);
@@ -14749,7 +14749,7 @@ s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
    put_gpr_dw0(r1, mkexpr(result));
    s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
 
-   return "cgxbr";
+   return "cgxbra";
 }
 
 static const HChar *
@@ -20816,22 +20816,22 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, RRF2_m3(ovl),
+   case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, RRF2_m3(ovl),
+   case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, RRF2_m3(ovl),
+   case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, RRF2_m3(ovl),
+   case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, RRF2_m3(ovl),
+   case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, RRF2_m3(ovl),
+   case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
    case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, RRF2_m3(ovl),
@@ -20852,22 +20852,22 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, RRF2_m3(ovl),
+   case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, RRF2_m3(ovl),
+   case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, RRF2_m3(ovl),
+   case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, RRF2_m3(ovl),
+   case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, RRF2_m3(ovl),
+   case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
-   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, RRF2_m3(ovl),
+   case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
    case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, RRF2_m3(ovl),
@@ -20936,7 +20936,7 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
                                    RRE_r2(ovl));  goto ok;
    case 0xb3df: /* FIXTR */ goto unimplemented;
    case 0xb3e0: /* KDTR */ goto unimplemented;
-   case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, RRF2_m3(ovl),
+   case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
    case 0xb3e2: /* CUDTR */ goto unimplemented;
@@ -20948,7 +20948,7 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, RRE_r1(ovl),
                                    RRE_r2(ovl));  goto ok;
    case 0xb3e8: /* KXTR */ goto unimplemented;
-   case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, RRF2_m3(ovl),
+   case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
    case 0xb3ea: /* CUXTR */ goto unimplemented;
@@ -20974,7 +20974,7 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, RRF4_r3(ovl),
                                      RRF4_m4(ovl), RRF4_r1(ovl),
                                      RRF4_r2(ovl)); goto ok;
-   case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, RRF2_m3(ovl),
+   case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTRA, RRF2_m3(ovl),
                                      RRF2_m4(ovl), RRF2_r1(ovl),
                                      RRF2_r2(ovl));  goto ok;
    case 0xb3fa: /* CXUTR */ goto unimplemented;
index 37b4b5baa3e2a5d4ca659b6eb3e770da69104051..684d1735886c6ed01d39541f489bb351e99971b6 100644 (file)
@@ -3939,12 +3939,8 @@ s390_emit_CEFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cefbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cefbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cefbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3940000, m3, m4, r1, r2);
 }
@@ -3956,12 +3952,8 @@ s390_emit_CDFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cdfbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cdfbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cdfbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3950000, m3, m4, r1, r2);
 }
@@ -3973,12 +3965,8 @@ s390_emit_CXFBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cxfbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cxfbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cxfbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3960000, m3, m4, r1, r2);
 }
@@ -3990,12 +3978,8 @@ s390_emit_CEGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cegbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cegbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cegbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a40000, m3, m4, r1, r2);
 }
@@ -4007,12 +3991,8 @@ s390_emit_CDGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cdgbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cdgbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cdgbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a50000, m3, m4, r1, r2);
 }
@@ -4024,12 +4004,8 @@ s390_emit_CXGBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cxgbr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cxgbra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cxgbra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a60000, m3, m4, r1, r2);
 }
@@ -4042,7 +4018,7 @@ s390_emit_CELFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("celfbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("celfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3900000, m3, m4, r1, r2);
 }
@@ -4055,7 +4031,7 @@ s390_emit_CDLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cdlfbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cdlfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3910000, m3, m4, r1, r2);
 }
@@ -4068,7 +4044,7 @@ s390_emit_CXLFBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxlfbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cxlfbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3920000, m3, m4, r1, r2);
 }
@@ -4081,7 +4057,7 @@ s390_emit_CELGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("celgbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("celgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a00000, m3, m4, r1, r2);
 }
@@ -4094,7 +4070,7 @@ s390_emit_CDLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cdlgbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cdlgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a10000, m3, m4, r1, r2);
 }
@@ -4107,7 +4083,7 @@ s390_emit_CXLGBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxlgbr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cxlgbr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3a20000, m3, m4, r1, r2);
 }
@@ -4120,7 +4096,7 @@ s390_emit_CLFEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clfebr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clfebr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb39c0000, m3, m4, r1, r2);
 }
@@ -4133,7 +4109,7 @@ s390_emit_CLFDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clfdbr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clfdbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb39d0000, m3, m4, r1, r2);
 }
@@ -4146,7 +4122,7 @@ s390_emit_CLFXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clfxbr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clfxbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb39e0000, m3, m4, r1, r2);
 }
@@ -4159,7 +4135,7 @@ s390_emit_CLGEBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clgebr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clgebr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3ac0000, m3, m4, r1, r2);
 }
@@ -4172,7 +4148,7 @@ s390_emit_CLGDBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clgdbr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clgdbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3ad0000, m3, m4, r1, r2);
 }
@@ -4185,67 +4161,67 @@ s390_emit_CLGXBR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clgxbr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clgxbr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3ae0000, m3, m4, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CFEBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CFEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cfebr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cfebra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb3980000, m3, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CFDBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CFDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cfdbr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cfdbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb3990000, m3, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CFXBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CFXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cfxbr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cfxbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb39a0000, m3, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CGEBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CGEBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cgebr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cgebra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb3a80000, m3, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CGDBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CGDBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cgdbr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cgdbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb3a90000, m3, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CGXBR(UChar *p, UChar m3, UChar r1, UChar r2)
+s390_emit_CGXBRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cgxbr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cgxbra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF3(p, 0xb3aa0000, m3, r1, r2);
 }
@@ -4691,19 +4667,15 @@ s390_emit_CDGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m4 == 0);
    vassert(m3 == 0 || s390_host_has_fpext);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
-      if (m3 == 0)
-         S390_DISASM(MNM("cdgtr"), FPR(r1), GPR(r2));
-      else
-         S390_DISASM(MNM("cdgtra"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
-   }
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      S390_DISASM(XMNM("cdgtra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3f10000, m3, m4, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CXGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+s390_emit_CXGTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    vassert(s390_host_has_dfp);
    vassert(m4 == 0);
@@ -4712,7 +4684,7 @@ s390_emit_CXGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(m3 == 0);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxgtr"), FPR(r1), GPR(r2));
+      S390_DISASM(XMNM("cxgtra", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3f90000, m3, m4, r1, r2);
 }
@@ -4726,7 +4698,7 @@ s390_emit_CDFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cdftr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cdftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9510000, m3, m4, r1, r2);
 }
@@ -4740,7 +4712,7 @@ s390_emit_CXFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxftr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cxftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9590000, m3, m4, r1, r2);
 }
@@ -4754,7 +4726,7 @@ s390_emit_CDLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cdlftr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cdlftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9530000, m3, m4, r1, r2);
 }
@@ -4768,7 +4740,7 @@ s390_emit_CXLFTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxlftr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cxlftr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb95b0000, m3, m4, r1, r2);
 }
@@ -4782,7 +4754,7 @@ s390_emit_CDLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cdlgtr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cdlgtr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9520000, m3, m4, r1, r2);
 }
@@ -4796,7 +4768,7 @@ s390_emit_CXLGTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cxlgtr"), FPR(r1), UINT(m3), GPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cxlgtr", fp_convf_disasm), FPR(r1), MASK(m3), GPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb95a0000, m3, m4, r1, r2);
 }
@@ -4830,7 +4802,7 @@ s390_emit_CFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cfdtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cfdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9410000, m3, m4, r1, r2);
 }
@@ -4844,35 +4816,35 @@ s390_emit_CFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cfxtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("cfxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9490000, m3, m4, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+s390_emit_CGDTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    vassert(s390_host_has_dfp);
    vassert(m4 == 0);
    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cgdtr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cgdtra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3e10000, m3, m4, r1, r2);
 }
 
 
 static UChar *
-s390_emit_CGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
+s390_emit_CGXTRA(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
 {
    vassert(s390_host_has_dfp);
    vassert(m4 == 0);
    vassert(s390_host_has_fpext || m3 < 1 || m3 > 7);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("cgxtr"), GPR(r1), UINT(m3), FPR(r2));
+      S390_DISASM(XMNM("cgxtra", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb3e90000, m3, m4, r1, r2);
 }
@@ -4886,7 +4858,7 @@ s390_emit_CLFDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clfdtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clfdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9430000, m3, m4, r1, r2);
 }
@@ -4900,7 +4872,7 @@ s390_emit_CLFXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clfxtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clfxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb94b0000, m3, m4, r1, r2);
 }
@@ -4914,7 +4886,7 @@ s390_emit_CLGDTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clgdtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clgdtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb9420000, m3, m4, r1, r2);
 }
@@ -4928,7 +4900,7 @@ s390_emit_CLGXTR(UChar *p, UChar m3, UChar m4, UChar r1, UChar r2)
    vassert(s390_host_has_fpext);
 
    if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
-      S390_DISASM(MNM("clgxtr"), GPR(r1), UINT(m3), FPR(r2), UINT(m4));
+      S390_DISASM(XMNM("clgxtr", fp_convt_disasm), GPR(r1), MASK(m3), FPR(r2), MASK(m4));
 
    return emit_RRF2(p, 0xb94a0000, m3, m4, r1, r2);
 }
@@ -10645,12 +10617,12 @@ s390_insn_bfp_convert_emit(UChar *buf, const s390_insn *insn)
 
    switch (insn->variant.bfp_convert.tag) {
       /* Convert to fixed */
-   case S390_BFP_F32_TO_I32:  return s390_emit_CFEBR(buf, m3, r1, r2);
-   case S390_BFP_F64_TO_I32:  return s390_emit_CFDBR(buf, m3, r1, r2);
-   case S390_BFP_F128_TO_I32: return s390_emit_CFXBR(buf, m3, r1, r2);
-   case S390_BFP_F32_TO_I64:  return s390_emit_CGEBR(buf, m3, r1, r2);
-   case S390_BFP_F64_TO_I64:  return s390_emit_CGDBR(buf, m3, r1, r2);
-   case S390_BFP_F128_TO_I64: return s390_emit_CGXBR(buf, m3, r1, r2);
+   case S390_BFP_F32_TO_I32:  return s390_emit_CFEBRA(buf, m3, m4, r1, r2);
+   case S390_BFP_F64_TO_I32:  return s390_emit_CFDBRA(buf, m3, m4, r1, r2);
+   case S390_BFP_F128_TO_I32: return s390_emit_CFXBRA(buf, m3, m4, r1, r2);
+   case S390_BFP_F32_TO_I64:  return s390_emit_CGEBRA(buf, m3, m4, r1, r2);
+   case S390_BFP_F64_TO_I64:  return s390_emit_CGDBRA(buf, m3, m4, r1, r2);
+   case S390_BFP_F128_TO_I64: return s390_emit_CGXBRA(buf, m3, m4, r1, r2);
 
       /* Convert to logical */
    case S390_BFP_F32_TO_U32:  return s390_emit_CLFEBR(buf, m3, m4, r1, r2);
@@ -10884,8 +10856,8 @@ s390_insn_dfp_convert_emit(UChar *buf, const s390_insn *insn)
       /* Convert to fixed */
    case S390_DFP_D64_TO_I32:  return s390_emit_CFDTR(buf, m3, m4, r1, r2);
    case S390_DFP_D128_TO_I32: return s390_emit_CFXTR(buf, m3, m4, r1, r2);
-   case S390_DFP_D64_TO_I64:  return s390_emit_CGDTR(buf, m3, m4, r1, r2);
-   case S390_DFP_D128_TO_I64: return s390_emit_CGXTR(buf, m3, m4, r1, r2);
+   case S390_DFP_D64_TO_I64:  return s390_emit_CGDTRA(buf, m3, m4, r1, r2);
+   case S390_DFP_D128_TO_I64: return s390_emit_CGXTRA(buf, m3, m4, r1, r2);
 
       /* Convert to logical */
    case S390_DFP_D64_TO_U32:  return s390_emit_CLFDTR(buf, m3, m4, r1, r2);
@@ -10897,7 +10869,7 @@ s390_insn_dfp_convert_emit(UChar *buf, const s390_insn *insn)
    case S390_DFP_I32_TO_D64:  return s390_emit_CDFTR(buf, 0, m4, r1, r2);
    case S390_DFP_I32_TO_D128: return s390_emit_CXFTR(buf, 0, m4, r1, r2);
    case S390_DFP_I64_TO_D64:  return s390_emit_CDGTRA(buf, m3, m4, r1, r2);
-   case S390_DFP_I64_TO_D128: return s390_emit_CXGTR(buf, 0, m4, r1, r2);
+   case S390_DFP_I64_TO_D128: return s390_emit_CXGTRA(buf, 0, m4, r1, r2);
 
       /* Convert from logical */
    case S390_DFP_U32_TO_D64:  return s390_emit_CDLFTR(buf, m3, m4, r1, r2);
index 3812de0e9a97523812a6310f639a41e7d323da02..9649f9f0e1e766d57eefd350051adaa78653a482 100644 (file)
@@ -524,6 +524,15 @@ always_mh(UInt ix __attribute__((unused)),
 }
 
 
+static Int
+never_mh(UInt ix __attribute__((unused)),
+         UInt mask, UInt *value)
+{
+   *value = mask;
+   return 0;
+}
+
+
 HChar *
 vfce_like_disasm(const s390_opnd *opnds, HChar *p)
 {
@@ -978,6 +987,85 @@ vcgld_disasm(const s390_opnd *opnds, HChar *p)
 }
 
 
+/* Used by BFP / DFP convert from fixed / logical opcodes
+
+   1) Mnemonics ending in 'A', e.g. CEFBRA
+      a) m3 == m4 == 0  --> CEFBR and no mask values written
+      b) otherwise      --> CEFBRA and both mask values written
+
+   2) Mnemonics for "logical" opcodes, e.g. CELFBR
+      These do not end in 'A'
+      --> mnemonic unchanged, both mask values written
+
+   3) Neither #1 nor #2, e.g. CDFTR
+      --> mnemonic unchanged, both mask values written
+*/
+HChar *
+fp_convf_disasm(const s390_opnd *opnds, HChar *p)
+{
+   vassert(mask_count(opnds) == 2);
+
+   const HChar *base = opnds[0].xmnm.base;
+   UInt m3 = opnds[get_mask_index(opnds, 1)].mask;
+   UInt m4 = opnds[get_mask_index(opnds, 2)].mask;
+   UInt len = vex_strlen(base);
+
+   HChar xmnm[len + 1];
+
+   vex_sprintf(xmnm, "%s", base);
+
+   if (xmnm[len - 1] == 'a' && m3 + m4 == 0) {
+      xmnm[len - 1] = '\0';
+      return s390_disasm_aux(opnds, xmnm, p, never_mh);
+   }
+   return s390_disasm_aux(opnds, xmnm, p, always_mh);
+}
+
+
+/* Return 1, if mask should be printed. In *VALUE return the mask value
+   that should be printed.  */
+static Int
+fp_convt_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value)
+{
+   *value = mask;
+   return (ix == 2 || mask != 0) ? 1 : 0;
+}
+
+
+/* Used by BFP / DFP convert to fixed / logical opcodes
+
+   1) Mnemonics ending in 'A', e.g. CFEBRA
+      a) m4 == 0     --> CFEBR and no mask values written
+      b) otherwise   --> CFEBRA and both mask values written
+
+   2) Mnemonics for "logical" opcodes, e.g. CLFEBR
+      These do not end in 'A'
+      --> mnemonic unchanged, both mask values written
+
+   3) Neither #1 nor #2, e.g. CFDTR
+      --> mnemonic unchanged, both mask values written
+*/
+HChar *
+fp_convt_disasm(const s390_opnd *opnds, HChar *p)
+{
+   vassert(mask_count(opnds) == 2);
+
+   const HChar *base = opnds[0].xmnm.base;
+   UInt m4 = opnds[get_mask_index(opnds, 2)].mask;
+   UInt len = vex_strlen(base);
+
+   HChar xmnm[len + 1];
+
+   vex_sprintf(xmnm, "%s", base);
+
+   if (xmnm[len - 1] == 'a' && m4 == 0) {
+      xmnm[len - 1] = '\0';
+      return s390_disasm_aux(opnds, xmnm, p, fp_convt_mh);
+   }
+   return s390_disasm_aux(opnds, xmnm, p, always_mh);
+}
+
+
 /* Write out OPNDS. MH is a mask handler. It decides whether or not a
    MASK operand is written and if so, massages the mask value as needed. */
 static HChar *
index 89fc9e8de6184247e993995a4bc8558c7e5262e3..b28af8f6594aac6d562d095a2d68d6d42fb8a756 100644 (file)
@@ -135,6 +135,8 @@ HChar *wfc_like_disasm(const s390_opnd *, HChar *);
 HChar *vfae_like_disasm(const s390_opnd *, HChar *);
 HChar *vfce_like_disasm(const s390_opnd *, HChar *);
 HChar *vfmix_like_disasm(const s390_opnd *, HChar *);
+HChar *fp_convf_disasm(const s390_opnd *, HChar *);
+HChar *fp_convt_disasm(const s390_opnd *, HChar *);
 
 /*---------------------------------------------------------------*/
 /*--- end                                       s390_disasm.h ---*/