xref: /csrg-svn/lib/libc/quad/subdi3.c (revision 53459)
153444Sbostic /*-
253444Sbostic  * Copyright (c) 1992 The Regents of the University of California.
353444Sbostic  * All rights reserved.
453444Sbostic  *
553444Sbostic  * %sccs.include.redist.c%
653444Sbostic  */
753444Sbostic 
853444Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*53459Sbostic static char sccsid[] = "@(#)subdi3.c	5.3 (Berkeley) 05/12/92";
1053444Sbostic #endif /* LIBC_SCCS and not lint */
1153444Sbostic 
12*53459Sbostic /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
13*53459Sbostic 
14*53459Sbostic This file is part of GNU CC.
15*53459Sbostic 
16*53459Sbostic GNU CC is free software; you can redistribute it and/or modify
17*53459Sbostic it under the terms of the GNU General Public License as published by
18*53459Sbostic the Free Software Foundation; either version 2, or (at your option)
19*53459Sbostic any later version.
20*53459Sbostic 
21*53459Sbostic GNU CC is distributed in the hope that it will be useful,
22*53459Sbostic but WITHOUT ANY WARRANTY; without even the implied warranty of
23*53459Sbostic MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24*53459Sbostic GNU General Public License for more details.
25*53459Sbostic 
26*53459Sbostic You should have received a copy of the GNU General Public License
27*53459Sbostic along with GNU CC; see the file COPYING.  If not, write to
28*53459Sbostic the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
29*53459Sbostic 
30*53459Sbostic /* As a special exception, if you link this library with files
31*53459Sbostic    compiled with GCC to produce an executable, this does not cause
32*53459Sbostic    the resulting executable to be covered by the GNU General Public License.
33*53459Sbostic    This exception does not however invalidate any other reasons why
34*53459Sbostic    the executable file might be covered by the GNU General Public License.  */
35*53459Sbostic 
3653444Sbostic #include "longlong.h"
3753444Sbostic 
3853444Sbostic static int bsub ();
3953444Sbostic 
4053444Sbostic long long
4153444Sbostic __subdi3 (u, v)
4253444Sbostic      long long u, v;
4353444Sbostic {
4453444Sbostic   long a[2], b[2], c[2];
4553444Sbostic   long_long w;
4653444Sbostic   long_long uu, vv;
4753444Sbostic 
4853444Sbostic   uu.ll = u;
4953444Sbostic   vv.ll = v;
5053444Sbostic 
5153444Sbostic   a[HIGH] = uu.s.high;
5253444Sbostic   a[LOW] = uu.s.low;
5353444Sbostic   b[HIGH] = vv.s.high;
5453444Sbostic   b[LOW] = vv.s.low;
5553444Sbostic 
5653444Sbostic   bsub (a, b, c, sizeof c);
5753444Sbostic 
5853444Sbostic   w.s.high = c[HIGH];
5953444Sbostic   w.s.low = c[LOW];
6053444Sbostic   return w.ll;
6153444Sbostic }
6253444Sbostic 
6353444Sbostic static int
6453444Sbostic bsub (a, b, c, n)
6553444Sbostic      unsigned short *a, *b, *c;
6653458Sbostic      unsigned long n;
6753444Sbostic {
6853444Sbostic   signed long acc;
6953444Sbostic   int i;
7053444Sbostic 
7153444Sbostic   n /= sizeof *c;
7253444Sbostic 
7353444Sbostic   acc = 0;
7453444Sbostic   for (i = little_end (n); is_not_msd (i, n); i = next_msd (i))
7553444Sbostic     {
7653444Sbostic       /* Widen before subtracting to avoid loss of high bits.  */
7753444Sbostic       acc += (long) a[i] - b[i];
7853444Sbostic       c[i] = acc & low16;
7953444Sbostic       acc = acc >> 16;
8053444Sbostic     }
8153444Sbostic   return acc;
8253444Sbostic }
83