xref: /csrg-svn/sys/sparc/fpu/fpu_mul.c (revision 55114)
1*55114Storek /*
2*55114Storek  * Copyright (c) 1992 The Regents of the University of California.
3*55114Storek  * All rights reserved.
4*55114Storek  *
5*55114Storek  * This software was developed by the Computer Systems Engineering group
6*55114Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7*55114Storek  * contributed to Berkeley.
8*55114Storek  *
9*55114Storek  * %sccs.include.redist.c%
10*55114Storek  *
11*55114Storek  *	@(#)fpu_mul.c	7.1 (Berkeley) 07/13/92
12*55114Storek  *
13*55114Storek  * from: $Header: fpu_mul.c,v 1.2 92/06/17 05:41:34 torek Exp $
14*55114Storek  */
15*55114Storek 
16*55114Storek /*
17*55114Storek  * Perform an FPU multiply (return x * y).
18*55114Storek  */
19*55114Storek 
20*55114Storek #include "sys/types.h"
21*55114Storek 
22*55114Storek #include "machine/reg.h"
23*55114Storek 
24*55114Storek #include "fpu_arith.h"
25*55114Storek #include "fpu_emu.h"
26*55114Storek 
27*55114Storek /*
28*55114Storek  * The multiplication algorithm for normal numbers is as follows:
29*55114Storek  *
30*55114Storek  * The fraction of the product is built in the usual stepwise fashion.
31*55114Storek  * Each step consists of shifting the accumulator right one bit
32*55114Storek  * (maintaining any guard bits) and, if the next bit in y is set,
33*55114Storek  * adding the multiplicand (x) to the accumulator.  Then, in any case,
34*55114Storek  * we advance one bit leftward in y.  Algorithmically:
35*55114Storek  *
36*55114Storek  *	A = 0;
37*55114Storek  *	for (bit = 0; bit < FP_NMANT; bit++) {
38*55114Storek  *		sticky |= A & 1, A >>= 1;
39*55114Storek  *		if (Y & (1 << bit))
40*55114Storek  *			A += X;
41*55114Storek  *	}
42*55114Storek  *
43*55114Storek  * (X and Y here represent the mantissas of x and y respectively.)
44*55114Storek  * The resultant accumulator (A) is the product's mantissa.  It may
45*55114Storek  * be as large as 11.11111... in binary and hence may need to be
46*55114Storek  * shifted right, but at most one bit.
47*55114Storek  *
48*55114Storek  * Since we do not have efficient multiword arithmetic, we code the
49*55114Storek  * accumulator as four separate words, just like any other mantissa.
50*55114Storek  * We use local `register' variables in the hope that this is faster
51*55114Storek  * than memory.  We keep x->fp_mant in locals for the same reason.
52*55114Storek  *
53*55114Storek  * In the algorithm above, the bits in y are inspected one at a time.
54*55114Storek  * We will pick them up 32 at a time and then deal with those 32, one
55*55114Storek  * at a time.  Note, however, that we know several things about y:
56*55114Storek  *
57*55114Storek  *    - the guard and round bits at the bottom are sure to be zero;
58*55114Storek  *
59*55114Storek  *    - often many low bits are zero (y is often from a single or double
60*55114Storek  *	precision source);
61*55114Storek  *
62*55114Storek  *    - bit FP_NMANT-1 is set, and FP_1*2 fits in a word.
63*55114Storek  *
64*55114Storek  * We can also test for 32-zero-bits swiftly.  In this case, the center
65*55114Storek  * part of the loop---setting sticky, shifting A, and not adding---will
66*55114Storek  * run 32 times without adding X to A.  We can do a 32-bit shift faster
67*55114Storek  * by simply moving words.  Since zeros are common, we optimize this case.
68*55114Storek  * Furthermore, since A is initially zero, we can omit the shift as well
69*55114Storek  * until we reach a nonzero word.
70*55114Storek  */
71*55114Storek struct fpn *
72*55114Storek fpu_mul(fe)
73*55114Storek 	register struct fpemu *fe;
74*55114Storek {
75*55114Storek 	register struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2;
76*55114Storek 	register u_int a3, a2, a1, a0, x3, x2, x1, x0, bit, m;
77*55114Storek 	register int sticky;
78*55114Storek 	FPU_DECL_CARRY
79*55114Storek 
80*55114Storek 	/*
81*55114Storek 	 * Put the `heavier' operand on the right (see fpu_emu.h).
82*55114Storek 	 * Then we will have one of the following cases, taken in the
83*55114Storek 	 * following order:
84*55114Storek 	 *
85*55114Storek 	 *  - y = NaN.  Implied: if only one is a signalling NaN, y is.
86*55114Storek 	 *	The result is y.
87*55114Storek 	 *  - y = Inf.  Implied: x != NaN (is 0, number, or Inf: the NaN
88*55114Storek 	 *    case was taken care of earlier).
89*55114Storek 	 *	If x = 0, the result is NaN.  Otherwise the result
90*55114Storek 	 *	is y, with its sign reversed if x is negative.
91*55114Storek 	 *  - x = 0.  Implied: y is 0 or number.
92*55114Storek 	 *	The result is 0 (with XORed sign as usual).
93*55114Storek 	 *  - other.  Implied: both x and y are numbers.
94*55114Storek 	 *	The result is x * y (XOR sign, multiply bits, add exponents).
95*55114Storek 	 */
96*55114Storek 	ORDER(x, y);
97*55114Storek 	if (ISNAN(y)) {
98*55114Storek 		y->fp_sign ^= x->fp_sign;
99*55114Storek 		return (y);
100*55114Storek 	}
101*55114Storek 	if (ISINF(y)) {
102*55114Storek 		if (ISZERO(x))
103*55114Storek 			return (fpu_newnan(fe));
104*55114Storek 		y->fp_sign ^= x->fp_sign;
105*55114Storek 		return (y);
106*55114Storek 	}
107*55114Storek 	if (ISZERO(x)) {
108*55114Storek 		x->fp_sign ^= y->fp_sign;
109*55114Storek 		return (x);
110*55114Storek 	}
111*55114Storek 
112*55114Storek 	/*
113*55114Storek 	 * Setup.  In the code below, the mask `m' will hold the current
114*55114Storek 	 * mantissa byte from y.  The variable `bit' denotes the bit
115*55114Storek 	 * within m.  We also define some macros to deal with everything.
116*55114Storek 	 */
117*55114Storek 	x3 = x->fp_mant[3];
118*55114Storek 	x2 = x->fp_mant[2];
119*55114Storek 	x1 = x->fp_mant[1];
120*55114Storek 	x0 = x->fp_mant[0];
121*55114Storek 	sticky = a3 = a2 = a1 = a0 = 0;
122*55114Storek 
123*55114Storek #define	ADD	/* A += X */ \
124*55114Storek 	FPU_ADDS(a3, a3, x3); \
125*55114Storek 	FPU_ADDCS(a2, a2, x2); \
126*55114Storek 	FPU_ADDCS(a1, a1, x1); \
127*55114Storek 	FPU_ADDC(a0, a0, x0)
128*55114Storek 
129*55114Storek #define	SHR1	/* A >>= 1, with sticky */ \
130*55114Storek 	sticky |= a3 & 1, a3 = (a3 >> 1) | (a2 << 31), \
131*55114Storek 	a2 = (a2 >> 1) | (a1 << 31), a1 = (a1 >> 1) | (a0 << 31), a0 >>= 1
132*55114Storek 
133*55114Storek #define	SHR32	/* A >>= 32, with sticky */ \
134*55114Storek 	sticky |= a3, a3 = a2, a2 = a1, a1 = a0, a0 = 0
135*55114Storek 
136*55114Storek #define	STEP	/* each 1-bit step of the multiplication */ \
137*55114Storek 	SHR1; if (bit & m) { ADD; }; bit <<= 1
138*55114Storek 
139*55114Storek 	/*
140*55114Storek 	 * We are ready to begin.  The multiply loop runs once for each
141*55114Storek 	 * of the four 32-bit words.  Some words, however, are special.
142*55114Storek 	 * As noted above, the low order bits of Y are often zero.  Even
143*55114Storek 	 * if not, the first loop can certainly skip the guard bits.
144*55114Storek 	 * The last word of y has its highest 1-bit in position FP_NMANT-1,
145*55114Storek 	 * so we stop the loop when we move past that bit.
146*55114Storek 	 */
147*55114Storek 	if ((m = y->fp_mant[3]) == 0) {
148*55114Storek 		/* SHR32; */			/* unneeded since A==0 */
149*55114Storek 	} else {
150*55114Storek 		bit = 1 << FP_NG;
151*55114Storek 		do {
152*55114Storek 			STEP;
153*55114Storek 		} while (bit != 0);
154*55114Storek 	}
155*55114Storek 	if ((m = y->fp_mant[2]) == 0) {
156*55114Storek 		SHR32;
157*55114Storek 	} else {
158*55114Storek 		bit = 1;
159*55114Storek 		do {
160*55114Storek 			STEP;
161*55114Storek 		} while (bit != 0);
162*55114Storek 	}
163*55114Storek 	if ((m = y->fp_mant[1]) == 0) {
164*55114Storek 		SHR32;
165*55114Storek 	} else {
166*55114Storek 		bit = 1;
167*55114Storek 		do {
168*55114Storek 			STEP;
169*55114Storek 		} while (bit != 0);
170*55114Storek 	}
171*55114Storek 	m = y->fp_mant[0];		/* definitely != 0 */
172*55114Storek 	bit = 1;
173*55114Storek 	do {
174*55114Storek 		STEP;
175*55114Storek 	} while (bit <= m);
176*55114Storek 
177*55114Storek 	/*
178*55114Storek 	 * Done with mantissa calculation.  Get exponent and handle
179*55114Storek 	 * 11.111...1 case, then put result in place.  We reuse x since
180*55114Storek 	 * it already has the right class (FP_NUM).
181*55114Storek 	 */
182*55114Storek 	m = x->fp_exp + y->fp_exp;
183*55114Storek 	if (a0 >= FP_2) {
184*55114Storek 		SHR1;
185*55114Storek 		m++;
186*55114Storek 	}
187*55114Storek 	x->fp_sign ^= y->fp_sign;
188*55114Storek 	x->fp_exp = m;
189*55114Storek 	x->fp_sticky = sticky;
190*55114Storek 	x->fp_mant[3] = a3;
191*55114Storek 	x->fp_mant[2] = a2;
192*55114Storek 	x->fp_mant[1] = a1;
193*55114Storek 	x->fp_mant[0] = a0;
194*55114Storek 	return (x);
195*55114Storek }
196