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,