From: Florian Krohm Date: Sat, 6 Dec 2014 16:34:48 +0000 (+0000) Subject: DFP insns should cause an emulation failure if the host cannot X-Git-Tag: svn/VALGRIND_3_11_0^2~143 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b921b6c9c19bad9256de0a0d5887ba971ef29892;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index f0add1ba1f..2463a06665 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -9597,53 +9597,55 @@ s390_irgen_SDB(UChar r1, IRTemp op2addr) 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; - - vassert(s390_host_has_dfp); + 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; + + 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; + + 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; + } - vassert(s390_host_has_dfp); + 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)); - 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; + 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 @@ static const HChar * 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 @@ static const HChar * 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 @@ static const HChar * s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)), UChar r1, UChar r2) { - 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_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op2 = newTemp(Ity_I64); - assign(op2, get_gpr_dw0(r2)); - put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)), - mkexpr(op2))); + 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))); + } return (m3 == 0) ? "cdgtr" : "cdgtra"; } @@ -9740,16 +9748,17 @@ static const HChar * s390_irgen_CXGTR(UChar m3 __attribute__((unused)), UChar m4 __attribute__((unused)), UChar r1, UChar r2) { - IRTemp op2 = newTemp(Ity_I64); - - vassert(s390_host_has_dfp); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op2 = newTemp(Ity_I64); - /* 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))); + /* 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))); + } return "cxgtr"; } @@ -9757,15 +9766,17 @@ static const HChar * 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 @@ static const HChar * 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 @@ static const HChar * 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 @@ static const HChar * 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 @@ static const HChar * 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); - - 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); + 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); + } } return "cfdtr"; } @@ -9849,20 +9868,23 @@ static const HChar * 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); - - 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); + 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); + } } return "cfxtr"; } @@ -9871,22 +9893,23 @@ static const HChar * 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 @@ static const HChar * 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); - - vassert(s390_host_has_dfp); + 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); - /* 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); - - 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))); + 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); - assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); - s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); + 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); + } 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(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); - s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); + 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); + } return "cextr"; } @@ -9954,20 +9982,22 @@ static const HChar * 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); - - 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); + 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); + } } return "clfdtr"; } @@ -9976,20 +10006,23 @@ static const HChar * 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); - - 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); + 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); + } } return "clfxtr"; } @@ -9998,20 +10031,22 @@ static const HChar * 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); - - 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); + 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); + } } return "clgdtr"; } @@ -10020,21 +10055,23 @@ static const HChar * 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); - - 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); + 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); + } } return "clgxtr"; } @@ -10042,131 +10079,146 @@ s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)), 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; - - vassert(s390_host_has_dfp); + 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; + + 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; - - vassert(s390_host_has_dfp); + 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; + + 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); - - 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)); - + 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); + + 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); - - 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)); - + 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); + + 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); - - vassert(s390_host_has_dfp); - - assign(op, get_dpr_w0(r2)); - put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op))); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op = newTemp(Ity_D32); + assign(op, get_dpr_w0(r2)); + put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op))); + } return "ldetr"; } @@ -10185,20 +10237,21 @@ static const HChar * 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 @@ static const HChar * 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 @@ s390_irgen_LTXTR(UChar r1, UChar r2) 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; - - vassert(s390_host_has_dfp); + 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; + + 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; - - vassert(s390_host_has_dfp); + 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; + + 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; + + /* 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; + } - 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; + 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; + + /* 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; + } - 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; + 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; + + /* 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; + } - 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; + 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; + + /* 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; + } - 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; + 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; - - vassert(s390_host_has_dfp); + 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; + + 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; + + 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; + } - vassert(s390_host_has_dfp); + 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)); - 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; + 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); - - 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))))); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op = newTemp(Ity_D64); + 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); - - 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))))); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op = newTemp(Ity_D128); + 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); - - 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))))); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op = newTemp(Ity_D64); + 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); - - 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))))); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp op = newTemp(Ity_D128); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_w0(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D32); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr); + assign(value, get_dpr_w0(r1)); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_dw0(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D64); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr); + assign(value, get_dpr_dw0(r1)); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_pair(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D128); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr); + assign(value, get_dpr_pair(r1)); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_w0(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D32); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr); + assign(value, get_dpr_w0(r1)); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_dw0(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D64); - s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr); + assign(value, get_dpr_dw0(r1)); + 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); - - vassert(s390_host_has_dfp); - assign(value, get_dpr_pair(r1)); + if (! s390_host_has_dfp) { + emulation_failure(EmFail_S390X_DFP_insn); + } else { + IRTemp value = newTemp(Ity_D128); - s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr); + assign(value, get_dpr_pair(r1)); + s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr); + } return "tdgxt"; } diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index a50f3f7c75..175c6137fc 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -1198,6 +1198,8 @@ const HChar* LibVEX_EmNote_string ( VexEmNote ew ) 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/VEX/pub/libvex_emnote.h b/VEX/pub/libvex_emnote.h index 82b0e76a40..5e6a9d8672 100644 --- a/VEX/pub/libvex_emnote.h +++ b/VEX/pub/libvex_emnote.h @@ -106,6 +106,9 @@ typedef /* 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,