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 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_arm_toIR.c b/priv/guest_arm_toIR.c
index fe5e6d2..39d8ef8 100644
--- a/priv/guest_arm_toIR.c
+++ b/priv/guest_arm_toIR.c
@@ -2875,6 +2875,31 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
}
}
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 @@
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/priv/host_arm_defs.c b/priv/host_arm_defs.c
index 3acead8..d9bb974 100644
--- a/priv/host_arm_defs.c
+++ b/priv/host_arm_defs.c
@@ -790,6 +790,7 @@
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/priv/host_arm_defs.h b/priv/host_arm_defs.h
index 73dfd8a..f1ce4a7 100644
--- a/priv/host_arm_defs.h
+++ b/priv/host_arm_defs.h
@@ -468,6 +468,7 @@
ARMneon_VQDMULL,
ARMneon_VRECPS,
ARMneon_VRSQRTS,
+ ARMneon_INVALID
/* ... */
}
ARMNeonBinOp;
diff --git a/priv/host_arm_isel.c b/priv/host_arm_isel.c
index 0149ac2..28568eb 100644
--- a/priv/host_arm_isel.c
+++ b/priv/host_arm_isel.c
@@ -4254,26 +4254,11 @@
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 @@
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 @@
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 @@
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 @@
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;
}