adding GNU dc ("desk calculator")
[unix-history] / gnu / usr.bin / gcc1 / gnulib / longlong / muldi3.c
CommitLineData
15637ed4
RG
1#include "longlong.h"
2
3static void bmul ();
4
5long 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
28static void
29bmul (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}