From: Julian Seward Date: Sat, 15 Mar 2014 11:41:39 +0000 (+0000) Subject: Un-break the arm32 compilation pipeline following the change of X-Git-Tag: svn/VALGRIND_3_10_1^2~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=203ce5d1703b0cf6278ca523fbd4cc1dcd582fda;p=thirdparty%2Fvalgrind.git Un-break the arm32 compilation pipeline following the change of arity of Iop_Mul32Fx4, Iop_Sub32Fx4, Iop_Add32Fx4 in r2809. git-svn-id: svn://svn.valgrind.org/vex/trunk@2840 --- diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c index fe5e6d2e9c..39d8ef8400 100644 --- a/VEX/priv/guest_arm_toIR.c +++ b/VEX/priv/guest_arm_toIR.c @@ -2875,6 +2875,31 @@ Bool dis_neon_vext ( UInt theInstr, IRTemp condT ) return True; } +/* Generate specific vector FP binary ops, possibly with a fake + rounding mode as required by the primop. */ +static +IRExpr* binop_w_fake_RM ( IROp op, IRExpr* argL, IRExpr* argR ) +{ + switch (op) { + case Iop_Add32Fx4: + case Iop_Sub32Fx4: + case Iop_Mul32Fx4: + return triop(op, get_FAKE_roundingmode(), argL, argR ); + case Iop_Add32x4: case Iop_Add16x8: + case Iop_Sub32x4: case Iop_Sub16x8: + case Iop_Mul32x4: case Iop_Mul16x8: + case Iop_Mul32x2: case Iop_Mul16x4: + case Iop_Add32Fx2: + case Iop_Sub32Fx2: + case Iop_Mul32Fx2: + case Iop_PwAdd32Fx2: + return binop(op, argL, argR); + default: + ppIROp(op); + vassert(0); + } +} + /* VTBL, VTBX */ static Bool dis_neon_vtb ( UInt theInstr, IRTemp condT ) @@ -4601,7 +4626,8 @@ Bool dis_neon_data_3same ( UInt theInstr, IRTemp condT ) /* VABD */ if (Q) { assign(res, unop(Iop_Abs32Fx4, - binop(Iop_Sub32Fx4, + triop(Iop_Sub32Fx4, + get_FAKE_roundingmode(), mkexpr(arg_n), mkexpr(arg_m)))); } else { @@ -4616,7 +4642,7 @@ Bool dis_neon_data_3same ( UInt theInstr, IRTemp condT ) break; } } - assign(res, binop(op, mkexpr(arg_n), mkexpr(arg_m))); + assign(res, binop_w_fake_RM(op, mkexpr(arg_n), mkexpr(arg_m))); } else { if (U == 0) { /* VMLA, VMLS */ @@ -4641,9 +4667,11 @@ Bool dis_neon_data_3same ( UInt theInstr, IRTemp condT ) default: vassert(0); } } - assign(res, binop(op2, - Q ? getQReg(dreg) : getDRegI64(dreg), - binop(op, mkexpr(arg_n), mkexpr(arg_m)))); + assign(res, binop_w_fake_RM( + op2, + Q ? getQReg(dreg) : getDRegI64(dreg), + binop_w_fake_RM(op, mkexpr(arg_n), + mkexpr(arg_m)))); DIP("vml%c.f32 %c%u, %c%u, %c%u\n", P ? 's' : 'a', Q ? 'q' : 'd', @@ -4654,7 +4682,7 @@ Bool dis_neon_data_3same ( UInt theInstr, IRTemp condT ) if ((C >> 1) != 0) return False; op = Q ? Iop_Mul32Fx4 : Iop_Mul32Fx2 ; - assign(res, binop(op, mkexpr(arg_n), mkexpr(arg_m))); + assign(res, binop_w_fake_RM(op, mkexpr(arg_n), mkexpr(arg_m))); DIP("vmul.f32 %c%u, %c%u, %c%u\n", Q ? 'q' : 'd', dreg, Q ? 'q' : 'd', nreg, Q ? 'q' : 'd', mreg); @@ -5318,10 +5346,10 @@ Bool dis_neon_data_2reg_and_scalar ( UInt theInstr, IRTemp condT ) } } op2 = INSN(10,10) ? sub : add; - assign(res, binop(op, mkexpr(arg_n), mkexpr(arg_m))); + assign(res, binop_w_fake_RM(op, mkexpr(arg_n), mkexpr(arg_m))); if (Q) - putQReg(dreg, binop(op2, getQReg(dreg), mkexpr(res)), - condT); + putQReg(dreg, binop_w_fake_RM(op2, getQReg(dreg), mkexpr(res)), + condT); else putDRegI64(dreg, binop(op2, getDRegI64(dreg), mkexpr(res)), condT); @@ -5548,7 +5576,7 @@ Bool dis_neon_data_2reg_and_scalar ( UInt theInstr, IRTemp condT ) vassert(0); } } - assign(res, binop(op, mkexpr(arg_n), mkexpr(arg_m))); + assign(res, binop_w_fake_RM(op, mkexpr(arg_n), mkexpr(arg_m))); if (Q) putQReg(dreg, mkexpr(res), condT); else diff --git a/VEX/priv/host_arm_defs.c b/VEX/priv/host_arm_defs.c index 3acead8d57..d9bb974c0b 100644 --- a/VEX/priv/host_arm_defs.c +++ b/VEX/priv/host_arm_defs.c @@ -790,6 +790,7 @@ const HChar* showARMNeonBinOp ( ARMNeonBinOp op ) { case ARMneon_VTBL: return "vtbl"; case ARMneon_VRECPS: return "vrecps"; case ARMneon_VRSQRTS: return "vrecps"; + case ARMneon_INVALID: return "??invalid??"; /* ... */ default: vpanic("showARMNeonBinOp"); } diff --git a/VEX/priv/host_arm_defs.h b/VEX/priv/host_arm_defs.h index 73dfd8ab44..f1ce4a741d 100644 --- a/VEX/priv/host_arm_defs.h +++ b/VEX/priv/host_arm_defs.h @@ -468,6 +468,7 @@ typedef ARMneon_VQDMULL, ARMneon_VRECPS, ARMneon_VRSQRTS, + ARMneon_INVALID /* ... */ } ARMNeonBinOp; diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 0149ac2780..28568eb4ed 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -4254,26 +4254,11 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) return res; } case Iop_Abs32Fx4: { - DECLARE_PATTERN(p_vabd_32fx4); - DEFINE_PATTERN(p_vabd_32fx4, - unop(Iop_Abs32Fx4, - binop(Iop_Sub32Fx4, - bind(0), - bind(1)))); - if (matchIRExpr(&mi, p_vabd_32fx4, e)) { - HReg res = newVRegV(env); - HReg argL = iselNeonExpr(env, mi.bindee[0]); - HReg argR = iselNeonExpr(env, mi.bindee[1]); - addInstr(env, ARMInstr_NBinary(ARMneon_VABDFP, - res, argL, argR, 0, True)); - return res; - } else { - HReg res = newVRegV(env); - HReg argL = iselNeonExpr(env, e->Iex.Unop.arg); - addInstr(env, ARMInstr_NUnary(ARMneon_VABSFP, - res, argL, 0, True)); - return res; - } + HReg res = newVRegV(env); + HReg argL = iselNeonExpr(env, e->Iex.Unop.arg); + addInstr(env, ARMInstr_NUnary(ARMneon_VABSFP, + res, argL, 0, True)); + return res; } case Iop_Rsqrte32Fx4: { HReg res = newVRegV(env); @@ -4457,15 +4442,6 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) res, argL, argR, size, True)); return res; } - case Iop_Add32Fx4: { - HReg res = newVRegV(env); - HReg argL = iselNeonExpr(env, e->Iex.Binop.arg1); - HReg argR = iselNeonExpr(env, e->Iex.Binop.arg2); - UInt size = 0; - addInstr(env, ARMInstr_NBinary(ARMneon_VADDFP, - res, argL, argR, size, True)); - return res; - } case Iop_Recps32Fx4: { HReg res = newVRegV(env); HReg argL = iselNeonExpr(env, e->Iex.Binop.arg1); @@ -4632,15 +4608,6 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) res, argL, argR, size, True)); return res; } - case Iop_Sub32Fx4: { - HReg res = newVRegV(env); - HReg argL = iselNeonExpr(env, e->Iex.Binop.arg1); - HReg argR = iselNeonExpr(env, e->Iex.Binop.arg2); - UInt size = 0; - addInstr(env, ARMInstr_NBinary(ARMneon_VSUBFP, - res, argL, argR, size, True)); - return res; - } case Iop_QSub8Ux16: case Iop_QSub16Ux8: case Iop_QSub32Ux4: @@ -5083,15 +5050,6 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) res, argL, argR, size, True)); return res; } - case Iop_Mul32Fx4: { - HReg res = newVRegV(env); - HReg argL = iselNeonExpr(env, e->Iex.Binop.arg1); - HReg argR = iselNeonExpr(env, e->Iex.Binop.arg2); - UInt size = 0; - addInstr(env, ARMInstr_NBinary(ARMneon_VMULFP, - res, argL, argR, size, True)); - return res; - } case Iop_Mull8Ux8: case Iop_Mull16Ux4: case Iop_Mull32Ux2: { @@ -5352,6 +5310,23 @@ static HReg iselNeonExpr_wrk ( ISelEnv* env, IRExpr* e ) res, argL, argR, imm4, True)); return res; } + case Iop_Mul32Fx4: + case Iop_Sub32Fx4: + case Iop_Add32Fx4: { + HReg res = newVRegV(env); + HReg argL = iselNeonExpr(env, triop->arg2); + HReg argR = iselNeonExpr(env, triop->arg3); + UInt size = 0; + ARMNeonBinOp op = ARMneon_INVALID; + switch (triop->op) { + case Iop_Mul32Fx4: op = ARMneon_VMULFP; break; + case Iop_Sub32Fx4: op = ARMneon_VSUBFP; break; + case Iop_Add32Fx4: op = ARMneon_VADDFP; break; + default: vassert(0); + } + addInstr(env, ARMInstr_NBinary(op, res, argL, argR, size, True)); + return res; + } default: break; }