summaryrefslogtreecommitdiff
path: root/sys/src/9/port/mul64fract.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-06-26 15:13:10 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2016-06-26 15:13:10 +0200
commita99cf56c7d670f6af88cab39de91f1d6ac36416f (patch)
treefa016bece5cac7af37db387d10c36e5a590b2cec /sys/src/9/port/mul64fract.c
parent5bf09937da68b5b55e33cc24ea021ed08b2ae6e0 (diff)
kernel: more (arm) compiler friendly mul64fract()
the arm compiler can lift long->vlong casts on multiplcation and convert 64x64->64 multiplication into a 32x32->64 one with optional 64 bit accumulate.
Diffstat (limited to 'sys/src/9/port/mul64fract.c')
-rw-r--r--sys/src/9/port/mul64fract.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/sys/src/9/port/mul64fract.c b/sys/src/9/port/mul64fract.c
index ca6270739..aa3d1c9e2 100644
--- a/sys/src/9/port/mul64fract.c
+++ b/sys/src/9/port/mul64fract.c
@@ -21,19 +21,15 @@
void
mul64fract(uvlong *r, uvlong a, uvlong b)
{
- uvlong bh, bl;
- uvlong ah, al;
- uvlong res;
+ ulong bh, bl, ah, al;
- bl = b & 0xffffffffULL;
+ bl = b;
bh = b >> 32;
- al = a & 0xffffffffULL;
+ al = a;
ah = a >> 32;
- res = (al*bl)>>32;
- res += (al*bh);
- res += (ah*bl);
- res += (ah*bh)<<32;
-
- *r = res;
+ *r = (((uvlong)al*(uvlong)bl)>>32)
+ + ((uvlong)al*(uvlong)bh)
+ + ((uvlong)ah*(uvlong)bl)
+ + (((uvlong)ah*(uvlong)bh)<<32);
}