FreeBSD/Linux Kernel Cross Reference
sys/port/mul64fract.c
1 #include <u.h>
2
3 /* mul64fract(uvlong*r, uvlong a, uvlong b)
4 *
5 * Multiply two 64 numbers and return the middle 64 bits of the 128 bit result.
6 *
7 * The assumption is that one of the numbers is a
8 * fixed point number with the integer portion in the
9 * high word and the fraction in the low word.
10 *
11 * There should be an assembler version of this routine
12 * for each architecture. This one is intended to
13 * make ports easier.
14 *
15 * ignored r0 = lo(a0*b0)
16 * lsw of result r1 = hi(a0*b0) +lo(a0*b1) +lo(a1*b0)
17 * msw of result r2 = hi(a0*b1) +hi(a1*b0) +lo(a1*b1)
18 * ignored r3 = hi(a1*b1)
19 */
20
21 void
22 mul64fract(uvlong *r, uvlong a, uvlong b)
23 {
24 uvlong bh, bl;
25 uvlong ah, al;
26 uvlong res;
27
28 bl = b & 0xffffffffULL;
29 bh = b >> 32;
30 al = a & 0xffffffffULL;
31 ah = a >> 32;
32
33 res = (al*bl)>>32;
34 res += (al*bh);
35 res += (ah*bl);
36 res += (ah*bh)<<32;
37
38 *r = res;
39 }
Cache object: 608d6f08d9d632874e1c3b19babed106
|