DFP insns should cause an emulation failure if the host cannot
execute them. Previously, they caused a failing assertion
which was incorrect.


git-svn-id: svn://svn.valgrind.org/vex/trunk@3031 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_s390_toIR.c b/priv/guest_s390_toIR.c
index f0add1b..2463a06 100644
--- a/priv/guest_s390_toIR.c
+++ b/priv/guest_s390_toIR.c
@@ -9597,53 +9597,55 @@
 static const HChar *
 s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
-   put_dpr_dw0(r1, mkexpr(result));
-
    return (m4 == 0) ? "adtr" : "adtra";
 }
 
 static const HChar *
 s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_pair(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
+
+      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_pair(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
-   s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
-
    return (m4 == 0) ? "axtr" : "axtra";
 }
 
@@ -9687,15 +9689,17 @@
 s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I32);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I32);
 
-      assign(op2, get_gpr_w1(r2));
-      put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
+         assign(op2, get_gpr_w1(r2));
+         put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
+      }
    }
    return "cdftr";
 }
@@ -9704,15 +9708,17 @@
 s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I32);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I32);
 
-      assign(op2, get_gpr_w1(r2));
-      put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
+         assign(op2, get_gpr_w1(r2));
+         put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
+      }
    }
    return "cxftr";
 }
@@ -9721,18 +9727,20 @@
 s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op2 = newTemp(Ity_I64);
 
-   vassert(s390_host_has_dfp);
-   if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m3 = S390_DFP_ROUND_PER_FPC_0;
+      if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m3 = S390_DFP_ROUND_PER_FPC_0;
+      }
+
+      assign(op2, get_gpr_dw0(r2));
+      put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
+                            mkexpr(op2)));
    }
-
-   assign(op2, get_gpr_dw0(r2));
-   put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
-                         mkexpr(op2)));
-
    return (m3 == 0) ? "cdgtr" : "cdgtra";
 }
 
@@ -9740,16 +9748,17 @@
 s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
                  UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   IRTemp op2 = newTemp(Ity_I64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op2 = newTemp(Ity_I64);
 
-   vassert(s390_host_has_dfp);
+      /* No emulation warning here about an non-zero m3 on hosts without
+         floating point extension facility. No rounding is performed */
 
-   /* No emulation warning here about an non-zero m3 on hosts without
-      floating point extension facility. No rounding is performed */
-
-   assign(op2, get_gpr_dw0(r2));
-   put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
-
+      assign(op2, get_gpr_dw0(r2));
+      put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
+   }
    return "cxgtr";
 }
 
@@ -9757,15 +9766,17 @@
 s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I32);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I32);
 
-      assign(op2, get_gpr_w1(r2));
-      put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
+         assign(op2, get_gpr_w1(r2));
+         put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
+      }
    }
    return "cdlftr";
 }
@@ -9774,15 +9785,17 @@
 s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I32);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I32);
 
-      assign(op2, get_gpr_w1(r2));
-      put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
+         assign(op2, get_gpr_w1(r2));
+         put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
+      }
    }
    return "cxlftr";
 }
@@ -9791,17 +9804,19 @@
 s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I64);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I64);
 
-      assign(op2, get_gpr_dw0(r2));
-      put_dpr_dw0(r1, binop(Iop_I64UtoD64,
-                            mkexpr(encode_dfp_rounding_mode(m3)),
-                            mkexpr(op2)));
+         assign(op2, get_gpr_dw0(r2));
+         put_dpr_dw0(r1, binop(Iop_I64UtoD64,
+                               mkexpr(encode_dfp_rounding_mode(m3)),
+                               mkexpr(op2)));
+      }
    }
    return "cdlgtr";
 }
@@ -9810,15 +9825,17 @@
 s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
                   UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op2 = newTemp(Ity_I64);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op2 = newTemp(Ity_I64);
 
-      assign(op2, get_gpr_dw0(r2));
-      put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
+         assign(op2, get_gpr_dw0(r2));
+         put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
+      }
    }
    return "cxlgtr";
 }
@@ -9827,20 +9844,22 @@
 s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D64);
-      IRTemp result = newTemp(Ity_I32);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D64);
+         IRTemp result = newTemp(Ity_I32);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_dw0(r2));
-      assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_w1(r1, mkexpr(result));
-      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
+         assign(op, get_dpr_dw0(r2));
+         assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_w1(r1, mkexpr(result));
+         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
+      }
    }
    return "cfdtr";
 }
@@ -9849,20 +9868,23 @@
 s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D128);
-      IRTemp result = newTemp(Ity_I32);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D128);
+         IRTemp result = newTemp(Ity_I32);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_pair(r2));
-      assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_w1(r1, mkexpr(result));
-      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
+         assign(op, get_dpr_pair(r2));
+         assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_w1(r1, mkexpr(result));
+         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op,
+                                 rounding_mode);
+      }
    }
    return "cfxtr";
 }
@@ -9871,22 +9893,23 @@
 s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_D64);
-   IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D64);
+      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-   vassert(s390_host_has_dfp);
+      /* If fpext is not installed and m3 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m3 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   /* If fpext is not installed and m3 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m3 = S390_DFP_ROUND_PER_FPC_0;
+      assign(op, get_dpr_dw0(r2));
+      put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
+      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
    }
-
-   assign(op, get_dpr_dw0(r2));
-   put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
-   s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
-
    return "cgdtr";
 }
 
@@ -9894,59 +9917,64 @@
 s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_D128);
-   IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D128);
+      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-   vassert(s390_host_has_dfp);
-
-   /* If fpext is not installed and m3 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m3 = S390_DFP_ROUND_PER_FPC_0;
+      /* If fpext is not installed and m3 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m3 = S390_DFP_ROUND_PER_FPC_0;
+      }
+      assign(op, get_dpr_pair(r2));
+      put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
+      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
    }
-   assign(op, get_dpr_pair(r2));
-   put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
-   s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
-
    return "cgxtr";
 }
 
 static const HChar *
 s390_irgen_CEDTR(UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp cc_vex  = newTemp(Ity_I32);
-   IRTemp cc_s390 = newTemp(Ity_I32);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp cc_vex  = newTemp(Ity_I32);
+      IRTemp cc_s390 = newTemp(Ity_I32);
 
-   vassert(s390_host_has_dfp);
-   assign(op1, get_dpr_dw0(r1));
-   assign(op2, get_dpr_dw0(r2));
-   assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
+      assign(op1, get_dpr_dw0(r1));
+      assign(op2, get_dpr_dw0(r2));
+      assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
 
-   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
-   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
-
+      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
+      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
+   }
    return "cedtr";
 }
 
 static const HChar *
 s390_irgen_CEXTR(UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp cc_vex  = newTemp(Ity_I32);
-   IRTemp cc_s390 = newTemp(Ity_I32);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp cc_vex  = newTemp(Ity_I32);
+      IRTemp cc_s390 = newTemp(Ity_I32);
 
-   vassert(s390_host_has_dfp);
-   assign(op1, get_dpr_pair(r1));
-   assign(op2, get_dpr_pair(r2));
-   assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
+      assign(op1, get_dpr_pair(r1));
+      assign(op2, get_dpr_pair(r2));
+      assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
 
-   assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
-   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
-
+      assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
+      s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
+   }
    return "cextr";
 }
 
@@ -9954,20 +9982,22 @@
 s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D64);
-      IRTemp result = newTemp(Ity_I32);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D64);
+         IRTemp result = newTemp(Ity_I32);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_dw0(r2));
-      assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_w1(r1, mkexpr(result));
-      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
+         assign(op, get_dpr_dw0(r2));
+         assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_w1(r1, mkexpr(result));
+         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
+      }
    }
    return "clfdtr";
 }
@@ -9976,20 +10006,23 @@
 s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D128);
-      IRTemp result = newTemp(Ity_I32);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D128);
+         IRTemp result = newTemp(Ity_I32);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_pair(r2));
-      assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_w1(r1, mkexpr(result));
-      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
+         assign(op, get_dpr_pair(r2));
+         assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_w1(r1, mkexpr(result));
+         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op,
+                                 rounding_mode);
+      }
    }
    return "clfxtr";
 }
@@ -9998,20 +10031,22 @@
 s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D64);
-      IRTemp result = newTemp(Ity_I64);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D64);
+         IRTemp result = newTemp(Ity_I64);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_dw0(r2));
-      assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_dw0(r1, mkexpr(result));
-      s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
+         assign(op, get_dpr_dw0(r2));
+         assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_dw0(r1, mkexpr(result));
+         s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
+      }
    }
    return "clgdtr";
 }
@@ -10020,21 +10055,23 @@
 s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
                   UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   if (! s390_host_has_fpext) {
-      emulation_failure(EmFail_S390X_fpext);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
    } else {
-      IRTemp op = newTemp(Ity_D128);
-      IRTemp result = newTemp(Ity_I64);
-      IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
+      if (! s390_host_has_fpext) {
+         emulation_failure(EmFail_S390X_fpext);
+      } else {
+         IRTemp op = newTemp(Ity_D128);
+         IRTemp result = newTemp(Ity_I64);
+         IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
 
-      assign(op, get_dpr_pair(r2));
-      assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
-                           mkexpr(op)));
-      put_gpr_dw0(r1, mkexpr(result));
-      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
-                              rounding_mode);
+         assign(op, get_dpr_pair(r2));
+         assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
+                              mkexpr(op)));
+         put_gpr_dw0(r1, mkexpr(result));
+         s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
+                                 rounding_mode);
+      }
    }
    return "clgxtr";
 }
@@ -10042,131 +10079,146 @@
 static const HChar *
 s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
    return (m4 == 0) ? "ddtr" : "ddtra";
 }
 
 static const HChar *
 s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_pair(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_pair(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
    return (m4 == 0) ? "dxtr" : "dxtra";
 }
 
 static const HChar *
 s390_irgen_EEDTR(UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
+   }
    return "eedtr";
 }
 
 static const HChar *
 s390_irgen_EEXTR(UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-
-   put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
+   }
    return "eextr";
 }
 
 static const HChar *
 s390_irgen_ESDTR(UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-   put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
+   }
    return "esdtr";
 }
 
 static const HChar *
 s390_irgen_ESXTR(UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
-   put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
+   }
    return "esxtr";
 }
 
 static const HChar *
 s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_I64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_I64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op1, get_gpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
+      assign(op1, get_gpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
+      put_dpr_dw0(r1, mkexpr(result));
+   }
    return "iedtr";
 }
 
 static const HChar *
 s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_I64);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_I64);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op1, get_gpr_dw0(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
+      assign(op1, get_gpr_dw0(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
+   }
    return "iextr";
 }
 
 static const HChar *
 s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
 {
-   IRTemp op = newTemp(Ity_D32);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D32);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op, get_dpr_w0(r2));
-   put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
-
+      assign(op, get_dpr_w0(r2));
+      put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
+   }
    return "ldetr";
 }
 
@@ -10185,20 +10237,21 @@
 s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      /* If fpext is not installed and m3 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m3 = S390_DFP_ROUND_PER_FPC_0;
+      }
+      IRTemp result = newTemp(Ity_D64);
 
-   /* If fpext is not installed and m3 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m3 = S390_DFP_ROUND_PER_FPC_0;
+      assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
+                           get_dpr_pair(r2)));
+      put_dpr_dw0(r1, mkexpr(result));
    }
-   IRTemp result = newTemp(Ity_D64);
-
-   assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
-                        get_dpr_pair(r2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
    return "ldxtr";
 }
 
@@ -10206,20 +10259,21 @@
 s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
                  UChar r1, UChar r2)
 {
-   vassert(s390_host_has_dfp);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      /* If fpext is not installed and m3 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m3 = S390_DFP_ROUND_PER_FPC_0;
+      }
+      IRTemp op = newTemp(Ity_D64);
 
-   /* If fpext is not installed and m3 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m3 = S390_DFP_ROUND_PER_FPC_0;
+      assign(op, get_dpr_dw0(r2));
+      put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
+                           mkexpr(op)));
    }
-   IRTemp op = newTemp(Ity_D64);
-
-   assign(op, get_dpr_dw0(r2));
-   put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
-                        mkexpr(op)));
-
    return "ledtr";
 }
 
@@ -10250,341 +10304,373 @@
 static const HChar *
 s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
    return (m4 == 0) ? "mdtr" : "mdtra";
 }
 
 static const HChar *
 s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_pair(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_pair(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
    return (m4 == 0) ? "mxtr" : "mxtra";
 }
 
 static const HChar *
 s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
-   /* If fpext is not installed and m4 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      /* If fpext is not installed and m4 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
+
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
    return "qadtr";
 }
 
 static const HChar *
 s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
-   /* If fpext is not installed and m4 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      /* If fpext is not installed and m4 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
+
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_pair(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_pair(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
    return "qaxtr";
 }
 
 static const HChar *
 s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_I8);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_I8);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
-   /* If fpext is not installed and m4 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      /* If fpext is not installed and m4 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
+
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_gpr_b7(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
+                           mkexpr(op1), mkexpr(op2)));
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_gpr_b7(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
-                        mkexpr(op1), mkexpr(op2)));
-   put_dpr_dw0(r1, mkexpr(result));
-
    return "rrdtr";
 }
 
 static const HChar *
 s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_I8);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_I8);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
-   /* If fpext is not installed and m4 is in 1:7,
-      rounding mode performed is unpredictable */
-   if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      /* If fpext is not installed and m4 is in 1:7,
+         rounding mode performed is unpredictable */
+      if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
+
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_gpr_b7(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
+                           mkexpr(op1), mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_gpr_b7(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
-                        mkexpr(op1), mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
    return "rrxtr";
 }
 
 static const HChar *
 s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D64);
-   IRTemp op2 = newTemp(Ity_D64);
-   IRTemp result = newTemp(Ity_D64);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D64);
+      IRTemp op2 = newTemp(Ity_D64);
+      IRTemp result = newTemp(Ity_D64);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_dw0(r2));
+      assign(op2, get_dpr_dw0(r3));
+      assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
+      put_dpr_dw0(r1, mkexpr(result));
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_dw0(r2));
-   assign(op2, get_dpr_dw0(r3));
-   assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
-   put_dpr_dw0(r1, mkexpr(result));
-
    return (m4 == 0) ? "sdtr" : "sdtra";
 }
 
 static const HChar *
 s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
 {
-   IRTemp op1 = newTemp(Ity_D128);
-   IRTemp op2 = newTemp(Ity_D128);
-   IRTemp result = newTemp(Ity_D128);
-   IRTemp rounding_mode;
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op1 = newTemp(Ity_D128);
+      IRTemp op2 = newTemp(Ity_D128);
+      IRTemp result = newTemp(Ity_D128);
+      IRTemp rounding_mode;
 
-   vassert(s390_host_has_dfp);
+      if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
+         emulation_warning(EmWarn_S390X_fpext_rounding);
+         m4 = S390_DFP_ROUND_PER_FPC_0;
+      }
 
-   if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
-      emulation_warning(EmWarn_S390X_fpext_rounding);
-      m4 = S390_DFP_ROUND_PER_FPC_0;
+      rounding_mode = encode_dfp_rounding_mode(m4);
+      assign(op1, get_dpr_pair(r2));
+      assign(op2, get_dpr_pair(r3));
+      assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
+                           mkexpr(op2)));
+      put_dpr_pair(r1, mkexpr(result));
+
+      s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
    }
-
-   rounding_mode = encode_dfp_rounding_mode(m4);
-   assign(op1, get_dpr_pair(r2));
-   assign(op2, get_dpr_pair(r3));
-   assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
-                        mkexpr(op2)));
-   put_dpr_pair(r1, mkexpr(result));
-
-   s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
-
    return (m4 == 0) ? "sxtr" : "sxtra";
 }
 
 static const HChar *
 s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
 {
-   IRTemp op = newTemp(Ity_D64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D64);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op, get_dpr_dw0(r3));
-   put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
-               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
-
+      assign(op, get_dpr_dw0(r3));
+      put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op),
+                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
+                                                  mkU64(63)))));
+   }
    return "sldt";
 }
 
 static const HChar *
 s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
 {
-   IRTemp op = newTemp(Ity_D128);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D128);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op, get_dpr_pair(r3));
-   put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
-                binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
-
+      assign(op, get_dpr_pair(r3));
+      put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op),
+                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
+                                                   mkU64(63)))));
+   }
    return "slxt";
 }
 
 static const HChar *
 s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
 {
-   IRTemp op = newTemp(Ity_D64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D64);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op, get_dpr_dw0(r3));
-   put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
-               binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
-
+      assign(op, get_dpr_dw0(r3));
+      put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op),
+                            unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
+                                                  mkU64(63)))));
+   }
    return "srdt";
 }
 
 static const HChar *
 s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
 {
-   IRTemp op = newTemp(Ity_D128);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp op = newTemp(Ity_D128);
 
-   vassert(s390_host_has_dfp);
-
-   assign(op, get_dpr_pair(r3));
-   put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
-                binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
-
+      assign(op, get_dpr_pair(r3));
+      put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op),
+                             unop(Iop_64to8, binop(Iop_And64, mkexpr(op2addr),
+                                                   mkU64(63)))));
+   }
    return "srxt";
 }
 
 static const HChar *
 s390_irgen_TDCET(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D32);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D32);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_w0(r1));
+      assign(value, get_dpr_w0(r1));
 
-   s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
-
+      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
+   }
    return "tdcet";
 }
 
 static const HChar *
 s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D64);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_dw0(r1));
+      assign(value, get_dpr_dw0(r1));
 
-   s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
-
+      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
+   }
    return "tdcdt";
 }
 
 static const HChar *
 s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D128);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D128);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_pair(r1));
+      assign(value, get_dpr_pair(r1));
 
-   s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
-
+      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
+   }
    return "tdcxt";
 }
 
 static const HChar *
 s390_irgen_TDGET(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D32);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D32);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_w0(r1));
+      assign(value, get_dpr_w0(r1));
 
-   s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
-
+      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
+   }
    return "tdget";
 }
 
 static const HChar *
 s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D64);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D64);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_dw0(r1));
+      assign(value, get_dpr_dw0(r1));
 
-   s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
-
+      s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
+   }
    return "tdgdt";
 }
 
 static const HChar *
 s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
 {
-   IRTemp value = newTemp(Ity_D128);
+   if (! s390_host_has_dfp) {
+      emulation_failure(EmFail_S390X_DFP_insn);
+   } else {
+      IRTemp value = newTemp(Ity_D128);
 
-   vassert(s390_host_has_dfp);
-   assign(value, get_dpr_pair(r1));
+      assign(value, get_dpr_pair(r1));
 
-   s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
-
+      s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
+   }
    return "tdgxt";
 }
 
diff --git a/priv/main_main.c b/priv/main_main.c
index a50f3f7..175c613 100644
--- a/priv/main_main.c
+++ b/priv/main_main.c
@@ -1198,6 +1198,8 @@
         return "Instruction ecag is not supported on this host";
      case EmFail_S390X_pfpo:
         return "Instruction pfpo is not supported on this host";
+     case EmFail_S390X_DFP_insn:
+        return "DFP instructions are not supported on this host";
      case EmFail_S390X_fpext:
         return "Encountered an instruction that requires the floating "
                "point extension facility.\n"
diff --git a/pub/libvex_emnote.h b/pub/libvex_emnote.h
index 82b0e76..5e6a9d8 100644
--- a/pub/libvex_emnote.h
+++ b/pub/libvex_emnote.h
@@ -106,6 +106,9 @@
       /* pfpo insn is not supported on this host */
       EmFail_S390X_pfpo,
 
+      /* DFP insns are not supported on this host */
+      EmFail_S390X_DFP_insn,
+
       /* insn needs floating point extension facility which is not
          available on this host */
       EmFail_S390X_fpext,