[PATCH] ARM: Fix VFP to use do_div()
VFP used __divdi3 64-bit division needlessly. Convert it to use our 64-bit by 32-bit division instead. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
b3402cf50e
commit
438a761679
@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
|
|||||||
if (nh >= m)
|
if (nh >= m)
|
||||||
return ~0ULL;
|
return ~0ULL;
|
||||||
mh = m >> 32;
|
mh = m >> 32;
|
||||||
z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32;
|
if (mh << 32 <= nh) {
|
||||||
|
z = 0xffffffff00000000ULL;
|
||||||
|
} else {
|
||||||
|
z = nh;
|
||||||
|
do_div(z, mh);
|
||||||
|
z <<= 32;
|
||||||
|
}
|
||||||
mul64to128(&termh, &terml, m, z);
|
mul64to128(&termh, &terml, m, z);
|
||||||
sub128(&remh, &reml, nh, nl, termh, terml);
|
sub128(&remh, &reml, nh, nl, termh, terml);
|
||||||
ml = m << 32;
|
ml = m << 32;
|
||||||
@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
|
|||||||
add128(&remh, &reml, remh, reml, mh, ml);
|
add128(&remh, &reml, remh, reml, mh, ml);
|
||||||
}
|
}
|
||||||
remh = (remh << 32) | (reml >> 32);
|
remh = (remh << 32) | (reml >> 32);
|
||||||
z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh;
|
if (mh << 32 <= remh) {
|
||||||
|
z |= 0xffffffff;
|
||||||
|
} else {
|
||||||
|
do_div(remh, mh);
|
||||||
|
z |= remh;
|
||||||
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
*/
|
*/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#include <asm/div64.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/vfp.h>
|
#include <asm/vfp.h>
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
*/
|
*/
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#include <asm/div64.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/vfp.h>
|
#include <asm/vfp.h>
|
||||||
|
|
||||||
@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
|
|||||||
if (z <= a)
|
if (z <= a)
|
||||||
return (s32)a >> 1;
|
return (s32)a >> 1;
|
||||||
}
|
}
|
||||||
return (u32)(((u64)a << 31) / z) + (z >> 1);
|
{
|
||||||
|
u64 v = (u64)a << 31;
|
||||||
|
do_div(v, z);
|
||||||
|
return v + (z >> 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
|
static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
|
||||||
@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
|
|||||||
vsn.significand >>= 1;
|
vsn.significand >>= 1;
|
||||||
vsd.exponent++;
|
vsd.exponent++;
|
||||||
}
|
}
|
||||||
vsd.significand = ((u64)vsn.significand << 32) / vsm.significand;
|
{
|
||||||
|
u64 significand = (u64)vsn.significand << 32;
|
||||||
|
do_div(significand, vsm.significand);
|
||||||
|
vsd.significand = significand;
|
||||||
|
}
|
||||||
if ((vsd.significand & 0x3f) == 0)
|
if ((vsd.significand & 0x3f) == 0)
|
||||||
vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
|
vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user