mul64fract.c 867 B

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