home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LIBSRC.ZOO / libsrc / longlong / muldi3.c < prev    next >
C/C++ Source or Header  |  1992-02-22  |  950b  |  55 lines

  1. #include "longlong.h"
  2.  
  3. static void bmul ();
  4.  
  5. long long 
  6. __muldi3 (u, v)
  7.      long long u, v;
  8. {
  9.   long a[2], b[2], c[2][2];
  10.   long_long w;
  11.   long_long uu, vv;
  12.  
  13.   uu.ll = u;
  14.   vv.ll = v;
  15.  
  16.   a[HIGH] = uu.s.high;
  17.   a[LOW] = uu.s.low;
  18.   b[HIGH] = vv.s.high;
  19.   b[LOW] = vv.s.low;
  20.  
  21.   bmul (a, b, c, sizeof a, sizeof b);
  22.  
  23.   w.s.high = c[LOW][HIGH];
  24.   w.s.low = c[LOW][LOW];
  25.   return w.ll;
  26. }
  27.  
  28. static void 
  29. bmul (a, b, c, m, n)
  30.     unsigned short *a, *b, *c;
  31.     size_t m, n;
  32. {
  33.   int i, j;
  34.   unsigned long acc;
  35.  
  36.   bzero (c, m + n);
  37.  
  38.   m /= sizeof *a;
  39.   n /= sizeof *b;
  40.  
  41.   for (j = little_end (n); is_not_msd (j, n); j = next_msd (j))
  42.     {
  43.       unsigned short *c1 = c + j + little_end (2);
  44.       acc = 0;
  45.       for (i = little_end (m); is_not_msd (i, m); i = next_msd (i))
  46.     {
  47.       /* Widen before arithmetic to avoid loss of high bits.  */
  48.       acc += (unsigned long) a[i] * b[j] + c1[i];
  49.       c1[i] = acc & low16;
  50.       acc = acc >> 16;
  51.     }
  52.       c1[i] = acc;
  53.     }
  54. }
  55.