From: Florian Krohm Date: Fri, 21 Dec 2012 21:05:17 +0000 (+0000) Subject: s390: Distinguish between conversion to/from IRCmpFxxResult and X-Git-Tag: svn/VALGRIND_3_9_0^2~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58a6d25da535a07232e6e9d4e9420822c2b87cd9;p=thirdparty%2Fvalgrind.git s390: Distinguish between conversion to/from IRCmpFxxResult and IRCmpDxxResult, even though the encodings are currently the same. Rename convert_s390_fpcc_to_vex to convert_s390_to_vex_bfpcc. Add convert_s390_to_vex_dfpcc and convert_vex_dfpcc_to_s390. git-svn-id: svn://svn.valgrind.org/vex/trunk@2608 --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index e77efc2aea..4c5febd57f 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -50,7 +50,6 @@ static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *); static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp); static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp); -static IRExpr *convert_vex_fpcc_to_s390(IRTemp); /*------------------------------------------------------------*/ @@ -1618,6 +1617,70 @@ encode_dfp_rounding_mode(UChar mode) } +/*------------------------------------------------------------*/ +/*--- Condition code helpers ---*/ +/*------------------------------------------------------------*/ + +/* The result of a Iop_CmpFxx operation is a condition code. It is + encoded using the values defined in type IRCmpFxxResult. + Before we can store the condition code into the guest state (or do + anything else with it for that matter) we need to convert it to + the encoding that s390 uses. This is what this function does. + + s390 VEX b6 b2 b0 cc.1 cc.0 + 0 0x40 EQ 1 0 0 0 0 + 1 0x01 LT 0 0 1 0 1 + 2 0x00 GT 0 0 0 1 0 + 3 0x45 Unordered 1 1 1 1 1 + + The following bits from the VEX encoding are interesting: + b0, b2, b6 with b0 being the LSB. We observe: + + cc.0 = b0; + cc.1 = b2 | (~b0 & ~b6) + + with cc being the s390 condition code. +*/ +static IRExpr * +convert_vex_bfpcc_to_s390(IRTemp vex_cc) +{ + IRTemp cc0 = newTemp(Ity_I32); + IRTemp cc1 = newTemp(Ity_I32); + IRTemp b0 = newTemp(Ity_I32); + IRTemp b2 = newTemp(Ity_I32); + IRTemp b6 = newTemp(Ity_I32); + + assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1))); + assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)), + mkU32(1))); + assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)), + mkU32(1))); + + assign(cc0, mkexpr(b0)); + assign(cc1, binop(Iop_Or32, mkexpr(b2), + binop(Iop_And32, + binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */ + binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */ + ))); + + return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1))); +} + + +/* The result of a Iop_CmpDxx operation is a condition code. It is + encoded using the values defined in type IRCmpDxxResult. + Before we can store the condition code into the guest state (or do + anything else with it for that matter) we need to convert it to + the encoding that s390 uses. This is what this function does. */ +static IRExpr * +convert_vex_dfpcc_to_s390(IRTemp vex_cc) +{ + /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the + same. currently. */ + return convert_vex_dfpcc_to_s390(vex_cc); +} + + /*------------------------------------------------------------*/ /*--- Build IR for formats ---*/ /*------------------------------------------------------------*/ @@ -9194,7 +9257,7 @@ s390_irgen_CDTR(UChar r1, UChar r2) assign(op2, get_dpr_dw0(r2)); assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cdtr"; @@ -9212,7 +9275,7 @@ s390_irgen_CXTR(UChar r1, UChar r2) assign(op2, get_dpr_pair(r2)); assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cxtr"; @@ -10849,51 +10912,6 @@ s390_irgen_AXBR(UChar r1, UChar r2) return "axbr"; } -/* The result of a Iop_CmdFxx operation is a condition code. It is - encoded using the values defined in type IRCmpFxxResult. - Before we can store the condition code into the guest state (or do - anything else with it for that matter) we need to convert it to - the encoding that s390 uses. This is what this function does. - - s390 VEX b6 b2 b0 cc.1 cc.0 - 0 0x40 EQ 1 0 0 0 0 - 1 0x01 LT 0 0 1 0 1 - 2 0x00 GT 0 0 0 1 0 - 3 0x45 Unordered 1 1 1 1 1 - - The following bits from the VEX encoding are interesting: - b0, b2, b6 with b0 being the LSB. We observe: - - cc.0 = b0; - cc.1 = b2 | (~b0 & ~b6) - - with cc being the s390 condition code. -*/ -static IRExpr * -convert_vex_fpcc_to_s390(IRTemp vex_cc) -{ - IRTemp cc0 = newTemp(Ity_I32); - IRTemp cc1 = newTemp(Ity_I32); - IRTemp b0 = newTemp(Ity_I32); - IRTemp b2 = newTemp(Ity_I32); - IRTemp b6 = newTemp(Ity_I32); - - assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1))); - assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)), - mkU32(1))); - assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)), - mkU32(1))); - - assign(cc0, mkexpr(b0)); - assign(cc1, binop(Iop_Or32, mkexpr(b2), - binop(Iop_And32, - binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */ - binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */ - ))); - - return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1))); -} - static const HChar * s390_irgen_CEBR(UChar r1, UChar r2) { @@ -10906,7 +10924,7 @@ s390_irgen_CEBR(UChar r1, UChar r2) assign(op2, get_fpr_w0(r2)); assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cebr"; @@ -10924,7 +10942,7 @@ s390_irgen_CDBR(UChar r1, UChar r2) assign(op2, get_fpr_dw0(r2)); assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cdbr"; @@ -10942,7 +10960,7 @@ s390_irgen_CXBR(UChar r1, UChar r2) assign(op2, get_fpr_pair(r2)); assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cxbr"; @@ -10960,7 +10978,7 @@ s390_irgen_CEB(UChar r1, IRTemp op2addr) assign(op2, load(Ity_F32, mkexpr(op2addr))); assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "ceb"; @@ -10978,7 +10996,7 @@ s390_irgen_CDB(UChar r1, IRTemp op2addr) assign(op2, load(Ity_F64, mkexpr(op2addr))); assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2))); - assign(cc_s390, convert_vex_fpcc_to_s390(cc_vex)); + assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex)); s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False); return "cdb"; diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 2567b208ab..d22de3e4a7 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -727,8 +727,13 @@ get_dfp_rounding_mode(ISelEnv *env, IRExpr *irrm) return S390_DFP_ROUND_PER_FPC_0; } + +/*---------------------------------------------------------*/ +/*--- Condition code helper functions ---*/ +/*---------------------------------------------------------*/ + /* CC_S390 holds the condition code in s390 encoding. Convert it to - VEX encoding + VEX encoding (IRCmpFResult) s390 VEX b6 b2 b0 cc.1 cc.0 0 0x40 EQ 1 0 0 0 0 @@ -743,7 +748,7 @@ get_dfp_rounding_mode(ISelEnv *env, IRExpr *irrm) VEX = b0 | (b2 << 2) | (b6 << 6); */ static HReg -convert_s390_fpcc_to_vex(ISelEnv *env, HReg cc_s390) +convert_s390_to_vex_bfpcc(ISelEnv *env, HReg cc_s390) { HReg cc0, cc1, b2, b6, cc_vex; @@ -775,6 +780,15 @@ convert_s390_fpcc_to_vex(ISelEnv *env, HReg cc_s390) return cc_vex; } +/* CC_S390 holds the condition code in s390 encoding. Convert it to + VEX encoding (IRCmpDResult) */ +static HReg +convert_s390_to_vex_dfpcc(ISelEnv *env, HReg cc_s390) +{ + /* The encodings for IRCmpFResult and IRCmpDResult are the same/ */ + return convert_s390_to_vex_bfpcc(env, cc_s390); +} + /*---------------------------------------------------------*/ /*--- ISEL: Integer expressions (128 bit) ---*/ @@ -1177,7 +1191,7 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) addInstr(env, s390_insn_bfp_compare(size, cc_s390, h1, h2)); - return convert_s390_fpcc_to_vex(env, cc_s390); + return convert_s390_to_vex_bfpcc(env, cc_s390); } case Iop_CmpF128: { @@ -1204,7 +1218,7 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) res = newVRegI(env); addInstr(env, s390_insn_bfp128_compare(16, cc_s390, f12, f14, f13, f15)); - return convert_s390_fpcc_to_vex(env, cc_s390); + return convert_s390_to_vex_bfpcc(env, cc_s390); } case Iop_CmpD64: { @@ -1217,7 +1231,7 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) addInstr(env, s390_insn_dfp_compare(size, cc_s390, h1, h2)); - return convert_s390_fpcc_to_vex(env, cc_s390); + return convert_s390_to_vex_dfpcc(env, cc_s390); } case Iop_CmpD128: { @@ -1244,7 +1258,7 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) res = newVRegI(env); addInstr(env, s390_insn_dfp128_compare(16, cc_s390, f12, f14, f13, f15)); - return convert_s390_fpcc_to_vex(env, cc_s390); + return convert_s390_to_vex_dfpcc(env, cc_s390); } case Iop_Add8: