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