1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
5 * Floating-point emulation code
12 * @(#) pa/spmath/sfmpy.c $Revision: 1.1 $
15 * Single Precision Floating-point Multiply
17 * External Interfaces:
18 * sgl_fmpy(srcptr1,srcptr2,dstptr,status)
20 * Internal Interfaces:
23 * <<please update with a overview of the operation of this file>>
30 #include "sgl_float.h"
33 * Single Precision Floating-point Multiply
38 sgl_floating_point *srcptr1,
39 sgl_floating_point *srcptr2,
40 sgl_floating_point *dstptr,
43 register unsigned int opnd1, opnd2, opnd3, result;
44 register int dest_exponent, count;
45 register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
51 * set sign bit of result
53 if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) Sgl_setnegativezero(result);
54 else Sgl_setzero(result);
56 * check first operand for NaN's or infinity
58 if (Sgl_isinfinity_exponent(opnd1)) {
59 if (Sgl_iszero_mantissa(opnd1)) {
60 if (Sgl_isnotnan(opnd2)) {
61 if (Sgl_iszero_exponentmantissa(opnd2)) {
63 * invalid since operands are infinity
66 if (Is_invalidtrap_enabled())
67 return(INVALIDEXCEPTION);
69 Sgl_makequietnan(result);
76 Sgl_setinfinity_exponentmantissa(result);
83 * is NaN; signaling or quiet?
85 if (Sgl_isone_signaling(opnd1)) {
86 /* trap if INVALIDTRAP enabled */
87 if (Is_invalidtrap_enabled())
88 return(INVALIDEXCEPTION);
94 * is second operand a signaling NaN?
96 else if (Sgl_is_signalingnan(opnd2)) {
97 /* trap if INVALIDTRAP enabled */
98 if (Is_invalidtrap_enabled())
99 return(INVALIDEXCEPTION);
102 Sgl_set_quiet(opnd2);
114 * check second operand for NaN's or infinity
116 if (Sgl_isinfinity_exponent(opnd2)) {
117 if (Sgl_iszero_mantissa(opnd2)) {
118 if (Sgl_iszero_exponentmantissa(opnd1)) {
119 /* invalid since operands are zero & infinity */
120 if (Is_invalidtrap_enabled())
121 return(INVALIDEXCEPTION);
123 Sgl_makequietnan(opnd2);
130 Sgl_setinfinity_exponentmantissa(result);
135 * is NaN; signaling or quiet?
137 if (Sgl_isone_signaling(opnd2)) {
138 /* trap if INVALIDTRAP enabled */
139 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
143 Sgl_set_quiet(opnd2);
154 dest_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS;
159 if (Sgl_isnotzero_exponent(opnd1)) {
161 Sgl_clear_signexponent_set_hidden(opnd1);
165 if (Sgl_iszero_mantissa(opnd1)) {
166 Sgl_setzero_exponentmantissa(result);
170 /* is denormalized, adjust exponent */
171 Sgl_clear_signexponent(opnd1);
172 Sgl_leftshiftby1(opnd1);
173 Sgl_normalize(opnd1,dest_exponent);
175 /* opnd2 needs to have hidden bit set with msb in hidden bit */
176 if (Sgl_isnotzero_exponent(opnd2)) {
177 Sgl_clear_signexponent_set_hidden(opnd2);
181 if (Sgl_iszero_mantissa(opnd2)) {
182 Sgl_setzero_exponentmantissa(result);
186 /* is denormalized; want to normalize */
187 Sgl_clear_signexponent(opnd2);
188 Sgl_leftshiftby1(opnd2);
189 Sgl_normalize(opnd2,dest_exponent);
192 /* Multiply two source mantissas together */
194 Sgl_leftshiftby4(opnd2); /* make room for guard bits */
197 * Four bits at a time are inspected in each loop, and a
198 * simple shift and add multiply algorithm is used.
200 for (count=1;count<SGL_P;count+=4) {
201 stickybit |= Slow4(opnd3);
202 Sgl_rightshiftby4(opnd3);
203 if (Sbit28(opnd1)) Sall(opnd3) += (Sall(opnd2) << 3);
204 if (Sbit29(opnd1)) Sall(opnd3) += (Sall(opnd2) << 2);
205 if (Sbit30(opnd1)) Sall(opnd3) += (Sall(opnd2) << 1);
206 if (Sbit31(opnd1)) Sall(opnd3) += Sall(opnd2);
207 Sgl_rightshiftby4(opnd1);
209 /* make sure result is left-justified */
210 if (Sgl_iszero_sign(opnd3)) {
211 Sgl_leftshiftby1(opnd3);
214 /* result mantissa >= 2. */
217 /* check for denormalized result */
218 while (Sgl_iszero_sign(opnd3)) {
219 Sgl_leftshiftby1(opnd3);
223 * check for guard, sticky and inexact bits
225 stickybit |= Sgl_all(opnd3) << (SGL_BITLENGTH - SGL_EXP_LENGTH + 1);
226 guardbit = Sbit24(opnd3);
227 inexact = guardbit | stickybit;
229 /* re-align mantissa */
230 Sgl_rightshiftby8(opnd3);
235 if (inexact && (dest_exponent>0 || Is_underflowtrap_enabled())) {
236 Sgl_clear_signexponent(opnd3);
237 switch (Rounding_mode()) {
239 if (Sgl_iszero_sign(result))
240 Sgl_increment(opnd3);
243 if (Sgl_isone_sign(result))
244 Sgl_increment(opnd3);
248 if (stickybit || Sgl_isone_lowmantissa(opnd3))
249 Sgl_increment(opnd3);
252 if (Sgl_isone_hidden(opnd3)) dest_exponent++;
254 Sgl_set_mantissa(result,opnd3);
259 if (dest_exponent >= SGL_INFINITY_EXPONENT) {
260 /* trap if OVERFLOWTRAP enabled */
261 if (Is_overflowtrap_enabled()) {
263 * Adjust bias of result
265 Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
268 if (Is_inexacttrap_enabled())
269 return(OVERFLOWEXCEPTION | INEXACTEXCEPTION);
270 else Set_inexactflag();
271 return(OVERFLOWEXCEPTION);
275 /* set result to infinity or largest number */
276 Sgl_setoverflow(result);
281 else if (dest_exponent <= 0) {
282 /* trap if UNDERFLOWTRAP enabled */
283 if (Is_underflowtrap_enabled()) {
285 * Adjust bias of result
287 Sgl_setwrapped_exponent(result,dest_exponent,unfl);
290 if (Is_inexacttrap_enabled())
291 return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION);
292 else Set_inexactflag();
293 return(UNDERFLOWEXCEPTION);
296 /* Determine if should set underflow flag */
298 if (dest_exponent == 0 && inexact) {
299 switch (Rounding_mode()) {
301 if (Sgl_iszero_sign(result)) {
302 Sgl_increment(opnd3);
303 if (Sgl_isone_hiddenoverflow(opnd3))
305 Sgl_decrement(opnd3);
309 if (Sgl_isone_sign(result)) {
310 Sgl_increment(opnd3);
311 if (Sgl_isone_hiddenoverflow(opnd3))
313 Sgl_decrement(opnd3);
317 if (guardbit && (stickybit ||
318 Sgl_isone_lowmantissa(opnd3))) {
319 Sgl_increment(opnd3);
320 if (Sgl_isone_hiddenoverflow(opnd3))
322 Sgl_decrement(opnd3);
329 * denormalize result or set to signed zero
332 Sgl_denormalize(opnd3,dest_exponent,guardbit,stickybit,inexact);
334 /* return zero or smallest number */
336 switch (Rounding_mode()) {
338 if (Sgl_iszero_sign(result)) {
339 Sgl_increment(opnd3);
343 if (Sgl_isone_sign(result)) {
344 Sgl_increment(opnd3);
348 if (guardbit && (stickybit ||
349 Sgl_isone_lowmantissa(opnd3))) {
350 Sgl_increment(opnd3);
354 if (is_tiny) Set_underflowflag();
356 Sgl_set_exponentmantissa(result,opnd3);
358 else Sgl_set_exponent(result,dest_exponent);
361 /* check for inexact */
363 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
364 else Set_inexactflag();