diff options
author | Jay Foad <jay.foad@gmail.com> | 2014-04-14 16:23:15 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-04-14 23:28:24 +0100 |
commit | 244b478386260a8a9150b501bc97644e2e07f8d3 (patch) | |
tree | f7127bc02f4722ab1b47b16920ee402bae68b965 | |
parent | c39e1ef77c76729f34cdcb09bbb3a5096d91a740 (diff) | |
download | op-kernel-dev-244b478386260a8a9150b501bc97644e2e07f8d3.zip op-kernel-dev-244b478386260a8a9150b501bc97644e2e07f8d3.tar.gz |
ARM: 8026/1: Fix emulation of multiply accumulate instructions
The emulation for single and double precision multiply accumulate
instructions correctly normalised any denormal values in the operand
registers, but failed to normalise the destination (accumulator)
register.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=70501
Signed-off-by: Jay Foad <jay.foad@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/vfp/vfpdouble.c | 2 | ||||
-rw-r--r-- | arch/arm/vfp/vfpsingle.c | 2 |
2 files changed, 4 insertions, 0 deletions
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 6cac43b..423f56d 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -866,6 +866,8 @@ vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, ch vdp.sign = vfp_sign_negate(vdp.sign); vfp_double_unpack(&vdn, vfp_get_double(dd)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); if (negate & NEG_SUBTRACT) vdn.sign = vfp_sign_negate(vdn.sign); diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index b252631..4f96c16 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -915,6 +915,8 @@ vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, cha v = vfp_get_float(sd); pr_debug("VFP: s%u = %08x\n", sd, v); vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); if (negate & NEG_SUBTRACT) vsn.sign = vfp_sign_negate(vsn.sign); |