xref: /csrg-svn/lib/libc/quad/muldi3.c (revision 53459)
153430Sbostic /*-
253430Sbostic  * Copyright (c) 1992 The Regents of the University of California.
353430Sbostic  * All rights reserved.
453430Sbostic  *
553430Sbostic  * %sccs.include.redist.c%
653430Sbostic  */
753430Sbostic 
853430Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*53459Sbostic static char sccsid[] = "@(#)muldi3.c	5.5 (Berkeley) 05/12/92";
1053430Sbostic #endif /* LIBC_SCCS and not lint */
1153430Sbostic 
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 
3651749Smckusick #include "longlong.h"
3751749Smckusick 
3851749Smckusick static void bmul ();
3951749Smckusick 
4051749Smckusick long long
4151749Smckusick __muldi3 (u, v)
4251749Smckusick      long long u, v;
4351749Smckusick {
4451749Smckusick   long a[2], b[2], c[2][2];
4551749Smckusick   long_long w;
4651749Smckusick   long_long uu, vv;
4751749Smckusick 
4851749Smckusick   uu.ll = u;
4951749Smckusick   vv.ll = v;
5051749Smckusick 
5151749Smckusick   a[HIGH] = uu.s.high;
5251749Smckusick   a[LOW] = uu.s.low;
5351749Smckusick   b[HIGH] = vv.s.high;
5451749Smckusick   b[LOW] = vv.s.low;
5551749Smckusick 
5651749Smckusick   bmul (a, b, c, sizeof a, sizeof b);
5751749Smckusick 
5851749Smckusick   w.s.high = c[LOW][HIGH];
5951749Smckusick   w.s.low = c[LOW][LOW];
6051749Smckusick   return w.ll;
6151749Smckusick }
6251749Smckusick 
6351749Smckusick static void
6451749Smckusick bmul (a, b, c, m, n)
6551749Smckusick     unsigned short *a, *b, *c;
6653458Sbostic     unsigned long m, n;
6751749Smckusick {
6851749Smckusick   int i, j;
6951750Smckusick   unsigned short *d;
7051749Smckusick   unsigned long acc;
7151749Smckusick 
7251749Smckusick   m /= sizeof *a;
7351749Smckusick   n /= sizeof *b;
7451749Smckusick 
7551750Smckusick   for (i = m + n, d = c; i-- > 0; *d++ = 0)
7651750Smckusick     ;
7751750Smckusick 
7851749Smckusick   for (j = little_end (n); is_not_msd (j, n); j = next_msd (j))
7951749Smckusick     {
8051749Smckusick       unsigned short *c1 = c + j + little_end (2);
8151749Smckusick       acc = 0;
8251749Smckusick       for (i = little_end (m); is_not_msd (i, m); i = next_msd (i))
8351749Smckusick 	{
8451749Smckusick 	  /* Widen before arithmetic to avoid loss of high bits.  */
8551749Smckusick 	  acc += (unsigned long) a[i] * b[j] + c1[i];
8651749Smckusick 	  c1[i] = acc & low16;
8751749Smckusick 	  acc = acc >> 16;
8851749Smckusick 	}
8951749Smckusick       c1[i] = acc;
9051749Smckusick     }
9151749Smckusick }
92