43 lines
994 B
C
43 lines
994 B
C
/* Copyright (C) Charles Forsyth
|
|
* See /doc/license/NOTICE.Plan9-9k.txt for details about the licensing.
|
|
*/
|
|
#include "u.h"
|
|
|
|
/* mul64fract(uint64_t*r, uint64_t a, uint64_t 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(uint64_t *r, uint64_t a, uint64_t b)
|
|
{
|
|
uint64_t bh, bl;
|
|
uint64_t ah, al;
|
|
uint64_t 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;
|
|
}
|