]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 404406 - s390x: implement z14 miscellaneous instructions
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 16 May 2019 10:34:37 +0000 (12:34 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Wed, 12 Jun 2019 18:19:33 +0000 (20:19 +0200)
(from bug 404406 comment 0):
Valgrind on s390x currently lacks support for the miscellaneous
instruction extensions facility 2.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
13 files changed:
NEWS
VEX/priv/guest_s390_defs.h
VEX/priv/guest_s390_helpers.c
VEX/priv/guest_s390_toIR.c
VEX/priv/host_s390_defs.c
VEX/priv/host_s390_isel.c
VEX/priv/main_main.c
VEX/priv/s390_disasm.c
VEX/priv/s390_disasm.h
VEX/pub/libvex.h
VEX/pub/libvex_s390x_common.h
coregrind/m_machine.c
docs/internals/s390-opcodes.csv

diff --git a/NEWS b/NEWS
index 905a868417de37b447d93a7307532d439d1b5a83..770a231788493b496b890ce722af2a0fa82ba556 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -54,6 +54,7 @@ where XXXXXX is the bug number as listed below.
 407764  drd cond_post_wait gets wrong (?) condition on s390x z13 system
 408009  Expose rdrand and f16c even on avx if host cpu supports them
 408091  Missing pkey syscalls
+404406  s390x: z14 miscellaneous instructions not implemented
 n-i-bz  Fix minor one time leaks in dhat.
 n-i-bz  Add --run-cxx-freeres=no in outer args to avoid inner crashes.
 
index 0185de5fd547ad85892d43f1949283fae2d94449..1470558ceec1c5818f66549c5de1140b1f560f9e 100644 (file)
@@ -158,7 +158,9 @@ enum {
    S390_CC_OP_DFP_128_TO_INT_64 = 57,
    S390_CC_OP_PFPO_32 = 58,
    S390_CC_OP_PFPO_64 = 59,
-   S390_CC_OP_PFPO_128 = 60
+   S390_CC_OP_PFPO_128 = 60,
+   S390_CC_OP_MUL_32 = 61,
+   S390_CC_OP_MUL_64 = 62
 };
 
 /*------------------------------------------------------------*/
index 63ee68b24c10a4fbcc2733d7010c1f278ea706f9..525e7000cf2573102ceac0ce3a0be39f2697b832 100644 (file)
@@ -990,6 +990,16 @@ decode_bfp_rounding_mode(UInt irrm)
    psw >> 28;   /* cc */ \
 })
 
+#define S390_CC_FOR_TERNARY(opcode,cc_dep1,cc_dep2) \
+({ \
+   __asm__ volatile ( \
+        opcode ",%[op1],%[op1],%[op2],0\n\t" \
+        "ipm %[psw]\n\t"           : [psw] "=d"(psw), [op1] "+d"(cc_dep1) \
+                                   : [op2] "d"(cc_dep2) \
+                                   : "cc");\
+   psw >> 28;   /* cc */ \
+})
+
 #define S390_CC_FOR_TERNARY_SUBB(opcode,cc_dep1,cc_dep2,cc_ndep) \
 ({ \
    /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \
@@ -1802,6 +1812,12 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep)
       return psw >> 28;  /* cc */
    }
 
+   case S390_CC_OP_MUL_32:
+      return S390_CC_FOR_TERNARY(".insn rrf,0xb9fd0000", cc_dep1, cc_dep2);
+
+   case S390_CC_OP_MUL_64:
+      return S390_CC_FOR_TERNARY(".insn rrf,0xb9ed0000", cc_dep1, cc_dep2);
+
    default:
       break;
    }
index 076a4211facb15a2910cbeb6cc4460d611de0428..06ec27fae0edc2f40526f7168986059b9e0a00a7 100644 (file)
@@ -49,7 +49,7 @@
 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);
 
 /*------------------------------------------------------------*/
 /*--- Globals                                              ---*/
@@ -3314,8 +3314,12 @@ s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
 
    mnm = irgen(r1, op2addr);
 
-   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
-      s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) {
+      if (irgen == s390_irgen_BIC)
+         s390_disasm(ENC2(XMNM, SDXB), S390_XMNM_BIC, r1, dh2, dl2, x2, b2);
+      else
+         s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
+   }
 }
 
 static void
@@ -4280,6 +4284,22 @@ s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
    return "ahik";
 }
 
+static const HChar *
+s390_irgen_AGH(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I64);
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I64);
+
+   assign(op1, get_gpr_dw0(r1));
+   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
+   assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
+   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
+   put_gpr_dw0(r1, mkexpr(result));
+
+   return "agh";
+}
+
 static const HChar *
 s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
 {
@@ -5197,6 +5217,24 @@ s390_irgen_BCTG(UChar r1, IRTemp op2addr)
    return "bctg";
 }
 
+static const HChar *
+s390_irgen_BIC(UChar r1, IRTemp op2addr)
+{
+   IRTemp cond = newTemp(Ity_I32);
+
+   if (r1 == 0) {
+      /* nothing */
+   } else if (r1 == 15) {
+      always_goto(load(Ity_I64, mkexpr(op2addr)));
+   } else {
+      assign(cond, s390_call_calculate_cond(r1));
+      if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
+                                 load(Ity_I64, mkexpr(op2addr)));
+   }
+
+   return "bic";
+}
+
 static const HChar *
 s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
 {
@@ -8333,6 +8371,54 @@ s390_irgen_MFY(UChar r1, IRTemp op2addr)
    return "mfy";
 }
 
+static const HChar *
+s390_irgen_MG(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I64);
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I128);
+
+   assign(op1, get_gpr_dw0(r1 + 1));
+   assign(op2, load(Ity_I64, mkexpr(op2addr)));
+   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
+   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
+   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
+
+   return "mg";
+}
+
+static const HChar *
+s390_irgen_MGH(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I64);
+   IRTemp op2 = newTemp(Ity_I16);
+   IRTemp result = newTemp(Ity_I128);
+
+   assign(op1, get_gpr_dw0(r1));
+   assign(op2, load(Ity_I16, mkexpr(op2addr)));
+   assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64, mkexpr(op2))
+   ));
+   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
+
+   return "mgh";
+}
+
+static const HChar *
+s390_irgen_MGRK(UChar r3, UChar r1, UChar r2)
+{
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp op3 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I128);
+
+   assign(op2, get_gpr_dw0(r2));
+   assign(op3, get_gpr_dw0(r3));
+   assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
+   put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
+   put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
+
+   return "mgrk";
+}
+
 static const HChar *
 s390_irgen_MH(UChar r1, IRTemp op2addr)
 {
@@ -8522,6 +8608,38 @@ s390_irgen_MS(UChar r1, IRTemp op2addr)
    return "ms";
 }
 
+static const HChar *
+s390_irgen_MSC(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I32);
+   IRTemp op2 = newTemp(Ity_I32);
+   IRTemp result = newTemp(Ity_I64);
+
+   assign(op1, get_gpr_w1(r1));
+   assign(op2, load(Ity_I32, mkexpr(op2addr)));
+   assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
+   s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op1, op2);
+   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
+
+   return "msc";
+}
+
+static const HChar *
+s390_irgen_MSRKC(UChar r3, UChar r1, UChar r2)
+{
+   IRTemp op2 = newTemp(Ity_I32);
+   IRTemp op3 = newTemp(Ity_I32);
+   IRTemp result = newTemp(Ity_I64);
+
+   assign(op2, get_gpr_w1(r2));
+   assign(op3, get_gpr_w1(r3));
+   assign(result, binop(Iop_MullS32, mkexpr(op2), mkexpr(op3)));
+   s390_cc_thunk_putSS(S390_CC_OP_MUL_32, op2, op3);
+   put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
+
+   return "msrkc";
+}
+
 static const HChar *
 s390_irgen_MSY(UChar r1, IRTemp op2addr)
 {
@@ -8552,6 +8670,22 @@ s390_irgen_MSG(UChar r1, IRTemp op2addr)
    return "msg";
 }
 
+static const HChar *
+s390_irgen_MSGC(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I64);
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I128);
+
+   assign(op1, get_gpr_dw0(r1));
+   assign(op2, load(Ity_I64, mkexpr(op2addr)));
+   assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
+   s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op1, op2);
+   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
+
+   return "msgc";
+}
+
 static const HChar *
 s390_irgen_MSGF(UChar r1, IRTemp op2addr)
 {
@@ -8599,6 +8733,22 @@ s390_irgen_MSGFI(UChar r1, UInt i2)
    return "msgfi";
 }
 
+static const HChar *
+s390_irgen_MSGRKC(UChar r3, UChar r1, UChar r2)
+{
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp op3 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I128);
+
+   assign(op2, get_gpr_dw0(r2));
+   assign(op3, get_gpr_dw0(r3));
+   assign(result, binop(Iop_MullS64, mkexpr(op2), mkexpr(op3)));
+   s390_cc_thunk_putSS(S390_CC_OP_MUL_64, op2, op3);
+   put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
+
+   return "msgrkc";
+}
+
 static const HChar *
 s390_irgen_OR(UChar r1, UChar r2)
 {
@@ -10060,6 +10210,22 @@ s390_irgen_SGF(UChar r1, IRTemp op2addr)
    return "sgf";
 }
 
+static const HChar *
+s390_irgen_SGH(UChar r1, IRTemp op2addr)
+{
+   IRTemp op1 = newTemp(Ity_I64);
+   IRTemp op2 = newTemp(Ity_I64);
+   IRTemp result = newTemp(Ity_I64);
+
+   assign(op1, get_gpr_dw0(r1));
+   assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
+   assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
+   s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
+   put_gpr_dw0(r1, mkexpr(result));
+
+   return "sgh";
+}
+
 static const HChar *
 s390_irgen_SH(UChar r1, IRTemp op2addr)
 {
@@ -19693,8 +19859,12 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, RRF4_r3(ovl),
                                       RRF4_r1(ovl), RRF4_r2(ovl));
                                       goto ok;
-   case 0xb9ec: /* MGRK */ goto unimplemented;
-   case 0xb9ed: /* MSGRKC */ goto unimplemented;
+   case 0xb9ec: s390_format_RRF_R0RR2(s390_irgen_MGRK, RRF4_r3(ovl),
+                                      RRF4_r1(ovl), RRF4_r2(ovl));
+                                      goto ok;
+   case 0xb9ed: s390_format_RRF_R0RR2(s390_irgen_MSGRKC, RRF4_r3(ovl),
+                                      RRF4_r1(ovl), RRF4_r2(ovl));
+                                      goto ok;
    case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, RRF3_r3(ovl),
                                      RRF3_r1(ovl), RRF3_r2(ovl),
                                      S390_XMNM_LOCR);  goto ok;
@@ -19719,7 +19889,9 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
    case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, RRF4_r3(ovl),
                                       RRF4_r1(ovl), RRF4_r2(ovl));
                                       goto ok;
-   case 0xb9fd: /* MSRKC */ goto unimplemented;
+   case 0xb9fd: s390_format_RRF_R0RR2(s390_irgen_MSRKC, RRF4_r3(ovl),
+                                      RRF4_r1(ovl), RRF4_r2(ovl));
+                                      goto ok;
    }
 
    switch ((ovl & 0xff000000) >> 24) {
@@ -20036,8 +20208,14 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
                                                 RXY_dh2(ovl));  goto ok;
-   case 0xe30000000038ULL: /* AGH */ goto unimplemented;
-   case 0xe30000000039ULL: /* SGH */ goto unimplemented;
+   case 0xe30000000038ULL: s390_format_RXY_RRRD(s390_irgen_AGH, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
+   case 0xe30000000039ULL: s390_format_RXY_RRRD(s390_irgen_SGH, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
    case 0xe3000000003aULL: s390_format_RXY_RRRD(s390_irgen_LLZRGF, RXY_r1(ovl),
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
@@ -20046,7 +20224,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
                                                 RXY_dh2(ovl));  goto ok;
-   case 0xe3000000003cULL: /* MGH */ goto unimplemented;
+   case 0xe3000000003cULL: s390_format_RXY_RRRD(s390_irgen_MGH, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
    case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, RXY_r1(ovl),
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
@@ -20059,7 +20240,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
                                                 RXY_dh2(ovl));  goto ok;
-   case 0xe30000000047ULL: /* BIC */ goto unimplemented;
+   case 0xe30000000047ULL: s390_format_RXY_RRRD(s390_irgen_BIC, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
    case 0xe30000000048ULL: /* LLGFSG */ goto unimplemented;
    case 0xe30000000049ULL: /* STGSC */ goto unimplemented;
    case 0xe3000000004cULL: /* LGG */ goto unimplemented;
@@ -20072,7 +20256,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
                                                 RXY_dh2(ovl));  goto ok;
-   case 0xe30000000053ULL: /* MSC */ goto unimplemented;
+   case 0xe30000000053ULL: s390_format_RXY_RRRD(s390_irgen_MSC, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
    case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, RXY_r1(ovl),
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
@@ -20177,8 +20364,14 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
                                                 RXY_dh2(ovl));  goto ok;
-   case 0xe30000000083ULL: /* MSGC */ goto unimplemented;
-   case 0xe30000000084ULL: /* MG */ goto unimplemented;
+   case 0xe30000000083ULL: s390_format_RXY_RRRD(s390_irgen_MSGC, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
+   case 0xe30000000084ULL: s390_format_RXY_RRRD(s390_irgen_MG, RXY_r1(ovl),
+                                                RXY_x2(ovl), RXY_b2(ovl),
+                                                RXY_dl2(ovl),
+                                                RXY_dh2(ovl));  goto ok;
    case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, RXY_r1(ovl),
                                                 RXY_x2(ovl), RXY_b2(ovl),
                                                 RXY_dl2(ovl),
index 8aa2ba67f84ba671b4da0bf5b697d54913bce00e..162550fd707c3f0d322a1807f9b5e6c0995ef5a2 100644 (file)
@@ -3023,6 +3023,26 @@ s390_emit_MFY(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
 }
 
 
+static UChar *
+s390_emit_MG(UChar *p, UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
+{
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      s390_disasm(ENC3(MNM, GPR, SDXB), "mg", r1, dh2, dl2, x2, b2);
+
+    return emit_RXY(p, 0xe30000000084ULL, r1, x2, b2, dl2, dh2);
+}
+
+
+static UChar *
+s390_emit_MGRK(UChar *p, UChar r3, UChar r1, UChar r2)
+{
+   if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM))
+      s390_disasm(ENC4(MNM, GPR, GPR, GPR), "mgrk", r1, r2, r3);
+
+   return emit_RRF3(p, 0xb9ec0000, r3, r1, r2);
+}
+
+
 static UChar *
 s390_emit_MH(UChar *p, UChar r1, UChar x2, UChar b2, UShort d2)
 {
@@ -9595,7 +9615,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn)
 
       case 8:
          if (signed_multiply)
-            vpanic("s390_insn_mul_emit");
+            return s390_emit_MGRK(buf, r1 + 1, r1, r2);
          else
             return s390_emit_MLGR(buf, r1, r2);
 
@@ -9640,7 +9660,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn)
 
       case 8:
          if (signed_multiply)
-            vpanic("s390_insn_mul_emit");
+            return s390_emit_MG(buf, r1, x, b, DISP20(d));
          else
             return s390_emit_MLG(buf, r1, x, b, DISP20(d));
 
@@ -9665,7 +9685,7 @@ s390_insn_mul_emit(UChar *buf, const s390_insn *insn)
       case 8:
          buf = s390_emit_load_64imm(buf, R0, value);
          if (signed_multiply)
-            vpanic("s390_insn_mul_emit");
+            return s390_emit_MGRK(buf, r1 + 1, r1, R0);
          else
             return s390_emit_MLGR(buf, r1, R0);
 
index 9141b7bffd18603dc42b742951a298a6ea50e247..30e5c7620bf2aa2983e8db1b04e212593bf474a6 100644 (file)
@@ -1018,6 +1018,8 @@ s390_isel_int128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env,
          goto do_multiply64;
 
       case Iop_MullS64:
+         if (!(env->hwcaps & VEX_HWCAPS_S390X_MI2))
+            goto irreducible;
          is_signed_multiply = True;
          goto do_multiply64;
 
@@ -1125,7 +1127,10 @@ s390_isel_int128_expr_wrk(HReg *dst_hi, HReg *dst_lo, ISelEnv *env,
       }
    }
 
-   vpanic("s390_isel_int128_expr");
+   /* We get here if no pattern matched. */
+ irreducible:
+   ppIRExpr(expr);
+   vpanic("s390_isel_int128_expr: cannot reduce tree");
 }
 
 
index 97c0bacd67e9051bf78ea3448efe1a4d629e2d36..3cfe8c1cb2fa231f8e28230a76cb0d9f6856d765 100644 (file)
@@ -1721,6 +1721,7 @@ static const HChar* show_hwcaps_s390x ( UInt hwcaps )
       { VEX_HWCAPS_S390X_PFPO,  "pfpo" },
       { VEX_HWCAPS_S390X_VX,    "vx" },
       { VEX_HWCAPS_S390X_MSA5,  "msa5" },
+      { VEX_HWCAPS_S390X_MI2,   "mi2" },
    };
    /* Allocate a large enough buffer */
    static HChar buf[sizeof prefix + 
index 4d3fec544ce27e85e11a303eeb6f1c7c4048b9e0..e3fbc11af539c42b9e33609b496d63a80dd9c006 100644 (file)
@@ -433,6 +433,16 @@ s390_disasm(UInt command, ...)
                the integer mask is appended as the final operand */
             if (mask == 0 || mask == 15) mask_suffix = mask;
             break;
+         case S390_XMNM_BIC:
+            mask = va_arg(args, UInt);
+            if (mask == 0) {
+               /* There is no special opcode when mask == 0. */
+               p  += vex_sprintf(p, "bic");
+               mask_suffix = mask;
+            } else {
+               p  += vex_sprintf(p, "%s", construct_mnemonic("bi", "", mask));
+            }
+            break;
          }
       }
       continue;
index 8469f72ab7e899660807a607241d7f5467733047..eec41f8ac55f43de88283d22189640ecad8105f1 100644 (file)
@@ -91,7 +91,8 @@ enum {
    S390_XMNM_LOCFHR = 13,
    S390_XMNM_LOCHI = 14,
    S390_XMNM_LOCGHI = 15,
-   S390_XMNM_LOCHHI = 16
+   S390_XMNM_LOCHHI = 16,
+   S390_XMNM_BIC = 17
 };
 
 void s390_disasm(UInt command, ...);
index 37afd185a794efec650a8f84bb4bad38b51e0368..9337a7c3292676eae2f16d5c5aa13954ef0f97fb 100644 (file)
@@ -163,6 +163,7 @@ typedef
 #define VEX_HWCAPS_S390X_PFPO  (1<<17)  /* Perform floating point ops facility */
 #define VEX_HWCAPS_S390X_VX    (1<<18)  /* Vector facility */
 #define VEX_HWCAPS_S390X_MSA5  (1<<19)  /* message security assistance facility */
+#define VEX_HWCAPS_S390X_MI2   (1<<20)  /* miscellaneous-instruction-extensions facility 2 */
 
 
 /* Special value representing all available s390x hwcaps */
@@ -179,7 +180,8 @@ typedef
                                 VEX_HWCAPS_S390X_ETF2  | \
                                 VEX_HWCAPS_S390X_PFPO  | \
                                 VEX_HWCAPS_S390X_VX    | \
-                                VEX_HWCAPS_S390X_MSA5)
+                                VEX_HWCAPS_S390X_MSA5  | \
+                                VEX_HWCAPS_S390X_MI2)
 
 #define VEX_HWCAPS_S390X(x)  ((x) & ~VEX_S390X_MODEL_MASK)
 #define VEX_S390X_MODEL(x)   ((x) &  VEX_S390X_MODEL_MASK)
index c976395fc11ac8a92b57476fb534611f5607dded..d945a44722987472f184283eff621f785f00efca 100644 (file)
@@ -99,6 +99,7 @@
 #define S390_FAC_CTREXE  50  // constrained transactional execution
 #define S390_FAC_LSC2    53  // load/store on condition 2 and load and zero rightmost byte
 #define S390_FAC_MSA5    57  // message-security-assist 5
+#define S390_FAC_MI2     58  // miscellaneous-instruction-extensions 2
 #define S390_FAC_TREXE   73  // transactional execution
 #define S390_FAC_MSA4    77  // message-security-assist 4
 #define S390_FAC_VX      129 // vector facility
index cbb88472daca7234c8ffb8247476976c2ed538bd..9eab9000f4114d1b43014b181d3d9ef0e148f696 100644 (file)
@@ -1534,7 +1534,8 @@ Bool VG_(machine_get_hwcaps)( void )
         { False, S390_FAC_LSC,   VEX_HWCAPS_S390X_LSC,   "LSC"   },
         { False, S390_FAC_PFPO,  VEX_HWCAPS_S390X_PFPO,  "PFPO"  },
         { False, S390_FAC_VX,    VEX_HWCAPS_S390X_VX,    "VX"    },
-        { False, S390_FAC_MSA5,  VEX_HWCAPS_S390X_MSA5,  "MSA5"  }
+        { False, S390_FAC_MSA5,  VEX_HWCAPS_S390X_MSA5,  "MSA5"  },
+        { False, S390_FAC_MI2,   VEX_HWCAPS_S390X_MI2,   "MI2"   },
      };
 
      /* Set hwcaps according to the detected facilities */
index 4281f240f2c35d48c3de362211f31a2f72346caf..67d75490ccbe1aa56590e99230634c7b033b461f 100644 (file)
@@ -1633,17 +1633,17 @@ wfsxb,"scalar vector fp subtract scalar extended","not implemented","arch12"
 vftcisb,"vector fp test data class immediate short","not implemented","arch12"
 wftcisb,"scalar vector fp test data class immediate scalar short","not implemented","arch12"
 wftcixb,"scalar vector fp test data class immediate scalar extended","not implemented","arch12"
-agh,"add halfword to 64 bit value","not implemented","arch12"
-bic,"branch indirect on condition","not implemented","arch12"
-bi,"unconditional indirect branch","not implemented","arch12"
-mgrk,"multiply 64x64reg -> 128","not implemented","arch12"
-mg,"multiply 64x64mem -> 128","not implemented","arch12"
-mgh,"multiply halfword 64x16mem -> 64","not implemented","arch12"
-msrkc,"multiply single 32x32 -> 32","not implemented","arch12"
-msgrkc,"multiply single 64x64 -> 64","not implemented","arch12"
-msc,"multiply single 32x32mem -> 32","not implemented","arch12"
-msgc,"multiply single 64x64mem -> 64","not implemented","arch12"
-sgh,"subtract halfword from 64 bit value","not implemented","arch12"
+agh,"add halfword to 64 bit value",implemented,"arch12"
+bic,"branch indirect on condition",implemented,"arch12"
+bi,"unconditional indirect branch",implemented,"arch12"
+mgrk,"multiply 64x64reg -> 128",implemented,"arch12"
+mg,"multiply 64x64mem -> 128",implemented,"arch12"
+mgh,"multiply halfword 64x16mem -> 64",implemented,"arch12"
+msrkc,"multiply single 32x32 -> 32",implemented,"arch12"
+msgrkc,"multiply single 64x64 -> 64",implemented,"arch12"
+msc,"multiply single 32x32mem -> 32",implemented,"arch12"
+msgc,"multiply single 64x64mem -> 64",implemented,"arch12"
+sgh,"subtract halfword from 64 bit value",implemented,"arch12"
 vlrlr,"vector load rightmost with length","not implemented","arch12"
 vlrl,"vector load rightmost with immediate length","not implemented","arch12"
 vstrlr,"vector store rightmost with length","not implemented","arch12"