From: Julian Seward Date: Tue, 7 Apr 2015 09:07:51 +0000 (+0000) Subject: amd64 front and back ends: track the change of type of Iop_Sqrt32Fx4 X-Git-Tag: svn/VALGRIND_3_11_0^2~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38bc9b93187515694c3ce4eea3b11a895637a363;p=thirdparty%2Fvalgrind.git amd64 front and back ends: track the change of type of Iop_Sqrt32Fx4 and Iop_Sqrt64Fx2 as introduced in r3120, in which they acquired a rounding-mode argument. git-svn-id: svn://svn.valgrind.org/vex/trunk@3121 --- diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index f3fe6697fd..add943d76a 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -8850,17 +8850,26 @@ static ULong dis_SSE_E_to_G_unary_all ( Int alen; IRTemp addr; UChar rm = getUChar(delta); + // Sqrt32Fx4 and Sqrt64Fx2 take a rounding mode, which is faked + // up in the usual way. + Bool needsIRRM = op == Iop_Sqrt32Fx4 || op == Iop_Sqrt64Fx2; if (epartIsReg(rm)) { - putXMMReg( gregOfRexRM(pfx,rm), - unop(op, getXMMReg(eregOfRexRM(pfx,rm))) ); + IRExpr* src = getXMMReg(eregOfRexRM(pfx,rm)); + /* XXXROUNDINGFIXME */ + IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src) + : unop(op, src); + putXMMReg( gregOfRexRM(pfx,rm), res ); DIP("%s %s,%s\n", opname, nameXMMReg(eregOfRexRM(pfx,rm)), nameXMMReg(gregOfRexRM(pfx,rm)) ); return delta+1; } else { addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, 0 ); - putXMMReg( gregOfRexRM(pfx,rm), - unop(op, loadLE(Ity_V128, mkexpr(addr))) ); + IRExpr* src = loadLE(Ity_V128, mkexpr(addr)); + /* XXXROUNDINGFIXME */ + IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), src) + : unop(op, src); + putXMMReg( gregOfRexRM(pfx,rm), res ); DIP("%s %s,%s\n", opname, dis_buf, nameXMMReg(gregOfRexRM(pfx,rm)) ); @@ -23046,7 +23055,13 @@ Long dis_AVX128_E_to_G_unary_all ( /*OUT*/Bool* uses_vvvv, delta += alen; DIP("%s %s,%s\n", opname, dis_buf, nameXMMReg(rG)); } - putYMMRegLoAndZU( rG, unop(op, mkexpr(arg)) ); + // Sqrt32Fx4 and Sqrt64Fx2 take a rounding mode, which is faked + // up in the usual way. + Bool needsIRRM = op == Iop_Sqrt32Fx4 || op == Iop_Sqrt64Fx2; + /* XXXROUNDINGFIXME */ + IRExpr* res = needsIRRM ? binop(op, get_FAKE_roundingmode(), mkexpr(arg)) + : unop(op, mkexpr(arg)); + putYMMRegLoAndZU( rG, res ); *uses_vvvv = False; return delta; } diff --git a/VEX/priv/host_amd64_isel.c b/VEX/priv/host_amd64_isel.c index 81bea0be90..3403d54563 100644 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@ -3227,7 +3227,6 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) case Iop_RecipEst32Fx4: op = Asse_RCPF; goto do_32Fx4_unary; case Iop_RSqrtEst32Fx4: op = Asse_RSQRTF; goto do_32Fx4_unary; - case Iop_Sqrt32Fx4: op = Asse_SQRTF; goto do_32Fx4_unary; do_32Fx4_unary: { HReg arg = iselVecExpr(env, e->Iex.Unop.arg); @@ -3236,15 +3235,6 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) return dst; } - case Iop_Sqrt64Fx2: op = Asse_SQRTF; goto do_64Fx2_unary; - do_64Fx2_unary: - { - HReg arg = iselVecExpr(env, e->Iex.Unop.arg); - HReg dst = newVRegV(env); - addInstr(env, AMD64Instr_Sse64Fx2(op, arg, dst)); - return dst; - } - case Iop_RecipEst32F0x4: op = Asse_RCPF; goto do_32F0x4_unary; case Iop_RSqrtEst32F0x4: op = Asse_RSQRTF; goto do_32F0x4_unary; case Iop_Sqrt32F0x4: op = Asse_SQRTF; goto do_32F0x4_unary; @@ -3313,6 +3303,19 @@ static HReg iselVecExpr_wrk ( ISelEnv* env, IRExpr* e ) if (e->tag == Iex_Binop) { switch (e->Iex.Binop.op) { + case Iop_Sqrt64Fx2: + case Iop_Sqrt32Fx4: { + /* :: (rmode, vec) -> vec */ + HReg arg = iselVecExpr(env, e->Iex.Binop.arg2); + HReg dst = newVRegV(env); + /* XXXROUNDINGFIXME */ + /* set roundingmode here */ + addInstr(env, (e->Iex.Binop.op == Iop_Sqrt64Fx2 + ? AMD64Instr_Sse64Fx2 : AMD64Instr_Sse32Fx4) + (Asse_SQRTF, arg, dst)); + return dst; + } + /* FIXME: could we generate MOVQ here? */ case Iop_SetV128lo64: { HReg dst = newVRegV(env);