From: Julian Seward Date: Mon, 17 Sep 2012 18:08:00 +0000 (+0000) Subject: Merge from trunk, r2533 (Add support for: uqsub16 shadd16 uhsub8 X-Git-Tag: svn/VALGRIND_3_8_1^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f8bf2ebf1e664771dc54f8b1462181bbf943b2da;p=thirdparty%2Fvalgrind.git Merge from trunk, r2533 (Add support for: uqsub16 shadd16 uhsub8 uhsub16, #304035, vex side). git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_8_BRANCH@2537 --- diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c index da40d39c48..22aa3db72f 100644 --- a/VEX/priv/guest_arm_toIR.c +++ b/VEX/priv/guest_arm_toIR.c @@ -10490,6 +10490,186 @@ static Bool decode_V6MEDIA_instruction ( /* fall through */ } + /* ------------------ uqsub16 ,, ------------------ */ + { + UInt regD = 99, regN = 99, regM = 99; + Bool gate = False; + + if (isT) { + if (INSNT0(15,4) == 0xFAD && (INSNT1(15,0) & 0xF0F0) == 0xF050) { + regN = INSNT0(3,0); + regD = INSNT1(11,8); + regM = INSNT1(3,0); + if (!isBadRegT(regD) && !isBadRegT(regN) && !isBadRegT(regM)) + gate = True; + } + } else { + if (INSNA(27,20) == BITS8(0,1,1,0,0,1,1,0) && + INSNA(11,8) == BITS4(1,1,1,1) && + INSNA(7,4) == BITS4(0,1,1,1)) { + regD = INSNA(15,12); + regN = INSNA(19,16); + regM = INSNA(3,0); + if (regD != 15 && regN != 15 && regM != 15) + gate = True; + } + } + + if (gate) { + IRTemp rNt = newTemp(Ity_I32); + IRTemp rMt = newTemp(Ity_I32); + IRTemp res_q = newTemp(Ity_I32); + + assign( rNt, isT ? getIRegT(regN) : getIRegA(regN) ); + assign( rMt, isT ? getIRegT(regM) : getIRegA(regM) ); + + assign(res_q, binop(Iop_QSub16Ux2, mkexpr(rNt), mkexpr(rMt))); + if (isT) + putIRegT( regD, mkexpr(res_q), condT ); + else + putIRegA( regD, mkexpr(res_q), condT, Ijk_Boring ); + + DIP("uqsub16%s r%u, r%u, r%u\n", nCC(conq),regD,regN,regM); + return True; + } + /* fall through */ + } + + /* ----------------- shadd16 ,, ------------------- */ + { + UInt regD = 99, regN = 99, regM = 99; + Bool gate = False; + + if (isT) { + if (INSNT0(15,4) == 0xFA9 && (INSNT1(15,0) & 0xF0F0) == 0xF020) { + regN = INSNT0(3,0); + regD = INSNT1(11,8); + regM = INSNT1(3,0); + if (!isBadRegT(regD) && !isBadRegT(regN) && !isBadRegT(regM)) + gate = True; + } + } else { + if (INSNA(27,20) == BITS8(0,1,1,0,0,0,1,1) && + INSNA(11,8) == BITS4(1,1,1,1) && + INSNA(7,4) == BITS4(0,0,0,1)) { + regD = INSNA(15,12); + regN = INSNA(19,16); + regM = INSNA(3,0); + if (regD != 15 && regN != 15 && regM != 15) + gate = True; + } + } + + if (gate) { + IRTemp rNt = newTemp(Ity_I32); + IRTemp rMt = newTemp(Ity_I32); + IRTemp res_q = newTemp(Ity_I32); + + assign( rNt, isT ? getIRegT(regN) : getIRegA(regN) ); + assign( rMt, isT ? getIRegT(regM) : getIRegA(regM) ); + + assign(res_q, binop(Iop_HAdd16Sx2, mkexpr(rNt), mkexpr(rMt))); + if (isT) + putIRegT( regD, mkexpr(res_q), condT ); + else + putIRegA( regD, mkexpr(res_q), condT, Ijk_Boring ); + + DIP("shadd16%s r%u, r%u, r%u\n", nCC(conq),regD,regN,regM); + return True; + } + /* fall through */ + } + + /* ----------------- uhsub8 ,, ------------------- */ + { + UInt regD = 99, regN = 99, regM = 99; + Bool gate = False; + + if (isT) { + if (INSNT0(15,4) == 0xFAC && (INSNT1(15,0) & 0xF0F0) == 0xF060) { + regN = INSNT0(3,0); + regD = INSNT1(11,8); + regM = INSNT1(3,0); + if (!isBadRegT(regD) && !isBadRegT(regN) && !isBadRegT(regM)) + gate = True; + } + } else { + if (INSNA(27,20) == BITS8(0,1,1,0,0,1,1,1) && + INSNA(11,8) == BITS4(1,1,1,1) && + INSNA(7,4) == BITS4(1,1,1,1)) { + regD = INSNA(15,12); + regN = INSNA(19,16); + regM = INSNA(3,0); + if (regD != 15 && regN != 15 && regM != 15) + gate = True; + } + } + + if (gate) { + IRTemp rNt = newTemp(Ity_I32); + IRTemp rMt = newTemp(Ity_I32); + IRTemp res_q = newTemp(Ity_I32); + + assign( rNt, isT ? getIRegT(regN) : getIRegA(regN) ); + assign( rMt, isT ? getIRegT(regM) : getIRegA(regM) ); + + assign(res_q, binop(Iop_HSub8Ux4, mkexpr(rNt), mkexpr(rMt))); + if (isT) + putIRegT( regD, mkexpr(res_q), condT ); + else + putIRegA( regD, mkexpr(res_q), condT, Ijk_Boring ); + + DIP("uhsub8%s r%u, r%u, r%u\n", nCC(conq),regD,regN,regM); + return True; + } + /* fall through */ + } + + /* ----------------- uhsub16 ,, ------------------- */ + { + UInt regD = 99, regN = 99, regM = 99; + Bool gate = False; + + if (isT) { + if (INSNT0(15,4) == 0xFAD && (INSNT1(15,0) & 0xF0F0) == 0xF060) { + regN = INSNT0(3,0); + regD = INSNT1(11,8); + regM = INSNT1(3,0); + if (!isBadRegT(regD) && !isBadRegT(regN) && !isBadRegT(regM)) + gate = True; + } + } else { + if (INSNA(27,20) == BITS8(0,1,1,0,0,1,1,1) && + INSNA(11,8) == BITS4(1,1,1,1) && + INSNA(7,4) == BITS4(0,1,1,1)) { + regD = INSNA(15,12); + regN = INSNA(19,16); + regM = INSNA(3,0); + if (regD != 15 && regN != 15 && regM != 15) + gate = True; + } + } + + if (gate) { + IRTemp rNt = newTemp(Ity_I32); + IRTemp rMt = newTemp(Ity_I32); + IRTemp res_q = newTemp(Ity_I32); + + assign( rNt, isT ? getIRegT(regN) : getIRegA(regN) ); + assign( rMt, isT ? getIRegT(regM) : getIRegA(regM) ); + + assign(res_q, binop(Iop_HSub16Ux2, mkexpr(rNt), mkexpr(rMt))); + if (isT) + putIRegT( regD, mkexpr(res_q), condT ); + else + putIRegA( regD, mkexpr(res_q), condT, Ijk_Boring ); + + DIP("uhsub16%s r%u, r%u, r%u\n", nCC(conq),regD,regN,regM); + return True; + } + /* fall through */ + } + /* ---------- Doesn't match anything. ---------- */ return False; diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 7e827e6640..62739fdd28 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -1366,6 +1366,8 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) fn = &h_generic_calc_QAdd32S; break; case Iop_QSub32S: fn = &h_generic_calc_QSub32S; break; + case Iop_QSub16Ux2: + fn = &h_generic_calc_QSub16Ux2; break; default: break; }