From: Florian Krohm Date: Fri, 21 Mar 2025 23:08:49 +0000 (+0000) Subject: s390x: Fix disassembly for vector insns X-Git-Tag: VALGRIND_3_25_0~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bbebdbb2b1094b08ccbd8d09fc65f6fa0b9fecc0;p=thirdparty%2Fvalgrind.git s390x: Fix disassembly for vector insns This was painful because there is a lot of irregularity in the extended mnemonics. There is also a double-maintenance issue because S390_DISASM is used both in guest_s390_to_IR.c and in the 'emit' functions in host_s390_defs.c. It might be worth exploring whether the objdump disassembler can be extracted from binutils and re-used here. That way the disassembly would be correct by construction. And the double maintenance would go away. Fix a few things alongside: - In s390_format_VRI_VIM: is is a signed 16-bit value. So it needs to be sign-extended. Fixes disassembly for VLEI[BHFG] - Fix function dvb_operand. v0 is not special. - In s390_format_VRX_VRRDM pass forgotten m3 to S390_DISASM. - In s390_irgen_VCNF: remove s390_insn_assert. VCNF does not have specification exceptions. - Opcope VFLL has no mask m5. So s390_format_VRRa_VVMMM is the wrong format function. Change it to s390_format_VRRa_VVMM. In s390_irgen_VFLL: the value of m5 is not used in s390_vector_fp_convert because rounding == False. So, essentially, m5 is a don't care. - Add VRR_v3 and use it when a vector register is meant (instead of VRR_r3) - Add VRR_v4 and use it when a vector register is meant (instead of VRR_m4) - Add VRS_r3 and use it when a GPR is meant (instead of VRS_v3) - Add VRR_r2 and use it when a GPR is meant (instead of VRR_v2) - Add field-access macros for the VRV opcode format. Use them. - Add field-access macros for the VRIb opcode format. Use them. - Add field-access macros for the VRIc opcode format. Use them. - Add field-access macros for the VRSc opcode format. Use them. Part of fixing https://bugs.kde.org/show_bug.cgi?id=495817 --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 67633f1c9..db8cea1e8 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -49,7 +49,15 @@ static UInt s390_decode_and_irgen(const UChar *, UInt, DisResult *); static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp); static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp); -static const HChar *s390_irgen_BIC(UChar r1, IRTemp op2addr); +static const HChar *s390_irgen_BIC(UChar, IRTemp); +static const HChar *s390_irgen_VPDI(UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VFLR(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VFI(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VFPSO(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VCGD(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VCDG(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VCDLG(UChar, UChar, UChar, UChar, UChar); +static const HChar *s390_irgen_VCLGD(UChar, UChar, UChar, UChar, UChar); /*------------------------------------------------------------*/ /*--- Globals ---*/ @@ -204,9 +212,12 @@ typedef enum { #define VRX_rxb(insn) (((insn) >> 24) & 0xf) #define VRR_v1(insn) (((insn) >> 52) & 0xf) #define VRR_v2(insn) (((insn) >> 48) & 0xf) +#define VRR_r2(insn) (((insn) >> 48) & 0xf) #define VRR_r3(insn) (((insn) >> 44) & 0xf) +#define VRR_v3(insn) (((insn) >> 44) & 0xf) #define VRR_m5(insn) (((insn) >> 36) & 0xf) #define VRR_m4(insn) (((insn) >> 28) & 0xf) +#define VRR_v4(insn) (((insn) >> 28) & 0xf) #define VRR_rxb(insn) (((insn) >> 24) & 0xf) #define VRRa_v1(insn) (((insn) >> 52) & 0xf) #define VRRa_v2(insn) (((insn) >> 48) & 0xf) @@ -234,6 +245,16 @@ typedef enum { #define VRI_i2(insn) (((insn) >> 32) & 0xffff) #define VRI_m3(insn) (((insn) >> 28) & 0xf) #define VRI_rxb(insn) (((insn) >> 24) & 0xf) +#define VRIb_v1(insn) (((insn) >> 52) & 0xf) +#define VRIb_i2(insn) (((insn) >> 40) & 0xff) +#define VRIb_i3(insn) (((insn) >> 32) & 0xff) +#define VRIb_m4(insn) (((insn) >> 28) & 0xf) +#define VRIb_rxb(insn) (((insn) >> 24) & 0xf) +#define VRIc_v1(insn) (((insn) >> 52) & 0xf) +#define VRIc_v3(insn) (((insn) >> 48) & 0xf) +#define VRIc_i2(insn) (((insn) >> 32) & 0xffff) +#define VRIc_m4(insn) (((insn) >> 28) & 0xf) +#define VRIc_rxb(insn) (((insn) >> 24) & 0xf) #define VRId_v1(insn) (((insn) >> 52) & 0xf) #define VRId_v2(insn) (((insn) >> 48) & 0xf) #define VRId_v3(insn) (((insn) >> 44) & 0xf) @@ -248,10 +269,17 @@ typedef enum { #define VRIe_rxb(insn) (((insn) >> 24) & 0xf) #define VRS_v1(insn) (((insn) >> 52) & 0xf) #define VRS_v3(insn) (((insn) >> 48) & 0xf) +#define VRS_r3(insn) (((insn) >> 48) & 0xf) #define VRS_b2(insn) (((insn) >> 44) & 0xf) #define VRS_d2(insn) (((insn) >> 32) & 0xfff) #define VRS_m4(insn) (((insn) >> 28) & 0xf) #define VRS_rxb(insn) (((insn) >> 24) & 0xf) +#define VRSc_r1(insn) (((insn) >> 52) & 0xf) +#define VRSc_v3(insn) (((insn) >> 48) & 0xf) +#define VRSc_b2(insn) (((insn) >> 44) & 0xf) +#define VRSc_d2(insn) (((insn) >> 32) & 0xfff) +#define VRSc_m4(insn) (((insn) >> 28) & 0xf) +#define VRSc_rxb(insn) (((insn) >> 24) & 0xf) #define VRSd_v1(insn) (((insn) >> 28) & 0xf) #define VRSd_r3(insn) (((insn) >> 48) & 0xf) #define VSI_i3(insn) (((insn) >> 48) & 0xff) @@ -259,6 +287,12 @@ typedef enum { #define VSI_d2(insn) (((insn) >> 32) & 0xfff) #define VSI_v1(insn) (((insn) >> 28) & 0xf) #define VSI_rxb(insn) (((insn) >> 24) & 0xf) +#define VRV_v1(insn) (((insn) >> 52) & 0xf) +#define VRV_x2(insn) (((insn) >> 48) & 0xf) +#define VRV_b2(insn) (((insn) >> 44) & 0xf) +#define VRV_d2(insn) (((insn) >> 32) & 0xfff) +#define VRV_m3(insn) (((insn) >> 28) & 0xf) +#define VRV_rxb(insn) (((insn) >> 24) & 0xf) /*------------------------------------------------------------*/ @@ -3674,7 +3708,7 @@ s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr), static void s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr), - UChar v1, UChar x2, UChar b2, UShort d2, UChar rxb) + UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb) { const HChar *mnm; IRTemp op2addr = newTemp(Ity_I64); @@ -3692,13 +3726,14 @@ s390_format_VRX_VRRD(const HChar *(*irgen)(UChar v1, IRTemp op2addr), mnm = irgen(v1, op2addr); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, x2, b2)); + S390_DISASM(XMNM(mnm, mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(m3)); } static void s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3), - UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb) + UChar v1, UChar x2, UChar b2, UShort d2, UChar m3, UChar rxb, + HChar *(*handler)(const s390_opnd *, HChar *)) { const HChar *mnm; IRTemp op2addr = newTemp(Ity_I64); @@ -3715,8 +3750,12 @@ s390_format_VRX_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3), v1 = s390_vr_getVRindex(v1, 1, rxb); mnm = irgen(v1, op2addr, m3); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, x2, b2)); + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { + if (handler) + S390_DISASM(XMNM(mnm, handler), VR(v1), UDXB(d2, x2, b2), MASK(m3)); + else + S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, x2, b2), UINT(m3)); + } } @@ -3761,8 +3800,6 @@ s390_format_VRR_VVV(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3), } -// FIXME: VPDI uses this format but does not have extended mnemonics -// FIXME: all other opcodes have extended mnms static void s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4), UChar v1, UChar v2, UChar v3, UChar m4, UChar rxb) @@ -3779,14 +3816,19 @@ s390_format_VRR_VVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m v3 = s390_vr_getVRindex(v3, 3, rxb); mnm = irgen(v1, v2, v3, m4); - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4)); + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) { + if (irgen == s390_irgen_VPDI) + S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4)); + else + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); + } } static void s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5), - UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb) + UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar rxb, + HChar *(*handler)(const s390_opnd *, HChar *)) { const HChar *mnm; @@ -3801,7 +3843,7 @@ s390_format_VRR_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar mnm = irgen(v1, v2, v3, m4, m5); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); + S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5)); } @@ -3862,7 +3904,66 @@ s390_format_VRR_VVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3), mnm = irgen(v1, v2, m3); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), MASK(m3)); +} + + +static void +s390_format_VRI_V0U(const HChar *(*irgen)(UChar v1, UShort i2), + UChar v1, UShort i2, UChar rxb, + HChar *(*handler)(const s390_opnd *, HChar *)) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + mnm = irgen(v1, i2); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + S390_DISASM(XMNM(mnm, handler), VR(v1), UINT(i2)); +} + + +static void +s390_format_VRI_V0UUU(const HChar *(*irgen)(UChar v1, UChar i2, UChar i3, + UChar m4), + UChar v1, UChar i2, UChar i3, UChar m4, UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + mnm = irgen(v1, i2, i3, m4); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), UINT(i2), UINT(i3), MASK(m4)); +} + + +static void +s390_format_VRI_V0IU(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), + UChar v1, UShort i2, UChar m3, UChar rxb) +{ + const HChar *mnm; + + if (! s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + mnm = irgen(v1, i2, m3); + + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), INT((Short)i2), MASK(m3)); } @@ -3881,7 +3982,7 @@ s390_format_VRI_VIM(const HChar *(*irgen)(UChar v1, UShort i2, UChar m3), mnm = irgen(v1, i2, m3); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UINT(i2), UINT(m3)); + S390_DISASM(MNM(mnm), VR(v1), INT((Short)i2), UINT(m3)); } @@ -3901,7 +4002,7 @@ s390_format_VRI_VVIM(const HChar *(*irgen)(UChar v1, UChar v3, UShort i2, UChar mnm = irgen(v1, v3, i2, m4); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v3), UINT(i2), UINT(m4)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v3), UINT(i2), MASK(m4)); } static void @@ -3922,7 +4023,7 @@ s390_format_VRI_VVIMM(const HChar *(*irgen)(UChar v1, UChar v2, UShort i3, mnm = irgen(v1, v2, i3, m4, m5); if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(i3), UINT(m4), UINT(m5)); + S390_DISASM(XMNM(mnm, vfmix_like_disasm), VR(v1), VR(v2), UINT(i3), MASK(m4), MASK(m5)); } static void @@ -3945,7 +4046,7 @@ s390_format_VRS_RRDVM(const HChar *(*irgen)(UChar r1, IRTemp op2addr, UChar v3, mnm = irgen(r1, op2addr, v3, m4); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), GPR(r1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM(mnm, va_like_disasm), GPR(r1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); } static void @@ -3992,13 +4093,13 @@ s390_format_VRS_VRDVM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3, mnm = irgen(v1, op2addr, v3, m4); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); } static void s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3), - UChar v1, UChar b2, UShort d2, UChar v3, UChar rxb) + UChar v1, UChar b2, UShort d2, UChar v3, UChar m4, UChar rxb) { const HChar *mnm; IRTemp op2addr = newTemp(Ity_I64); @@ -4016,7 +4117,7 @@ s390_format_VRS_VRDV(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar v3), mnm = irgen(v1, op2addr, v3); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), UDXB(d2, 0, b2), VR(v3)); + S390_DISASM(XMNM(mnm, mask0_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); } @@ -4040,7 +4141,7 @@ s390_format_VRS_VRRDM(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar r3, mnm = irgen(v1, op2addr, r3, m4); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), GPR(r3), UDXB(d2, 0, b2), UINT(m4)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), GPR(r3), UDXB(d2, 0, b2), MASK(m4)); } @@ -4103,9 +4204,10 @@ s390_format_VRV_VVRDMT(const HChar *(*irgen)(UChar v1, IRTemp op2addr, UChar m3) static void s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, - UChar v4, UChar m5, UChar m6), - UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, - UChar m6, UChar rxb) + UChar v4, UChar m5, UChar m6), + UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, + UChar m6, UChar rxb, + HChar *(*handler)(const s390_opnd *, HChar *)) { const HChar *mnm; @@ -4121,7 +4223,7 @@ s390_format_VRR_VVVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, mnm = irgen(v1, v2, v3, v4, m5, m6); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), VR(v4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); } @@ -4142,7 +4244,7 @@ s390_format_VRR_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, mnm = irgen(v1, v2, m3, m5); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m5)); + S390_DISASM(XMNM(mnm, vch_like_disasm), VR(v1), VR(v2), MASK(m3), MASK(m5)); } @@ -4165,7 +4267,7 @@ s390_format_VRId_VVVIM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, mnm = irgen(v1, v2, v3, i4, m5); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(i4), UINT(m5)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), UINT(i4), MASK(m5)); } @@ -4211,7 +4313,7 @@ s390_format_VRRd_VVVVM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, mnm = irgen(v1, v2, v3, v4, m5); if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), VR(v4), UINT(m5)); + S390_DISASM(XMNM(mnm, va_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5)); } @@ -4232,15 +4334,31 @@ s390_format_VRRa_VVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, v2 = s390_vr_getVRindex(v2, 2, rxb); mnm = irgen(v1, v2, m3, m4, m5); - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4), UINT(m5)); + if (vex_traceflags & VEX_TRACE_FE) { + if (irgen == s390_irgen_VFLR) + S390_DISASM(XMNM(mnm, vflr_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), UINT(m5)); + else if (irgen == s390_irgen_VFI) + S390_DISASM(XMNM(mnm, vfi_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), UINT(m5)); + else if (irgen == s390_irgen_VFPSO) + S390_DISASM(XMNM(mnm, vfpso_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); + else if (irgen == s390_irgen_VCGD) + S390_DISASM(XMNM(mnm, vcgd_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); + else if (irgen == s390_irgen_VCDG) + S390_DISASM(XMNM(mnm, vcdg_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); + else if (irgen == s390_irgen_VCLGD) + S390_DISASM(XMNM(mnm, vclgd_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); + else if (irgen == s390_irgen_VCDLG) + S390_DISASM(XMNM(mnm, vcgld_disasm), VR(v1), VR(v2), MASK(m3), MASK(m4), MASK(m5)); + else + S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4), UINT(m5)); + } } static void s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, UChar m4, UChar m5), UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, - UChar rxb) + UChar rxb, HChar *(*handler)(const s390_opnd *, HChar *)) { const HChar *mnm; @@ -4254,14 +4372,19 @@ s390_format_VRRa_VVVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, v3 = s390_vr_getVRindex(v3, 3, rxb); mnm = irgen(v1, v2, v3, m4, m5); - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); + if (vex_traceflags & VEX_TRACE_FE) { + if (handler) + S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5)); + else + S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5)); + } } static void s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, UChar m4), - UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb) + UChar v1, UChar v2, UChar m3, UChar m4, UChar rxb, + HChar *(*handler)(const s390_opnd *, HChar *)) { const HChar *mnm; @@ -4274,8 +4397,12 @@ s390_format_VRRa_VVMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar m3, v2 = s390_vr_getVRindex(v2, 2, rxb); mnm = irgen(v1, v2, m3, m4); - if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4)); + if (vex_traceflags & VEX_TRACE_FE) { + if (handler) + S390_DISASM(XMNM(mnm, handler), VR(v1), VR(v2), MASK(m3), MASK(m4)); + else + S390_DISASM(MNM(mnm), VR(v1), VR(v2), UINT(m3), UINT(m4)); + } } static void @@ -4297,7 +4424,30 @@ s390_format_VRRa_VVVMMM(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, mnm = irgen(v1, v2, v3, m4, m5, m6); if (vex_traceflags & VEX_TRACE_FE) - S390_DISASM(MNM(mnm), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM(mnm, vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); +} + + +static void +s390_format_VRRa_VVVMMM2(const HChar *(*irgen)(UChar v1, UChar v2, UChar v3, + UChar m4, UChar m5, UChar m6), + UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, + UChar m6, UChar rxb) +{ + const HChar *mnm; + + if (!s390_host_has_vx) { + emulation_failure(EmFail_S390X_vx); + return; + } + + v1 = s390_vr_getVRindex(v1, 1, rxb); + v2 = s390_vr_getVRindex(v2, 2, rxb); + v3 = s390_vr_getVRindex(v3, 3, rxb); + mnm = irgen(v1, v2, v3, m4, m5, m6); + + if (vex_traceflags & VEX_TRACE_FE) + S390_DISASM(XMNM(mnm, vfmix_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), UINT(m6)); } static void @@ -16438,7 +16588,7 @@ s390_irgen_VLGV(UChar r1, IRTemp op2addr, UChar v3, UChar m4) } static const HChar * -s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused))) +s390_irgen_VGBM(UChar v1, UShort i2) { put_vr_qw(v1, mkV128(i2)); @@ -16446,13 +16596,13 @@ s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused))) } static const HChar * -s390_irgen_VGM(UChar v1, UShort i2, UChar m3) +s390_irgen_VGM(UChar v1, UChar i2, UChar i3, UChar m4) { - s390_insn_assert("vgm", m3 <= 3); + s390_insn_assert("vgm", m4 <= 3); - UChar max_idx = (8 << m3) - 1; - UChar from = max_idx & (i2 >> 8); - UChar to = max_idx & i2; + UChar max_idx = (8 << m4) - 1; + UChar from = max_idx & i2; + UChar to = max_idx & i3; ULong all_one = (1ULL << max_idx << 1) - 1; ULong value = (all_one >> from) ^ (all_one >> to >> 1); @@ -16464,7 +16614,7 @@ s390_irgen_VGM(UChar v1, UShort i2, UChar m3) value ^= all_one; IRExpr* fillValue; - switch (m3) { + switch (m4) { case 0: fillValue = mkU8(value); break; @@ -19043,17 +19193,17 @@ s390_irgen_VFI(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) } static const HChar * -s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4, UChar m5) +s390_irgen_VFLL(UChar v1, UChar v2, UChar m3, UChar m4) { s390_insn_assert("vfll", m3 == 2 || (s390_host_has_vxe && m3 == 3)); s390_insn_assert("vfll", (m4 & 0x7) == 0); if (m3 == 2) s390_vector_fp_convert(Iop_F32toF64, Ity_F32, Ity_F64, False, - v1, v2, m3, m4, m5); + v1, v2, m3, m4, /* don't care */ 0); else s390_vector_fp_convert(Iop_F64toF128, Ity_F64, Ity_F128, False, - v1, v2, m3, m4, m5); + v1, v2, m3, m4, /* don't care */ 0); return "vfll"; } @@ -19911,9 +20061,6 @@ s390_irgen_VCxx(const HChar *mnem, s390x_vec_op_details_t details, static const HChar * s390_irgen_VCNF(UChar v1, UChar v2, UChar m3, UChar m4) { - s390_insn_assert("vcnf", m3 == 0); - s390_insn_assert("vcnf", m4 < 2); - s390x_vec_op_details_t details = { .serialized = 0ULL }; details.op = S390_VEC_OP_VCNF; details.v1 = v1; @@ -21794,56 +21941,56 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe60000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRH, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe60000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRG, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe60000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEBRF, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe60000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEBRZ, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), vllebrz_disasm); goto ok; case 0xe60000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLBRREP, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), va_like_disasm); goto ok; case 0xe60000000006ULL: s390_format_VRX_VRRDM(s390_irgen_VLBR, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), va_like_disasm); goto ok; case 0xe60000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLER, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), va_like_disasm); goto ok; case 0xe60000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRH, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe6000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRG, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), vstebrg_disasm); goto ok; case 0xe6000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEBRF, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), vstebrf_disasm); goto ok; case 0xe6000000000eULL: s390_format_VRX_VRRDM(s390_irgen_VSTBR, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), va_like_disasm); goto ok; case 0xe6000000000fULL: s390_format_VRX_VRRDM(s390_irgen_VSTER, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), va_like_disasm); goto ok; case 0xe60000000034ULL: /* VPKZ */ goto unimplemented; case 0xe60000000035ULL: s390_format_VSI_URDV(s390_irgen_VLRL, VSI_v1(ovl), VSI_b2(ovl), VSI_d2(ovl), @@ -21872,19 +22019,19 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe60000000055ULL: s390_format_VRRa_VVMM(s390_irgen_VCNF, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), NULL); goto ok; case 0xe60000000056ULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNH, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), NULL); goto ok; case 0xe6000000005dULL: s390_format_VRRa_VVMM(s390_irgen_VCFN, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), NULL); goto ok; case 0xe6000000005eULL: s390_format_VRRa_VVMM(s390_irgen_VCLFNL, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), NULL); goto ok; case 0xe60000000058ULL: /* VCVD */ goto unimplemented; case 0xe60000000059ULL: /* VSRP */ goto unimplemented; case 0xe6000000005aULL: /* VCVDG */ goto unimplemented; @@ -21899,7 +22046,7 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), NULL); goto ok; case 0xe60000000077ULL: /* VCP */ goto unimplemented; case 0xe60000000078ULL: /* VMP */ goto unimplemented; case 0xe60000000079ULL: /* VMSP */ goto unimplemented; @@ -21913,72 +22060,74 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe70000000000ULL: s390_format_VRX_VRRDM(s390_irgen_VLEB, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000001ULL: s390_format_VRX_VRRDM(s390_irgen_VLEH, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000002ULL: s390_format_VRX_VRRDM(s390_irgen_VLEG, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000003ULL: s390_format_VRX_VRRDM(s390_irgen_VLEF, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000004ULL: s390_format_VRX_VRRDM(s390_irgen_VLLEZ, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), vllez_disasm); goto ok; case 0xe70000000005ULL: s390_format_VRX_VRRDM(s390_irgen_VLREP, VRX_v1(ovl), + VRX_x2(ovl), VRX_b2(ovl), + VRX_d2(ovl), VRX_m3(ovl), + VRX_rxb(ovl), va_like_disasm); goto ok; + case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), VRX_rxb(ovl)); goto ok; - case 0xe70000000006ULL: s390_format_VRX_VRRD(s390_irgen_VL, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_rxb(ovl)); goto ok; case 0xe70000000007ULL: s390_format_VRX_VRRDM(s390_irgen_VLBB, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000008ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEB, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe70000000009ULL: s390_format_VRX_VRRDM(s390_irgen_VSTEH, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe7000000000aULL: s390_format_VRX_VRRDM(s390_irgen_VSTEG, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe7000000000bULL: s390_format_VRX_VRRDM(s390_irgen_VSTEF, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl)); goto ok; + VRX_rxb(ovl), NULL); goto ok; case 0xe7000000000eULL: s390_format_VRX_VRRD(s390_irgen_VST, VRX_v1(ovl), VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_rxb(ovl)); goto ok; - case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), Ity_I64); goto ok; - case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), Ity_I32); goto ok; - case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), Ity_I64); goto ok; - case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, VRX_v1(ovl), - VRX_x2(ovl), VRX_b2(ovl), - VRX_d2(ovl), VRX_m3(ovl), - VRX_rxb(ovl), Ity_I32); goto ok; - case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_m4(ovl), VRS_rxb(ovl)); goto ok; + VRX_d2(ovl), VRX_m3(ovl), + VRX_rxb(ovl)); goto ok; + case 0xe70000000012ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEG, VRV_v1(ovl), + VRV_x2(ovl), VRV_b2(ovl), + VRV_d2(ovl), VRV_m3(ovl), + VRV_rxb(ovl), Ity_I64); goto ok; + case 0xe70000000013ULL: s390_format_VRV_VVRDMT(s390_irgen_VGEF, VRV_v1(ovl), + VRV_x2(ovl), VRV_b2(ovl), + VRV_d2(ovl), VRV_m3(ovl), + VRV_rxb(ovl), Ity_I32); goto ok; + case 0xe7000000001aULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEG, VRV_v1(ovl), + VRV_x2(ovl), VRV_b2(ovl), + VRV_d2(ovl), VRV_m3(ovl), + VRV_rxb(ovl), Ity_I64); goto ok; + case 0xe7000000001bULL: s390_format_VRV_VVRDMT(s390_irgen_VSCEF, VRV_v1(ovl), + VRV_x2(ovl), VRV_b2(ovl), + VRV_d2(ovl), VRV_m3(ovl), + VRV_rxb(ovl), Ity_I32); goto ok; + case 0xe70000000021ULL: s390_format_VRS_RRDVM(s390_irgen_VLGV, VRSc_r1(ovl), + VRSc_b2(ovl), VRSc_d2(ovl), VRSc_v3(ovl), + VRSc_m4(ovl), VRSc_rxb(ovl)); goto ok; case 0xe70000000022ULL: s390_format_VRS_VRRDM(s390_irgen_VLVG, VRS_v1(ovl), VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), VRS_m4(ovl), VRS_rxb(ovl)); goto ok; @@ -21995,9 +22144,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRS_rxb(ovl)); goto ok; case 0xe70000000036ULL: s390_format_VRS_VRDV(s390_irgen_VLM, VRS_v1(ovl), VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_rxb(ovl)); goto ok; + VRS_m4(ovl), VRS_rxb(ovl)); goto ok; case 0xe70000000037ULL: s390_format_VRS_VRRD(s390_irgen_VLL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), + VRS_b2(ovl), VRS_d2(ovl), VRS_r3(ovl), VRS_rxb(ovl)); goto ok; case 0xe70000000038ULL: s390_format_VRS_VRDVM(s390_irgen_VESRL, VRS_v1(ovl), VRS_b2(ovl), VRS_d2(ovl), @@ -22009,9 +22158,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRS_rxb(ovl)); goto ok; case 0xe7000000003eULL: s390_format_VRS_VRDV(s390_irgen_VSTM, VRS_v1(ovl), VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), - VRS_rxb(ovl)); goto ok; + VRS_m4(ovl), VRS_rxb(ovl)); goto ok; case 0xe7000000003fULL: s390_format_VRS_VRRD(s390_irgen_VSTL, VRS_v1(ovl), - VRS_b2(ovl), VRS_d2(ovl), VRS_v3(ovl), + VRS_b2(ovl), VRS_d2(ovl), VRS_r3(ovl), VRS_rxb(ovl)); goto ok; case 0xe70000000040ULL: s390_format_VRI_VIM(s390_irgen_VLEIB, VRI_v1(ovl), VRI_i2(ovl), VRI_m3(ovl), @@ -22025,139 +22174,139 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe70000000043ULL: s390_format_VRI_VIM(s390_irgen_VLEIF, VRI_v1(ovl), VRI_i2(ovl), VRI_m3(ovl), VRI_rxb(ovl)); goto ok;break; - case 0xe70000000044ULL: s390_format_VRI_VIM(s390_irgen_VGBM, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000045ULL: s390_format_VRI_VIM(s390_irgen_VREPI, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; - case 0xe70000000046ULL: s390_format_VRI_VIM(s390_irgen_VGM, VRI_v1(ovl), - VRI_i2(ovl), VRI_m3(ovl), - VRI_rxb(ovl)); goto ok; + case 0xe70000000044ULL: s390_format_VRI_V0U(s390_irgen_VGBM, VRI_v1(ovl), + VRI_i2(ovl), VRI_rxb(ovl), + vgbm_disasm); goto ok; + case 0xe70000000045ULL: s390_format_VRI_V0IU(s390_irgen_VREPI, VRI_v1(ovl), + VRI_i2(ovl), VRI_m3(ovl), + VRI_rxb(ovl)); goto ok; + case 0xe70000000046ULL: s390_format_VRI_V0UUU(s390_irgen_VGM, VRIb_v1(ovl), + VRIb_i2(ovl), VRIb_i3(ovl), VRIb_m4(ovl), + VRIb_rxb(ovl)); goto ok; case 0xe7000000004aULL: s390_format_VRI_VVIMM(s390_irgen_VFTCI, VRIe_v1(ovl), VRIe_v2(ovl), VRIe_i3(ovl), VRIe_m4(ovl), VRIe_m5(ovl), VRIe_rxb(ovl)); goto ok; - case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, VRI_v1(ovl), - VRI_v3(ovl), VRI_i2(ovl), - VRI_m3(ovl), VRI_rxb(ovl)); goto ok; - case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), + case 0xe7000000004dULL: s390_format_VRI_VVIM(s390_irgen_VREP, VRIc_v1(ovl), + VRIc_v3(ovl), VRIc_i2(ovl), + VRIc_m4(ovl), VRIc_rxb(ovl)); goto ok; + case 0xe70000000050ULL: s390_format_VRR_VVM(s390_irgen_VPOPCT, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), VRR_rxb(ovl)); goto ok; + case 0xe70000000052ULL: s390_format_VRR_VVM(s390_irgen_VCTZ, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe70000000053ULL: s390_format_VRR_VVM(s390_irgen_VCLZ, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; case 0xe70000000054ULL: /* VGEM */ goto unimplemented; case 0xe70000000056ULL: s390_format_VRR_VV(s390_irgen_VLR, VRR_v1(ovl), VRR_v2(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000005cULL: s390_format_VRR_VVMM(s390_irgen_VISTR, VRR_v1(ovl), VRR_v2(ovl), VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok; - case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; + case 0xe7000000005fULL: s390_format_VRR_VVM(s390_irgen_VSEG, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; case 0xe70000000060ULL: s390_format_VRR_VVVM(s390_irgen_VMRL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000061ULL: s390_format_VRR_VVVM(s390_irgen_VMRH, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000062ULL: s390_format_VRR_VRR(s390_irgen_VLVGP, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_r2(ovl), VRR_r3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000064ULL: s390_format_VRR_VVVM(s390_irgen_VSUM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000065ULL: s390_format_VRR_VVVM(s390_irgen_VSUMG, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000066ULL: s390_format_VRR_VVV(s390_irgen_VCKSM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000067ULL: s390_format_VRR_VVVM(s390_irgen_VSUMQ, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000068ULL: s390_format_VRR_VVV(s390_irgen_VN, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000069ULL: s390_format_VRR_VVV(s390_irgen_VNC, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006aULL: s390_format_VRR_VVV(s390_irgen_VO, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006bULL: s390_format_VRR_VVV(s390_irgen_VNO, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006cULL: s390_format_VRR_VVV(s390_irgen_VNX, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006dULL: s390_format_VRR_VVV(s390_irgen_VX, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006eULL: s390_format_VRR_VVV(s390_irgen_VNN, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000006fULL: s390_format_VRR_VVV(s390_irgen_VOC, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000070ULL: s390_format_VRR_VVVM(s390_irgen_VESLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000072ULL: s390_format_VRId_VVVIM(s390_irgen_VERIM, VRId_v1(ovl), VRId_v2(ovl), VRId_v3(ovl), VRId_i4(ovl), VRId_m5(ovl), VRId_rxb(ovl)); goto ok; case 0xe70000000073ULL: s390_format_VRR_VVVM(s390_irgen_VERLLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000074ULL: s390_format_VRR_VVV(s390_irgen_VSL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000075ULL: s390_format_VRR_VVV(s390_irgen_VSLB, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000077ULL: s390_format_VRId_VVVI(s390_irgen_VSLDB, VRId_v1(ovl), VRId_v2(ovl), VRId_v3(ovl), VRId_i4(ovl), VRId_rxb(ovl)); goto ok; case 0xe70000000078ULL: s390_format_VRR_VVVM(s390_irgen_VESRLV, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000007aULL: s390_format_VRR_VVVM(s390_irgen_VESRAV, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000007cULL: s390_format_VRR_VVV(s390_irgen_VSRL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000007dULL: s390_format_VRR_VVV(s390_irgen_VSRLB, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000007eULL: s390_format_VRR_VVV(s390_irgen_VSRA, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000007fULL: s390_format_VRR_VVV(s390_irgen_VSRAB, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000080ULL: s390_format_VRR_VVVMM(s390_irgen_VFEE, VRR_v1(ovl), VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vfae_like_disasm); goto ok; case 0xe70000000081ULL: s390_format_VRR_VVVMM(s390_irgen_VFENE, VRR_v1(ovl), VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vfae_like_disasm); goto ok; case 0xe70000000082ULL: s390_format_VRR_VVVMM(s390_irgen_VFAE, VRR_v1(ovl), VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vfae_like_disasm); goto ok; case 0xe70000000084ULL: s390_format_VRR_VVVM(s390_irgen_VPDI, VRR_v1(ovl), VRR_v2(ovl), VRR_r3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000085ULL: s390_format_VRR_VVV(s390_irgen_VBPERM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000086ULL: s390_format_VRId_VVVI(s390_irgen_VSLD, VRId_v1(ovl), VRId_v2(ovl), VRId_v3(ovl), @@ -22172,68 +22321,70 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe7000000008aULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRC, VRRd_v1(ovl), VRRd_v2(ovl), VRRd_v3(ovl), VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), - VRRd_rxb(ovl)); goto ok; + VRRd_m6(ovl), VRRd_rxb(ovl), + vstrc_disasm); goto ok; case 0xe7000000008bULL: s390_format_VRR_VVVVMM(s390_irgen_VSTRS, VRRd_v1(ovl), VRRd_v2(ovl), VRRd_v3(ovl), VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), - VRRd_rxb(ovl)); goto ok; + VRRd_m6(ovl), VRRd_rxb(ovl), + vfae_like_disasm); goto ok; case 0xe7000000008cULL: s390_format_VRR_VVVV(s390_irgen_VPERM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_v4(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000008dULL: s390_format_VRR_VVVV(s390_irgen_VSEL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_v4(ovl), VRR_rxb(ovl)); goto ok; case 0xe7000000008eULL: s390_format_VRR_VVVVMM(s390_irgen_VFMS, VRRe_v1(ovl), VRRe_v2(ovl), VRRe_v3(ovl), VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), - VRRe_rxb(ovl)); goto ok; + VRRe_m6(ovl), VRRe_rxb(ovl), + vfms_like_disasm); goto ok; case 0xe7000000008fULL: s390_format_VRR_VVVVMM(s390_irgen_VFMA, VRRe_v1(ovl), VRRe_v2(ovl), VRRe_v3(ovl), VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), - VRRe_rxb(ovl)); goto ok; + VRRe_m6(ovl), VRRe_rxb(ovl), + vfms_like_disasm); goto ok; case 0xe70000000094ULL: s390_format_VRR_VVVM(s390_irgen_VPK, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe70000000095ULL: s390_format_VRR_VVVMM(s390_irgen_VPKLS, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vch_like_disasm); goto ok; case 0xe70000000097ULL: s390_format_VRR_VVVMM(s390_irgen_VPKS, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vch_like_disasm); goto ok; case 0xe7000000009eULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMS, VRRe_v1(ovl), VRRe_v2(ovl), VRRe_v3(ovl), VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), - VRRe_rxb(ovl)); goto ok; + VRRe_m6(ovl), VRRe_rxb(ovl), + vfms_like_disasm); goto ok; case 0xe7000000009fULL: s390_format_VRR_VVVVMM(s390_irgen_VFNMA, VRRe_v1(ovl), VRRe_v2(ovl), VRRe_v3(ovl), VRRe_v4(ovl), VRRe_m5(ovl), - VRRe_m6(ovl), - VRRe_rxb(ovl)); goto ok; + VRRe_m6(ovl), VRRe_rxb(ovl), + vfms_like_disasm); goto ok; case 0xe700000000a1ULL: s390_format_VRR_VVVM(s390_irgen_VMLH, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a2ULL: s390_format_VRR_VVVM(s390_irgen_VML, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a3ULL: s390_format_VRR_VVVM(s390_irgen_VMH, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a4ULL: s390_format_VRR_VVVM(s390_irgen_VMLE, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a5ULL: s390_format_VRR_VVVM(s390_irgen_VMLO, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a6ULL: s390_format_VRR_VVVM(s390_irgen_VME, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a7ULL: s390_format_VRR_VVVM(s390_irgen_VMO, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000a9ULL: s390_format_VRRd_VVVVM(s390_irgen_VMALH, VRRd_v1(ovl), VRRd_v2(ovl), VRRd_v3(ovl), @@ -22268,13 +22419,13 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe700000000b2ULL: /* VD */ goto unimplemented; case 0xe700000000b3ULL: /* VR */ goto unimplemented; case 0xe700000000b4ULL: s390_format_VRR_VVVM(s390_irgen_VGFM, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000b8ULL: s390_format_VRR_VVVVMM(s390_irgen_VMSL, VRRd_v1(ovl), VRRd_v2(ovl), VRRd_v3(ovl), VRRd_v4(ovl), VRRd_m5(ovl), - VRRd_m6(ovl), - VRRd_rxb(ovl)); goto ok; + VRRd_m6(ovl), VRRd_rxb(ovl), + vmsl_disasm); goto ok; case 0xe700000000b9ULL: s390_format_VRRd_VVVVM(s390_irgen_VACCC, VRRd_v1(ovl), VRRd_v2(ovl), VRRd_v3(ovl), VRRd_v4(ovl), VRRd_m5(ovl), @@ -22311,10 +22462,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), VRRa_m5(ovl), VRRa_rxb(ovl)); goto ok; - case 0xe700000000c4ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLL, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; + case 0xe700000000c4ULL: s390_format_VRRa_VVMM(s390_irgen_VFLL, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_m4(ovl), VRRa_rxb(ovl), + vfll_disasm); goto ok; case 0xe700000000c5ULL: s390_format_VRRa_VVMMM(s390_irgen_VFLR, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), VRRa_m5(ovl), @@ -22325,12 +22476,12 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRRa_rxb(ovl)); goto ok; case 0xe700000000caULL: s390_format_VRRa_VVMM(s390_irgen_WFK, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_m4(ovl), VRRa_rxb(ovl), + wfc_like_disasm); goto ok; case 0xe700000000cbULL: s390_format_VRRa_VVMM(s390_irgen_WFC, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), - VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_m4(ovl), VRRa_rxb(ovl), + wfc_like_disasm); goto ok; case 0xe700000000ccULL: s390_format_VRRa_VVMMM(s390_irgen_VFPSO, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), VRRa_m5(ovl), @@ -22338,49 +22489,49 @@ s390_decode_6byte_and_irgen(const UChar *bytes) case 0xe700000000ceULL: s390_format_VRRa_VVMM(s390_irgen_VFSQ, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; + VRRa_rxb(ovl), vfmix_like_disasm); goto ok; + case 0xe700000000d4ULL: s390_format_VRR_VVM(s390_irgen_VUPLL, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000d5ULL: s390_format_VRR_VVM(s390_irgen_VUPLH, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000d6ULL: s390_format_VRR_VVM(s390_irgen_VUPL, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000d7ULL: s390_format_VRR_VVM(s390_irgen_VUPH, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; case 0xe700000000d8ULL: s390_format_VRR_VV(s390_irgen_VTM, VRR_v1(ovl), VRR_v2(ovl), VRR_rxb(ovl)); goto ok; - case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; - case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, VRR_v1(ovl), - VRR_v2(ovl), VRR_m4(ovl), - VRR_rxb(ovl)); goto ok; + case 0xe700000000d9ULL: s390_format_VRR_VVM(s390_irgen_VECL, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000dbULL: s390_format_VRR_VVM(s390_irgen_VEC, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000deULL: s390_format_VRR_VVM(s390_irgen_VLC, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000dfULL: s390_format_VRR_VVM(s390_irgen_VLP, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_m3(ovl), + VRRa_rxb(ovl)); goto ok; case 0xe700000000e2ULL: s390_format_VRRa_VVVMM(s390_irgen_VFS, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), vfa_like_disasm); goto ok; case 0xe700000000e3ULL: s390_format_VRRa_VVVMM(s390_irgen_VFA, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), vfa_like_disasm); goto ok; case 0xe700000000e5ULL: s390_format_VRRa_VVVMM(s390_irgen_VFD, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), vfa_like_disasm); goto ok; case 0xe700000000e7ULL: s390_format_VRRa_VVVMM(s390_irgen_VFM, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_rxb(ovl)); goto ok; + VRRa_rxb(ovl), vfa_like_disasm); goto ok; case 0xe700000000e8ULL: s390_format_VRRa_VVVMMM(s390_irgen_VFCE, VRRa_v1(ovl), VRRa_v2(ovl), VRRa_v3(ovl), VRRa_m3(ovl), VRRa_m4(ovl), @@ -22396,58 +22547,58 @@ s390_decode_6byte_and_irgen(const UChar *bytes) VRRa_m3(ovl), VRRa_m4(ovl), VRRa_m5(ovl), VRRa_rxb(ovl)); goto ok; - case 0xe700000000eeULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMIN, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; - case 0xe700000000efULL: s390_format_VRRa_VVVMMM(s390_irgen_VFMAX, VRRa_v1(ovl), - VRRa_v2(ovl), VRRa_v3(ovl), - VRRa_m3(ovl), VRRa_m4(ovl), - VRRa_m5(ovl), - VRRa_rxb(ovl)); goto ok; + case 0xe700000000eeULL: s390_format_VRRa_VVVMMM2(s390_irgen_VFMIN, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_v3(ovl), + VRRa_m3(ovl), VRRa_m4(ovl), + VRRa_m5(ovl), + VRRa_rxb(ovl)); goto ok; + case 0xe700000000efULL: s390_format_VRRa_VVVMMM2(s390_irgen_VFMAX, VRRa_v1(ovl), + VRRa_v2(ovl), VRRa_v3(ovl), + VRRa_m3(ovl), VRRa_m4(ovl), + VRRa_m5(ovl), + VRRa_rxb(ovl)); goto ok; case 0xe700000000f0ULL: s390_format_VRR_VVVM(s390_irgen_VAVGL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f1ULL: s390_format_VRR_VVVM(s390_irgen_VACC, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f2ULL: s390_format_VRR_VVVM(s390_irgen_VAVG, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f3ULL: s390_format_VRR_VVVM(s390_irgen_VA, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f5ULL: s390_format_VRR_VVVM(s390_irgen_VSCBI, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f7ULL: s390_format_VRR_VVVM(s390_irgen_VS, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000f8ULL: s390_format_VRR_VVVMM(s390_irgen_VCEQ, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vch_like_disasm); goto ok; case 0xe700000000f9ULL: s390_format_VRR_VVVMM(s390_irgen_VCHL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vch_like_disasm); goto ok; case 0xe700000000fbULL: s390_format_VRR_VVVMM(s390_irgen_VCH, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_m5(ovl), - VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_m5(ovl), VRR_rxb(ovl), + vch_like_disasm); goto ok; case 0xe700000000fcULL: s390_format_VRR_VVVM(s390_irgen_VMNL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000fdULL: s390_format_VRR_VVVM(s390_irgen_VMXL, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), + VRR_v2(ovl), VRR_v3(ovl), VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000feULL: s390_format_VRR_VVVM(s390_irgen_VMN, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xe700000000ffULL: s390_format_VRR_VVVM(s390_irgen_VMX, VRR_v1(ovl), - VRR_v2(ovl), VRR_r3(ovl), - VRR_m4(ovl), VRR_rxb(ovl)); goto ok; + VRR_v2(ovl), VRR_v3(ovl), + VRR_m4(ovl), VRR_rxb(ovl)); goto ok; case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, RSY_r1(ovl), RSY_r3(ovl), RSY_b2(ovl), RSY_dl2(ovl), diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index f78abd8fe..37b4b5baa 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -5789,7 +5789,8 @@ static UChar * s390_emit_VL(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vl"), VR(v1), UDXB(d2, x2, b2)); + /* m3 = 0 --> no alignment indicated */ + S390_DISASM(XMNM("vl", mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(0)); return emit_VRX(p, 0xE70000000006ULL, v1, x2, b2, d2, 0); } @@ -5818,7 +5819,8 @@ static UChar * s390_emit_VST(UChar *p, UChar v1, UChar x2, UChar b2, UShort d2) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vst"), VR(v1), UDXB(d2, x2, b2)); + /* As the alignment of the 2nd operand is unknown --> m3 = 0 */ + S390_DISASM(XMNM("vst", mask0_disasm), VR(v1), UDXB(d2, x2, b2), MASK(0)); return emit_VRX(p, 0xE7000000000eULL, v1, x2, b2, d2, 0); } @@ -5828,7 +5830,7 @@ static UChar * s390_emit_VLGV(UChar *p, UChar r1, UChar b2, UShort d2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlgv"), GPR(r1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vlgv", va_like_disasm), GPR(r1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); return emit_VRS(p, 0xE70000000021ULL, r1, b2, d2, v3, m4); } @@ -5838,7 +5840,7 @@ static UChar * s390_emit_VLVG(UChar *p, UChar v1, UChar b2, UShort d2, UChar r3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlvg"), VR(v1), GPR(r3), UDXB(d2, 0, b2), UINT(m4)); + S390_DISASM(XMNM("vlvg", va_like_disasm), VR(v1), GPR(r3), UDXB(d2, 0, b2), MASK(m4)); return emit_VRS(p, 0xE70000000022ULL, v1, b2, d2, r3, m4); } @@ -5893,7 +5895,8 @@ static UChar* s390_emit_VCEQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vceq"), VR(v1), VR(v2), VR(v3), UINT(m4)); + /* fixs390: m5 = 0 --> condition code not set */ + S390_DISASM(XMNM("vceq", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); return emit_VRR_VVVM(p, 0xE700000000f8ULL, v1, v2, v3, m4); } @@ -5903,7 +5906,7 @@ static UChar * s390_emit_VGBM(UChar *p, UChar v1, UShort i2) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vgbm"), VR(v1), UINT(i2)); + S390_DISASM(XMNM("vgbm", vgbm_disasm), VR(v1), UINT(i2)); return emit_VRI_VI(p, 0xE70000000044ULL, v1, i2); } @@ -5913,7 +5916,7 @@ static UChar * s390_emit_VPK(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vpk"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vpk", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000094ULL, v1, v2, v3, m4); } @@ -5923,7 +5926,8 @@ static UChar * s390_emit_VPKS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vpks"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(0)); + /* fixs390: m5 = 0 --> condition code not set */ + S390_DISASM(XMNM("vpks", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); return emit_VRR_VVVM(p, 0xE70000000097ULL, v1, v2, v3, m4); } @@ -5933,7 +5937,8 @@ static UChar * s390_emit_VPKLS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vpkls"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(0)); + /* fixs390: m5 = 0 --> condition code not set */ + S390_DISASM(XMNM("vpkls", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); return emit_VRR_VVVM(p, 0xE70000000095ULL, v1, v2, v3, m4); } @@ -5943,7 +5948,7 @@ static UChar * s390_emit_VREP(UChar *p, UChar v1, UChar v3, UShort i2, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vrep"), VR(v1), VR(v3), UINT(i2), UINT(m4)); + S390_DISASM(XMNM("vrep", va_like_disasm), VR(v1), VR(v3), UINT(i2), MASK(m4)); return emit_VRI_VVMM(p, 0xE7000000004DULL, v1, v3, i2, m4); } @@ -5953,7 +5958,7 @@ static UChar * s390_emit_VREPI(UChar *p, UChar v1, UShort i2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vrepi"), VR(v1), UINT(i2), UINT(m3)); + S390_DISASM(XMNM("vrepi", va_like_disasm), VR(v1), INT((Short)i2), MASK(m3)); return emit_VRI_VIM(p, 0xE70000000045ULL, v1, i2, m3); } @@ -5963,7 +5968,7 @@ static UChar * s390_emit_VUPH(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vuph"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vuph", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE700000000D7ULL, v1, v2, m3); } @@ -5973,7 +5978,7 @@ static UChar * s390_emit_VUPLH(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vuplh"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vuplh", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE700000000D5ULL, v1, v2, m3); } @@ -5983,7 +5988,7 @@ static UChar* s390_emit_VMRH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmrh"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmrh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000061ULL, v1, v2, v3, m4); } @@ -5993,7 +5998,7 @@ static UChar* s390_emit_VMRL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmrl"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmrl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000060ULL, v1, v2, v3, m4); } @@ -6002,7 +6007,7 @@ static UChar * s390_emit_VA(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("va"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("va", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000f3ULL, v1, v2, v3, m4); } @@ -6011,7 +6016,7 @@ static UChar * s390_emit_VS(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vs"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vs", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000f7ULL, v1, v2, v3, m4); } @@ -6029,7 +6034,8 @@ static UChar * s390_emit_VCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vch"), VR(v1), VR(v2), VR(v3), UINT(m4)); + /* fixs390: m5 = 0 --> condition code not set */ + S390_DISASM(XMNM("vch", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); return emit_VRR_VVVM(p, 0xE700000000fbULL, v1, v2, v3, m4); } @@ -6038,7 +6044,8 @@ static UChar * s390_emit_VCHL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vchl"), VR(v1), VR(v2), VR(v3), UINT(m4)); + /* fixs390: m5 = 0 --> condition code not set */ + S390_DISASM(XMNM("vchl", vch_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(0)); return emit_VRR_VVVM(p, 0xE700000000f9ULL, v1, v2, v3, m4); } @@ -6047,7 +6054,7 @@ static UChar * s390_emit_VCLZ(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vclz"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vclz", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE70000000053ULL, v1, v2, m3); } @@ -6056,7 +6063,7 @@ static UChar * s390_emit_VCTZ(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vctz"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vctz", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE70000000052ULL, v1, v2, m3); } @@ -6065,7 +6072,7 @@ static UChar * s390_emit_VPOPCT(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vpopct"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vpopct", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE70000000050ULL, v1, v2, m3); } @@ -6074,7 +6081,7 @@ static UChar * s390_emit_VMX(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmx"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmx", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000ffULL, v1, v2, v3, m4); } @@ -6083,7 +6090,7 @@ static UChar * s390_emit_VMXL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmxl"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmxl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000fdULL, v1, v2, v3, m4); } @@ -6092,7 +6099,7 @@ static UChar * s390_emit_VMN(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmn"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmn", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000feULL, v1, v2, v3, m4); } @@ -6101,7 +6108,7 @@ static UChar * s390_emit_VMNL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmnl"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmnl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000fcULL, v1, v2, v3, m4); } @@ -6110,7 +6117,7 @@ static UChar * s390_emit_VAVG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vavg"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vavg", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000f2ULL, v1, v2, v3, m4); } @@ -6119,7 +6126,7 @@ static UChar * s390_emit_VAVGL(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vavgl"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vavgl", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000f0ULL, v1, v2, v3, m4); } @@ -6128,7 +6135,7 @@ static UChar * s390_emit_VLP(UChar *p, UChar v1, UChar v2, UChar m3) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vlp"), VR(v1), VR(v2), UINT(m3)); + S390_DISASM(XMNM("vlp", va_like_disasm), VR(v1), VR(v2), MASK(m3)); return emit_VRR_VVM(p, 0xE700000000DFULL, v1, v2, m3); } @@ -6137,7 +6144,7 @@ static UChar * s390_emit_VMH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmh"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000a3ULL, v1, v2, v3, m4); } @@ -6146,7 +6153,7 @@ static UChar * s390_emit_VMLH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmlh"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmlh", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000a1ULL, v1, v2, v3, m4); } @@ -6155,7 +6162,7 @@ static UChar * s390_emit_VML(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vml"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vml", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000a2ULL, v1, v2, v3, m4); } @@ -6164,7 +6171,7 @@ static UChar * s390_emit_VME(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vme"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vme", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000a6ULL, v1, v2, v3, m4); } @@ -6173,7 +6180,7 @@ static UChar * s390_emit_VMLE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vmle"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vmle", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE700000000a4ULL, v1, v2, v3, m4); } @@ -6182,7 +6189,7 @@ static UChar * s390_emit_VESLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("veslv"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("veslv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000070ULL, v1, v2, v3, m4); } @@ -6191,7 +6198,7 @@ static UChar * s390_emit_VESRAV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vesrav"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vesrav", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE7000000007aULL, v1, v2, v3, m4); } @@ -6200,7 +6207,7 @@ static UChar * s390_emit_VESRLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vesrlv"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vesrlv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000078ULL, v1, v2, v3, m4); } @@ -6209,7 +6216,7 @@ static UChar * s390_emit_VESL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vesl"), VR(v1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vesl", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); return emit_VRS(p, 0xE70000000030ULL, v1, b2, d2, v3, m4); } @@ -6218,7 +6225,7 @@ static UChar * s390_emit_VESRA(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vesra"), VR(v1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vesra", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); return emit_VRS(p, 0xE7000000003aULL, v1, b2, d2, v3, m4); } @@ -6227,7 +6234,7 @@ static UChar * s390_emit_VESRL(UChar *p, UChar v1, UChar b2, UShort d2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vesrl"), VR(v1), UDXB(d2, 0, b2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vesrl", va_like_disasm), VR(v1), VR(v3), UDXB(d2, 0, b2), MASK(m4)); return emit_VRS(p, 0xE70000000038ULL, v1, b2, d2, v3, m4); } @@ -6236,7 +6243,7 @@ static UChar * s390_emit_VERLLV(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("verllv"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("verllv", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000073ULL, v1, v2, v3, m4); } @@ -6299,7 +6306,7 @@ static UChar * s390_emit_VSUM(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsum"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vsum", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000064ULL, v1, v2, v3, m4); } @@ -6308,7 +6315,7 @@ static UChar * s390_emit_VSUMG(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsumg"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vsumg", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000065ULL, v1, v2, v3, m4); } @@ -6317,7 +6324,7 @@ static UChar * s390_emit_VSUMQ(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vsumq"), VR(v1), VR(v2), VR(v3), UINT(m4)); + S390_DISASM(XMNM("vsumq", va_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4)); return emit_VRR_VVVM(p, 0xE70000000067ULL, v1, v2, v3, m4); } @@ -6390,7 +6397,7 @@ s390_emit_VFMA(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfma"), VR(v1), VR(v2), VR(v3), VR(v4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM("vfma", vfms_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); return emit_VRRe_VVVVMM(p, 0xE7000000008fULL, v1, v2, v3, v4, m5, m6); } @@ -6400,7 +6407,7 @@ s390_emit_VFMS(UChar *p, UChar v1, UChar v2, UChar v3, UChar v4, UChar m5, UChar m6) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfms"), VR(v1), VR(v2), VR(v3), VR(v4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM("vfms", vfms_like_disasm), VR(v1), VR(v2), VR(v3), VR(v4), MASK(m5), MASK(m6)); return emit_VRRe_VVVVMM(p, 0xE7000000008eULL, v1, v2, v3, v4, m5, m6); } @@ -6410,7 +6417,7 @@ s390_emit_VFCE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfce"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM("vfce", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); return emit_VRR_VVVMMM(p, 0xE700000000e8ULL, v1, v2, v3, m4, m5, m6); } @@ -6420,7 +6427,7 @@ s390_emit_VFCH(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfch"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM("vfch", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); return emit_VRR_VVVMMM(p, 0xE700000000ebULL, v1, v2, v3, m4, m5, m6); } @@ -6430,7 +6437,7 @@ s390_emit_VFCHE(UChar *p, UChar v1, UChar v2, UChar v3, UChar m4, UChar m5, UChar m6) { if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) - S390_DISASM(MNM("vfche"), VR(v1), VR(v2), VR(v3), UINT(m4), UINT(m5), UINT(m6)); + S390_DISASM(XMNM("vfche", vfce_like_disasm), VR(v1), VR(v2), VR(v3), MASK(m4), MASK(m5), MASK(m6)); return emit_VRR_VVVMMM(p, 0xE700000000eaULL, v1, v2, v3, m4, m5, m6); } diff --git a/VEX/priv/s390_disasm.c b/VEX/priv/s390_disasm.c index 27a7d6aac..d55ca5b79 100644 --- a/VEX/priv/s390_disasm.c +++ b/VEX/priv/s390_disasm.c @@ -35,7 +35,7 @@ #include "s390_disasm.h" static HChar *s390_disasm_aux(const s390_opnd *, const HChar *, HChar *, - Int (*)(UInt, UInt)); + Int (*)(UInt, UInt, UInt *)); /* Return the mnemonic padded with blanks to its right */ static const HChar * @@ -202,38 +202,58 @@ dvb_operand(HChar *p, UInt d, UInt v, UInt b, Bool displacement_is_signed) } else { p += vex_sprintf(p, "%u", d); } - if (v != 0) { - p += vex_sprintf(p, "(%s", vr_operand(v)); - if (b != 0) { - p += vex_sprintf(p, ",%s", gpr_operand(b)); - } - p += vex_sprintf(p, ")"); - } else { - if (b != 0) { - p += vex_sprintf(p, "(%s)", gpr_operand(b)); - } - } + p += vex_sprintf(p, "(%s", vr_operand(v)); + p += vex_sprintf(p, ",%s", gpr_operand(b)); + p += vex_sprintf(p, ")"); return p; } -/* It is expected that OPNDS contains exactly one MASK operand. Return - its index. Assert, if there is no mask or multiple mask fields. */ +/* Return the number of MASK operands */ static UInt -unique_mask_index(const s390_opnd *opnds) +mask_count(const s390_opnd *opnds) { - UInt num_masks, mask_ix = 0; // silence GCC + UInt num_masks = 0; - num_masks = 0; for (UInt ix = 0; opnds[ix].kind != S390_OPND_DONE; ++ix) { if (opnds[ix].kind == S390_OPND_MASK) { ++num_masks; - mask_ix = ix; } } - vassert(num_masks == 1); - return mask_ix; + return num_masks; +} + + +/* Given the mask number return its index in the operands array. + Mask numbers begin at 1. */ +static UInt +get_mask_index(const s390_opnd *opnds, UInt mask_no) +{ + vassert(mask_no <= mask_count(opnds)); + + UInt count = 0; + + for (UInt ix = 0; opnds[ix].kind != S390_OPND_DONE; ++ix) { + if (opnds[ix].kind == S390_OPND_MASK) { + ++count; + if (count == mask_no) + return ix; + } + } + /* not reachable */ + return 0; +} + + +/* It is expected that OPNDS contains exactly one MASK operand. Return + its index. Assert, if there is no mask or multiple mask fields. */ +static UInt +unique_mask_index(const s390_opnd *opnds) +{ + vassert(mask_count(opnds) == 1); + + return get_mask_index(opnds, 1); } @@ -309,10 +329,12 @@ brcl_disasm(const s390_opnd *opnds, HChar *p) } -/* Return 1, if mask should be printed */ +/* Return 1, if mask should be printed. In *VALUE return the mask value + that should be printed. */ static Int -cabt_mdf(UInt ix __attribute__((unused)), UInt mask) +cabt_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) { + *value = mask; return (mask & 1) || mask == 0 || mask == 14; } @@ -344,13 +366,14 @@ cabt_disasm(const s390_opnd *opnds, HChar *p) } *x = '\0'; - return s390_disasm_aux(opnds, xmnm, p, cabt_mdf); + return s390_disasm_aux(opnds, xmnm, p, cabt_mh); } static Int -cls_mdf(UInt ix __attribute__((unused)), UInt mask) +cls_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) { + *value = mask; return mask == 0 || mask == 15; } @@ -366,13 +389,14 @@ cls_disasm(const s390_opnd *opnds, HChar *p) const HChar *base = opnds[0].xmnm.base; const HChar *xmnm = construct_mnemonic(base, "", mask); - return s390_disasm_aux(opnds, xmnm, p, cls_mdf); + return s390_disasm_aux(opnds, xmnm, p, cls_mh); } static Int -bic_mdf(UInt ix __attribute__((unused)), UInt mask) +bic_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) { + *value = mask; return mask == 0; } @@ -391,14 +415,569 @@ bic_disasm(const s390_opnd *opnds, HChar *p) xmnm = construct_mnemonic("bi", "", mask); } - return s390_disasm_aux(opnds, xmnm, p, bic_mdf); + return s390_disasm_aux(opnds, xmnm, p, bic_mh); +} + + +/* Special handling for the VGBM opcode */ +HChar * +vgbm_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar *xmnm; + const HChar *v1 = vr_operand(opnds[1].regno); + UInt i2 = opnds[2].u; + + if (i2 == 0) { + xmnm = padmnm("vzero"); + p += vex_sprintf(p, "%s %s", xmnm, v1); + } else if (i2 == 0xffff) { + xmnm = padmnm("vone"); + p += vex_sprintf(p, "%s %s", xmnm, v1); + } else { + xmnm = padmnm(opnds[0].xmnm.base); + p += vex_sprintf(p, "%s %s,%u", xmnm, v1, i2); + } + return p; +} + + +static Int +mask0_mh(UInt ix __attribute__((unused)), UInt mask, UInt *value) +{ + *value = mask; + return mask != 0; +} + + +/* Write out the operands, except if the unique mask is 0 do not write it */ +HChar * +mask0_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 1); + + const HChar *mnm = opnds[0].xmnm.base; + + return s390_disasm_aux(opnds, mnm, p, mask0_mh); +} + + +/* Opcode is expected to have a single MASK operand. Use its value + to determine a single-character suffix to be appended to the base + mnemonic. The mask itself is not printed. */ +HChar * +va_like_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar suffix[] = { 'b', 'h', 'f', 'g', 'q' }; + const HChar *base = opnds[0].xmnm.base; + UInt mask = opnds[unique_mask_index(opnds)].mask; + HChar xmnm[vex_strlen(base) + 2 + 1]; + HChar extra = '\0'; + + vassert(mask < sizeof suffix); + + if (mask == 1 && + (vex_streq(base, "vupl") || vex_streq(base, "vmal") || + vex_streq(base, "vml"))) { + extra = 'w'; + } + vex_sprintf(xmnm, "%s%c%c", base, suffix[mask], extra); + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +/* Opcode is expected to have two MASK operands. Use their values + to determine a suffix to be appended to the base mnemonic. The + masks themselves are not printed. */ +HChar * +vch_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix1[] = { 'b', 'h', 'f', 'g' }; + const HChar suffix2[] = { '\0', 's' }; + const HChar *base = opnds[0].xmnm.base; + UInt m4 = opnds[get_mask_index(opnds, 1)].mask; + UInt m5 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + 2 + 1]; + + vassert(m4 < sizeof suffix1); + vassert(m5 < sizeof suffix2); + + vex_sprintf(xmnm, "%s%c%c", base, suffix1[m4], suffix2[m5]); + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +static Int +always_mh(UInt ix __attribute__((unused)), + UInt mask, UInt *value) +{ + *value = mask; + return 1; +} + + +HChar * +vfce_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 3); + + const HChar suffix1[][3] = { "sb", "db", "xb" }; + const HChar suffix2[] = { '\0', 's' }; + const HChar *base = opnds[0].xmnm.base; + UInt m4 = opnds[get_mask_index(opnds, 1)].mask; + UInt m5 = opnds[get_mask_index(opnds, 2)].mask; + UInt m6 = opnds[get_mask_index(opnds, 3)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix1 - 1) + 1 + 1]; + + if (m4 == 4 && (m5 == 0 || m5 == 4)) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m4 - 2 < sizeof suffix1 / sizeof *suffix1); + vassert(m6 < sizeof suffix2); + + vex_sprintf(xmnm, "%s%s%c", base, suffix1[m4 - 2], suffix2[m6]); + + if (m5 & 0x8) xmnm[0] = 'w'; + if (m5 & 0x4) xmnm[2] = 'k'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +HChar * +vfmix_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[][3] = { "sb", "db", "xb" }; + const HChar *base = opnds[0].xmnm.base; + UInt m4 = opnds[get_mask_index(opnds, 1)].mask; + UInt m5 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + if (m4 == 4 && m5 == 0) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m4 - 2 < sizeof suffix / sizeof *suffix); + + vex_sprintf(xmnm, "%s%s", base, suffix[m4 - 2]); + + if (m5 & 0x8) xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +HChar * +vfa_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[][3] = { "sb", "db", "xb" }; + const HChar *base = opnds[0].xmnm.base; + UInt m4 = opnds[get_mask_index(opnds, 1)].mask; + UInt m5 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + if (m4 == 4 && m5 == 0) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m4 - 2 < sizeof suffix / sizeof *suffix); + + vex_sprintf(xmnm, "%s%s", base, suffix[m4 - 2]); + + if (m5 & 0x8) xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +/* Also used for VFEE, VFENE, and VSTRS. But for those opcodes m5 < 8. + Hence, the return value is 0 and no mask will be written for + those opcodes. */ +static Int +vfae_mh(UInt ix, UInt mask, UInt *value) +{ + *value = mask & 0xC; + return (ix == 5) && (mask & 0xC); +} + + +HChar * +vfae_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[] = { 'b', 'h', 'f' }; + const HChar *base = opnds[0].xmnm.base; + + UInt m4 = opnds[get_mask_index(opnds, 1)].mask; + UInt m5 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + 3 + 1]; + + HChar s = (m5 & 0x1) ? 's' : '\0'; + HChar z = (m5 & 0x2) ? 'z' : '\0'; + + vex_sprintf(xmnm, "%s%c%c%c", base, z, suffix[m4], s); + + return s390_disasm_aux(opnds, xmnm, p, vfae_mh); +} + + +HChar * +vfms_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[][3] = { "sb", "db", "xb" }; + const HChar *base = opnds[0].xmnm.base; + UInt m5 = opnds[get_mask_index(opnds, 1)].mask; + UInt m6 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + if (m6 == 4 && m5 == 0) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m6 - 2 < sizeof suffix / sizeof *suffix); + + vex_sprintf(xmnm, "%s%s", base, suffix[m6 - 2]); + + if (m5 & 0x8) xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +static Int +vmsl_mh(UInt ix, UInt mask, UInt *value) +{ + *value = mask; + return ix == 6; +} + + +HChar * +vmsl_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[] = { 'g' }; + const HChar *base = opnds[0].xmnm.base; + UInt m5 = opnds[get_mask_index(opnds, 1)].mask; + /* m6 does not influence the extended mnemonic */ + HChar xmnm[vex_strlen(base) + 1 + 1]; + + vassert(m5 - 3 < sizeof suffix); + + vex_sprintf(xmnm, "%s%c", base, suffix[m5 - 3]); + + return s390_disasm_aux(opnds, xmnm, p, vmsl_mh); +} + + +static Int +vstrc_mh(UInt ix, UInt mask, UInt *value) +{ + *value = mask & 0xC; + return (ix == 6) && (mask & 0xC); +} + + +HChar * +vstrc_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[] = { 'b', 'h', 'f' }; + const HChar *base = opnds[0].xmnm.base; + + UInt m5 = opnds[get_mask_index(opnds, 1)].mask; + UInt m6 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(base) + 3 + 1]; + + HChar s = (m6 & 0x1) ? 's' : '\0'; + HChar z = (m6 & 0x2) ? 'z' : '\0'; + + vex_sprintf(xmnm, "%s%c%c%c", base, z, suffix[m5], s); + + return s390_disasm_aux(opnds, xmnm, p, vstrc_mh); +} + + +HChar * +vllebrz_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 1); + + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + const HChar *xmnm; + + switch (m3) { + case 1: xmnm = "vllebrzh"; break; + case 2: xmnm = "vllebrzf"; break; + case 3: xmnm = "ldrv"; break; + case 6: xmnm = "lerv"; break; + default: vassert(0); + } + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +HChar * +vstebrf_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 1); + + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + const HChar *xmnm; + + if (m3 == 0) + xmnm = "sterv"; + else + xmnm = opnds[0].xmnm.base; + + return s390_disasm_aux(opnds, xmnm, p, mask0_mh); +} + + +HChar * +vstebrg_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 1); + + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + const HChar *xmnm; + + if (m3 == 0) + xmnm = "stdrv"; + else + xmnm = opnds[0].xmnm.base; + + return s390_disasm_aux(opnds, xmnm, p, mask0_mh); +} + + +HChar * +vllez_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 1); + + const HChar suffix[][3] = { "b", "h", "f", "g", "", "", "lf" }; + const HChar *base = opnds[0].xmnm.base; + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + vassert(m3 < sizeof suffix / sizeof *suffix); + vex_sprintf(xmnm, "%s%s", base, suffix[m3]); + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +HChar * +wfc_like_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[][3] = { "sb", "db", "xb" }; + const HChar *base = opnds[0].xmnm.base; + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + vassert(m3 - 2 < sizeof suffix / sizeof *suffix); + + vex_sprintf(xmnm, "%s%s", base, suffix[m3 - 2]); + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +HChar * +vfll_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[] = { 's', 'd' }; + 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; + HChar xmnm[vex_strlen(base) + 1 + 1]; + + if (m3 == 3 && m4 == 0) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m3 - 2 < sizeof suffix); + vex_sprintf(xmnm, "%s%c", base, suffix[m3 - 2]); + + if (m4 == 8) + xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +static Int +always_m4(UInt ix, UInt mask, UInt *value) +{ + *value = mask & 0x4; + return ix == 4; +} + + +HChar * +vflr_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[] = { 'd', 'x' }; + 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; + HChar xmnm[vex_strlen(base) + 1 + 1]; + + if (m3 == 4 && m4 < 8) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m3 - 3 < sizeof suffix); + vex_sprintf(xmnm, "%s%c", base, suffix[m3 - 3]); + + if (m4 & 0x8) + xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, always_m4); +} + + +HChar * +vfi_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 2); + + const HChar suffix[][3] = { "sb", "db", "xb" }; + 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; + HChar xmnm[vex_strlen(base) + (sizeof *suffix - 1) + 1]; + + if (m3 == 4 && m4 < 8) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(m3 - 2 < sizeof suffix / sizeof *suffix); + vex_sprintf(xmnm, "%s%s", base, suffix[m3 - 2]); + + if (m4 & 0x8) + xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, always_m4); +} + + +HChar * +vfpso_disasm(const s390_opnd *opnds, HChar *p) +{ + vassert(mask_count(opnds) == 3); + + const HChar suffix1[] = { 'c', 'n', 'p' }; + const HChar suffix2[][3] = { "sb", "db", "xb" }; + 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 m5 = opnds[get_mask_index(opnds, 3)].mask; + HChar xmnm[vex_strlen(base) + 1 + (sizeof *suffix2 - 1) + 1]; + + if (m3 == 4 && m4 == 0) + return s390_disasm_aux(opnds, base, p, always_mh); + + vassert(vex_strlen("vfl") <= vex_strlen(base)); + vassert(m5 < sizeof suffix1); + vassert(m3 - 2 < sizeof suffix2 / sizeof *suffix2); + vex_sprintf(xmnm, "%s%c%s", "vfl", suffix1[m5], suffix2[m3 - 2]); + + if (m4 & 0x8) + xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, NULL); +} + + +static Int +vcgd_mh(UInt ix, UInt mask, UInt *value) +{ + *value = mask; + if (ix == 5) + return 1; + if (ix == 4) { + if (mask >= 8) + *value = mask - 8; + return 1; + } + return 0; +} + + +static HChar * +vcgd_like_disasm(const s390_opnd *opnds, const HChar *mnm[2], HChar *p) +{ + vassert(mask_count(opnds) == 3); + vassert(vex_strlen(mnm[0]) == vex_strlen(mnm[1])); + + UInt m3 = opnds[get_mask_index(opnds, 1)].mask; + UInt m4 = opnds[get_mask_index(opnds, 2)].mask; + HChar xmnm[vex_strlen(mnm[0]) + 1]; + + vex_sprintf(xmnm, "%s", mnm[m3 - 2]); + if (m4 & 0x8) + xmnm[0] = 'w'; + + return s390_disasm_aux(opnds, xmnm, p, vcgd_mh); +} + + +HChar * +vcgd_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar *mnm[2] = { "vcfeb", "vcgdb" }; + + return vcgd_like_disasm(opnds, mnm, p); +} + + +HChar * +vcdg_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar *mnm[2] = { "vcefb", "vcdgb" }; + + return vcgd_like_disasm(opnds, mnm, p); +} + + +HChar * +vclgd_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar *mnm[2] = { "vclfeb", "vclgdb" }; + + return vcgd_like_disasm(opnds, mnm, p); +} + + +HChar * +vcgld_disasm(const s390_opnd *opnds, HChar *p) +{ + const HChar *mnm[2] = { "vcelfb", "vcdlgb" }; + + return vcgd_like_disasm(opnds, mnm, p); } -/* Write out OPNDS. */ +/* 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 * s390_disasm_aux(const s390_opnd *opnds, const HChar *xmnm, HChar *p, - Int (*mdf)(UInt, UInt)) + Int (*mh)(UInt, UInt, UInt *)) { vassert(opnds[0].kind == S390_OPND_MNM || opnds[0].kind == S390_OPND_XMNM); @@ -438,9 +1017,10 @@ s390_disasm_aux(const s390_opnd *opnds, const HChar *xmnm, HChar *p, p += vex_sprintf(p, "%s", vr_operand(opnd->regno)); break; - case S390_OPND_MASK: - if (mdf && mdf(ix, opnd->mask)) - p += vex_sprintf(p, "%u", opnd->mask); + case S390_OPND_MASK: { + UInt value; + if (mh && mh(ix, opnd->mask, &value)) + p += vex_sprintf(p, "%u", value); else { if (ix != 1) (*--p) = '\0'; // overwrite the separator @@ -448,6 +1028,7 @@ s390_disasm_aux(const s390_opnd *opnds, const HChar *xmnm, HChar *p, separator = 0; } continue; // *not* break + } case S390_OPND_UINT: p += vex_sprintf(p, "%u", opnd->u); diff --git a/VEX/priv/s390_disasm.h b/VEX/priv/s390_disasm.h index 4010d6bfc..89fc9e8de 100644 --- a/VEX/priv/s390_disasm.h +++ b/VEX/priv/s390_disasm.h @@ -111,6 +111,30 @@ HChar *bic_disasm(const s390_opnd *, HChar *); HChar *cls_disasm(const s390_opnd *, HChar *); HChar *brcl_disasm(const s390_opnd *, HChar *); HChar *cabt_disasm(const s390_opnd *, HChar *); +HChar *mask0_disasm(const s390_opnd *, HChar *); +HChar *vcdg_disasm(const s390_opnd *, HChar *); +HChar *vcgd_disasm(const s390_opnd *, HChar *); +HChar *vcgld_disasm(const s390_opnd *, HChar *); +HChar *vclgd_disasm(const s390_opnd *, HChar *); +HChar *vfi_disasm(const s390_opnd *, HChar *); +HChar *vfll_disasm(const s390_opnd *, HChar *); +HChar *vflr_disasm(const s390_opnd *, HChar *); +HChar *vfms_like_disasm(const s390_opnd *, HChar *); +HChar *vfpso_disasm(const s390_opnd *, HChar *); +HChar *vgbm_disasm(const s390_opnd *, HChar *); +HChar *vllez_disasm(const s390_opnd *, HChar *); +HChar *vllebrz_disasm(const s390_opnd *, HChar *); +HChar *vmsl_disasm(const s390_opnd *, HChar *); +HChar *vstebrf_disasm(const s390_opnd *, HChar *); +HChar *vstebrg_disasm(const s390_opnd *, HChar *); +HChar *vstrc_disasm(const s390_opnd *, HChar *); +HChar *va_like_disasm(const s390_opnd *, HChar *); +HChar *vch_like_disasm(const s390_opnd *, HChar *); +HChar *vfa_like_disasm(const s390_opnd *, HChar *); +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 *); /*---------------------------------------------------------------*/ /*--- end s390_disasm.h ---*/