xref: /csrg-svn/lib/libc/quad/subdi3.c (revision 53458)
1 /*-
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)subdi3.c	5.2 (Berkeley) 05/12/92";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include "longlong.h"
13 
14 static int bsub ();
15 
16 long long
17 __subdi3 (u, v)
18      long long u, v;
19 {
20   long a[2], b[2], c[2];
21   long_long w;
22   long_long uu, vv;
23 
24   uu.ll = u;
25   vv.ll = v;
26 
27   a[HIGH] = uu.s.high;
28   a[LOW] = uu.s.low;
29   b[HIGH] = vv.s.high;
30   b[LOW] = vv.s.low;
31 
32   bsub (a, b, c, sizeof c);
33 
34   w.s.high = c[HIGH];
35   w.s.low = c[LOW];
36   return w.ll;
37 }
38 
39 static int
40 bsub (a, b, c, n)
41      unsigned short *a, *b, *c;
42      unsigned long n;
43 {
44   signed long acc;
45   int i;
46 
47   n /= sizeof *c;
48 
49   acc = 0;
50   for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
51     {
52       /* Widen before subtracting to avoid loss of high bits.  */
53       acc += (long) a[i] - b[i];
54       c[i] = acc & low16;
55       acc = acc >> 16;
56     }
57   return acc;
58 }
59