mul64fract.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. /* mul64fract(uint64_t*r, uint64_t a, uint64_t b)
  11. *
  12. * Multiply two 64 numbers and return the middle 64 bits of the 128 bit result.
  13. *
  14. * The assumption is that one of the numbers is a
  15. * fixed point number with the integer portion in the
  16. * high word and the fraction in the low word.
  17. *
  18. * There should be an assembler version of this routine
  19. * for each architecture. This one is intended to
  20. * make ports easier.
  21. *
  22. * ignored r0 = lo(a0*b0)
  23. * lsw of result r1 = hi(a0*b0) +lo(a0*b1) +lo(a1*b0)
  24. * msw of result r2 = hi(a0*b1) +hi(a1*b0) +lo(a1*b1)
  25. * ignored r3 = hi(a1*b1)
  26. */
  27. void
  28. mul64fract(uint64_t *r, uint64_t a, uint64_t b)
  29. {
  30. uint64_t bh, bl;
  31. uint64_t ah, al;
  32. uint64_t res;
  33. bl = b & 0xffffffffULL;
  34. bh = b >> 32;
  35. al = a & 0xffffffffULL;
  36. ah = a >> 32;
  37. res = (al*bl)>>32;
  38. res += (al*bh);
  39. res += (ah*bl);
  40. res += (ah*bh)<<32;
  41. *r = res;
  42. }