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