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