xref: /csrg-svn/lib/libc/quad/muldi3.c (revision 51750)
151749Smckusick #include "longlong.h"
251749Smckusick 
351749Smckusick static void bmul ();
451749Smckusick 
551749Smckusick long long
651749Smckusick __muldi3 (u, v)
751749Smckusick      long long u, v;
851749Smckusick {
951749Smckusick   long a[2], b[2], c[2][2];
1051749Smckusick   long_long w;
1151749Smckusick   long_long uu, vv;
1251749Smckusick 
1351749Smckusick   uu.ll = u;
1451749Smckusick   vv.ll = v;
1551749Smckusick 
1651749Smckusick   a[HIGH] = uu.s.high;
1751749Smckusick   a[LOW] = uu.s.low;
1851749Smckusick   b[HIGH] = vv.s.high;
1951749Smckusick   b[LOW] = vv.s.low;
2051749Smckusick 
2151749Smckusick   bmul (a, b, c, sizeof a, sizeof b);
2251749Smckusick 
2351749Smckusick   w.s.high = c[LOW][HIGH];
2451749Smckusick   w.s.low = c[LOW][LOW];
2551749Smckusick   return w.ll;
2651749Smckusick }
2751749Smckusick 
2851749Smckusick static void
2951749Smckusick bmul (a, b, c, m, n)
3051749Smckusick     unsigned short *a, *b, *c;
3151749Smckusick     size_t m, n;
3251749Smckusick {
3351749Smckusick   int i, j;
34*51750Smckusick   unsigned short *d;
3551749Smckusick   unsigned long acc;
3651749Smckusick 
3751749Smckusick   m /= sizeof *a;
3851749Smckusick   n /= sizeof *b;
3951749Smckusick 
40*51750Smckusick   for (i = m + n, d = c; i-- > 0; *d++ = 0)
41*51750Smckusick     ;
42*51750Smckusick 
4351749Smckusick   for (j = little_end (n); is_not_msd (j, n); j = next_msd (j))
4451749Smckusick     {
4551749Smckusick       unsigned short *c1 = c + j + little_end (2);
4651749Smckusick       acc = 0;
4751749Smckusick       for (i = little_end (m); is_not_msd (i, m); i = next_msd (i))
4851749Smckusick 	{
4951749Smckusick 	  /* Widen before arithmetic to avoid loss of high bits.  */
5051749Smckusick 	  acc += (unsigned long) a[i] * b[j] + c1[i];
5151749Smckusick 	  c1[i] = acc & low16;
5251749Smckusick 	  acc = acc >> 16;
5351749Smckusick 	}
5451749Smckusick       c1[i] = acc;
5551749Smckusick     }
5651749Smckusick }
57