diff options
Diffstat (limited to 'os/port/mul64fract.c')
| -rw-r--r-- | os/port/mul64fract.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/os/port/mul64fract.c b/os/port/mul64fract.c new file mode 100644 index 00000000..ca627073 --- /dev/null +++ b/os/port/mul64fract.c @@ -0,0 +1,39 @@ +#include <u.h> + +/* mul64fract(uvlong*r, uvlong a, uvlong b) + * + * Multiply two 64 numbers and return the middle 64 bits of the 128 bit result. + * + * The assumption is that one of the numbers is a + * fixed point number with the integer portion in the + * high word and the fraction in the low word. + * + * There should be an assembler version of this routine + * for each architecture. This one is intended to + * make ports easier. + * + * ignored r0 = lo(a0*b0) + * lsw of result r1 = hi(a0*b0) +lo(a0*b1) +lo(a1*b0) + * msw of result r2 = hi(a0*b1) +hi(a1*b0) +lo(a1*b1) + * ignored r3 = hi(a1*b1) + */ + +void +mul64fract(uvlong *r, uvlong a, uvlong b) +{ + uvlong bh, bl; + uvlong ah, al; + uvlong res; + + bl = b & 0xffffffffULL; + bh = b >> 32; + al = a & 0xffffffffULL; + ah = a >> 32; + + res = (al*bl)>>32; + res += (al*bh); + res += (ah*bl); + res += (ah*bh)<<32; + + *r = res; +} |
