Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 438a7616 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b3402cf5
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
	if (nh >= m)
		return ~0ULL;
	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);
	sub128(&remh, &reml, nh, nl, termh, terml);
	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);
	}
	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;
}

+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
 */
#include <linux/kernel.h>
#include <linux/bitops.h>

#include <asm/div64.h>
#include <asm/ptrace.h>
#include <asm/vfp.h>

+12 −2
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
 */
#include <linux/kernel.h>
#include <linux/bitops.h>

#include <asm/div64.h>
#include <asm/ptrace.h>
#include <asm/vfp.h>

@@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
		if (z <= a)
			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)
@@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
		vsn.significand >>= 1;
		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)
		vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);