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 short *d; 35 unsigned long acc; 36 37 m /= sizeof *a; 38 n /= sizeof *b; 39 40 for (i = m + n, d = c; i-- > 0; *d++ = 0) 41 ; 42 43 for (j = little_end (n); is_not_msd (j, n); j = next_msd (j)) 44 { 45 unsigned short *c1 = c + j + little_end (2); 46 acc = 0; 47 for (i = little_end (m); is_not_msd (i, m); i = next_msd (i)) 48 { 49 /* Widen before arithmetic to avoid loss of high bits. */ 50 acc += (unsigned long) a[i] * b[j] + c1[i]; 51 c1[i] = acc & low16; 52 acc = acc >> 16; 53 } 54 c1[i] = acc; 55 } 56 } 57