| 1 | #include "longlong.h" |
| 2 | |
| 3 | static int bsub (); |
| 4 | |
| 5 | long long |
| 6 | __subdi3 (u, v) |
| 7 | long long u, v; |
| 8 | { |
| 9 | long a[2], b[2], c[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 | bsub (a, b, c, sizeof c); |
| 22 | |
| 23 | w.s.high = c[HIGH]; |
| 24 | w.s.low = c[LOW]; |
| 25 | return w.ll; |
| 26 | } |
| 27 | |
| 28 | static int |
| 29 | bsub (a, b, c, n) |
| 30 | unsigned short *a, *b, *c; |
| 31 | size_t n; |
| 32 | { |
| 33 | signed long acc; |
| 34 | int i; |
| 35 | |
| 36 | n /= sizeof *c; |
| 37 | |
| 38 | acc = 0; |
| 39 | for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) |
| 40 | { |
| 41 | /* Widen before subtracting to avoid loss of high bits. */ |
| 42 | acc += (long) a[i] - b[i]; |
| 43 | c[i] = acc & low16; |
| 44 | acc = acc >> 16; |
| 45 | } |
| 46 | return acc; |
| 47 | } |