|
From: <sv...@va...> - 2014-05-14 23:38:35
|
Author: sewardj
Date: Wed May 14 23:38:23 2014
New Revision: 2861
Log:
Implement VFPv4 VFMA and VFMS (F32 and F64 versions). Fixes #331057.
Patch from Janne Hellsten (jjh...@gm...) with algebraic
rearrangement for the VFMS cases so as to make result signs match with
the hardware when some of the inputs are infinities.
Modified:
trunk/priv/guest_arm_toIR.c
Modified: trunk/priv/guest_arm_toIR.c
==============================================================================
--- trunk/priv/guest_arm_toIR.c (original)
+++ trunk/priv/guest_arm_toIR.c Wed May 14 23:38:23 2014
@@ -13527,6 +13527,27 @@
condT);
DIP("fdivd%s d%u, d%u, d%u\n", nCC(conq), dD, dN, dM);
goto decode_success_vfp;
+ case BITS4(1,1,0,0): /* VFMA: d + n * m (fused) */
+ /* XXXROUNDINGFIXME look up ARM reference for fused
+ multiply-add rounding */
+ putDReg(dD, triop(Iop_AddF64, rm,
+ getDReg(dD),
+ triop(Iop_MulF64, rm, getDReg(dN),
+ getDReg(dM))),
+ condT);
+ DIP("vfmad%s d%u, d%u, d%u\n", nCC(conq), dD, dN, dM);
+ goto decode_success_vfp;
+ case BITS4(1,1,0,1): /* VFMS: d + (-n * m) (fused) */
+ /* XXXROUNDINGFIXME look up ARM reference for fused
+ multiply-add rounding */
+ putDReg(dD, triop(Iop_AddF64, rm,
+ getDReg(dD),
+ triop(Iop_MulF64, rm,
+ unop(Iop_NegF64, getDReg(dN)),
+ getDReg(dM))),
+ condT);
+ DIP("vfmsd%s d%u, d%u, d%u\n", nCC(conq), dD, dN, dM);
+ goto decode_success_vfp;
default:
break;
}
@@ -13991,6 +14012,27 @@
condT);
DIP("fdivs%s s%u, s%u, s%u\n", nCC(conq), fD, fN, fM);
goto decode_success_vfp;
+ case BITS4(1,1,0,0): /* VFMA: d + n * m (fused) */
+ /* XXXROUNDINGFIXME look up ARM reference for fused
+ multiply-add rounding */
+ putFReg(fD, triop(Iop_AddF32, rm,
+ getFReg(fD),
+ triop(Iop_MulF32, rm, getFReg(fN),
+ getFReg(fM))),
+ condT);
+ DIP("vfmas%s s%u, s%u, s%u\n", nCC(conq), fD, fN, fM);
+ goto decode_success_vfp;
+ case BITS4(1,1,0,1): /* VFMS: d + (-n * m) (fused) */
+ /* XXXROUNDINGFIXME look up ARM reference for fused
+ multiply-add rounding */
+ putFReg(fD, triop(Iop_AddF32, rm,
+ getFReg(fD),
+ triop(Iop_MulF32, rm,
+ unop(Iop_NegF32, getFReg(fN)),
+ getFReg(fM))),
+ condT);
+ DIP("vfmss%s s%u, s%u, s%u\n", nCC(conq), fD, fN, fM);
+ goto decode_success_vfp;
default:
break;
}
|