^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Linux/PA-RISC Project (http://www.parisc-linux.org/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Floating-point emulation code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * BEGIN_DESC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * File:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * @(#) pa/spmath/fmpyfadd.c $Revision: 1.1 $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Purpose:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Double Floating-point Multiply Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Double Floating-point Multiply Negate Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Single Floating-point Multiply Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Single Floating-point Multiply Negate Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * External Interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * dbl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * dbl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * sgl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * sgl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Internal Interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Theory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * <<please update with a overview of the operation of this file>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * END_DESC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "sgl_float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "dbl_float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Double Floating-point Multiply Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dbl_fmpyfadd(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dbl_floating_point *src1ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) dbl_floating_point *src2ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dbl_floating_point *src3ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned int *status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) dbl_floating_point *dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2, opnd3p1, opnd3p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) register unsigned int tmpresp1, tmpresp2, tmpresp3, tmpresp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int rightp1, rightp2, rightp3, rightp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned int resultp1, resultp2 = 0, resultp3 = 0, resultp4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) register int mpy_exponent, add_exponent, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) boolean inexact = FALSE, is_tiny = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int signlessleft1, signlessright1, save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) register int result_exponent, diff_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int sign_save, jumpsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) Dbl_copyfromptr(src1ptr,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) Dbl_copyfromptr(src2ptr,opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Dbl_copyfromptr(src3ptr,opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * set sign bit of result of multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) Dbl_setnegativezerop1(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) else Dbl_setzerop1(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Generate multiply exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) mpy_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) - DBL_BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * check first operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (Dbl_isinfinity_exponent(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (Dbl_isnotnan(opnd2p1,opnd2p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) Dbl_isnotnan(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * invalid since operands are infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * and zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (Dbl_isinfinity(opnd3p1,opnd3p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (Dbl_isone_signaling(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) Dbl_set_quiet(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * is second operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else if (Dbl_is_signalingnan(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) Dbl_set_quiet(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else if (Dbl_is_signalingnan(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * check second operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (Dbl_isinfinity_exponent(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (Dbl_isnotnan(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * invalid since multiply operands are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * zero & infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) Dbl_makequietnan(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (Dbl_isinfinity(opnd3p1,opnd3p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (Dbl_isone_signaling(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) Dbl_set_quiet(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) else if (Dbl_is_signalingnan(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * check third operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (Dbl_isinfinity_exponent(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* return infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (Dbl_isone_signaling(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Generate multiply mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (Dbl_isnotzero_exponent(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* set hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) Dbl_clear_signexponent_set_hidden(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) Dbl_or_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) Dbl_and_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) else if (Dbl_iszero_exponent(opnd3p1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) sign_save = Dbl_signextendedsign(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) Dbl_normalize(opnd3p1,opnd3p2,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) Dbl_set_sign(opnd3p1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) Dbl_setwrapped_exponent(opnd3p1,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* is denormalized, adjust exponent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) Dbl_clear_signexponent(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) Dbl_leftshiftby1(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) Dbl_normalize(opnd1p1,opnd1p2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* opnd2 needs to have hidden bit set with msb in hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (Dbl_isnotzero_exponent(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) Dbl_clear_signexponent_set_hidden(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) Dbl_or_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) Dbl_and_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) else if (Dbl_iszero_exponent(opnd3p1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) sign_save = Dbl_signextendedsign(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) Dbl_normalize(opnd3p1,opnd3p2,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) Dbl_set_sign(opnd3p1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) Dbl_setwrapped_exponent(opnd3p1,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* is denormalized; want to normalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) Dbl_clear_signexponent(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) Dbl_leftshiftby1(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) Dbl_normalize(opnd2p1,opnd2p2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Multiply the first two source mantissas together */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * The intermediate result will be kept in tmpres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * which needs enough room for 106 bits of mantissa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * so lets call it a Double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) Dblext_setzero(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * Four bits at a time are inspected in each loop, and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * simple shift and add multiply algorithm is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (count = DBL_P-1; count >= 0; count -= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) Dblext_rightshiftby4(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (Dbit28p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Fourword_add should be an ADD followed by 3 ADDC's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) opnd2p1<<3 | opnd2p2>>29, opnd2p2<<3, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (Dbit29p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) opnd2p1<<2 | opnd2p2>>30, opnd2p2<<2, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (Dbit30p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) opnd2p1<<1 | opnd2p2>>31, opnd2p2<<1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (Dbit31p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) opnd2p1, opnd2p2, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) Dbl_rightshiftby4(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (Is_dexthiddenoverflow(tmpresp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* result mantissa >= 2 (mantissa overflow) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mpy_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) Dblext_rightshiftby1(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Restore the sign of the mpy result which was saved in resultp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * The exponent will continue to be kept in mpy_exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) Dblext_set_sign(tmpresp1,Dbl_sign(resultp1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * No rounding is required, since the result of the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * is exact in the extended format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Now we are ready to perform the add portion of the operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * The exponents need to be kept as integers for now, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * multiply result might not fit into the exponent field. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * can't overflow or underflow because of this yet, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * add could bring the final result back into range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) add_exponent = Dbl_exponent(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * Check for denormalized or zero add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (add_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* right is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Left can't be zero and must be result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * The final result is now in tmpres and mpy_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * and needs to be rounded and squeezed back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * double precision format from double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) Dblext_copy(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) sign_save = Dbl_signextendedsign(resultp1);/*save sign*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Neither are zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Adjust exponent and normalize add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) sign_save = Dbl_signextendedsign(opnd3p1); /* save sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) Dbl_clear_signexponent(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) Dbl_normalize(opnd3p1,opnd3p2,add_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) Dbl_set_sign(opnd3p1,sign_save); /* restore sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) Dbl_clear_exponent_set_hidden(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Copy opnd3 to the double extended variable called right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) Dbl_copyto_dblext(opnd3p1,opnd3p2,rightp1,rightp2,rightp3,rightp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * A zero "save" helps discover equal operands (for later),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * and is used in swapping operands (if needed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) Dblext_xortointp1(tmpresp1,rightp1,/*to*/save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * Compare magnitude of operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) Dblext_copytoint_exponentmantissap1(tmpresp1,signlessleft1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) Dblext_copytoint_exponentmantissap1(rightp1,signlessright1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (mpy_exponent < add_exponent || mpy_exponent == add_exponent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) Dblext_ismagnitudeless(tmpresp2,rightp2,signlessleft1,signlessright1)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * Set the left operand to the larger one by XOR swap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * First finish the first word "save".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) Dblext_xorfromintp1(save,rightp1,/*to*/rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) Dblext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) Dblext_swap_lower(tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rightp2,rightp3,rightp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) diff_exponent = add_exponent - mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) result_exponent = add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) diff_exponent = mpy_exponent - add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Invariant: left is not smaller than right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * Special case alignment of operands that would force alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * beyond the extent of the extension. A further optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * could special case this but only reduces the path length for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * this infrequent case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (diff_exponent > DBLEXT_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) diff_exponent = DBLEXT_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Align right operand by shifting it to the right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) Dblext_clear_sign(rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) Dblext_right_align(rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /*shifted by*/diff_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* Treat sum and difference of the operands separately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if ((int)save < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * Difference of the two operands. Overflow can occur if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * multiply overflowed. A borrow can occur out of the hidden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * bit and force a post normalization phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) Dblext_subtract(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) sign_save = Dbl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (Dbl_iszero_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Handle normalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* A straightforward algorithm would now shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * result and extension left until the hidden bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * becomes one. Not all of the extension bits need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * participate in the shift. Only the two most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * significant bits (round and guard) are needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * If only a single shift is needed then the guard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * bit becomes a significant low order bit and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * extension must participate in the rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * If more than a single shift is needed, then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * bits to the right of the guard bit are zeros,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * and the guard bit may or may not be zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) Dblext_leftshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Need to check for a zero result. The sign and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * exponent fields have already been zeroed. The more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * efficient test of the full object can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if(Dblext_iszero(resultp1,resultp2,resultp3,resultp4)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* Must have been "x-x" or "x+(-x)". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (Is_rounding_mode(ROUNDMINUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) Dbl_setone_sign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) result_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Look to see if normalization is finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (Dbl_isone_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* No further normalization is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* Discover first one bit to determine shift amount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * Use a modified binary search. We have already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * shifted the result one position right and still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * not found a one so the remainder of the extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * must be zero and simplifies rounding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Scan bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) while (Dbl_iszero_hiddenhigh7mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) Dblext_leftshiftby8(resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) result_exponent -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Now narrow it down to the nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (Dbl_iszero_hiddenhigh3mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* The lower nibble contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * normalizing one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) Dblext_leftshiftby4(resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) result_exponent -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Select case where first bit is set (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * normalized) otherwise select the proper shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) jumpsize = Dbl_hiddenhigh3mantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (jumpsize <= 7) switch(jumpsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) Dblext_leftshiftby3(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) result_exponent -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) Dblext_leftshiftby2(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) result_exponent -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) Dblext_leftshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) result_exponent -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) } /* end if (hidden...)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Fall through and round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) } /* end if (save < 0)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* Add magnitudes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) Dblext_addition(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /*to*/resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) sign_save = Dbl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (Dbl_isone_hiddenoverflow(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Prenormalization required. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) Dblext_arithrightshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } /* end if hiddenoverflow... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) } /* end else ...add magnitudes... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* Round the result. If the extension and lower two words are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * all zeros, then the result is exact. Otherwise round in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * correct direction. Underflow is possible. If a postnormalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * is necessary, then the mantissa is all zeros so no shift is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (result_exponent <= 0 && !Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) Dblext_denormalize(resultp1,resultp2,resultp3,resultp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) result_exponent,is_tiny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) Dbl_set_sign(resultp1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (Dblext_isnotzero_mantissap3(resultp3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) Dblext_isnotzero_mantissap4(resultp4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) switch(Rounding_mode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case ROUNDNEAREST: /* The default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (Dblext_isone_highp3(resultp3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* at least 1/2 ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (Dblext_isnotzero_low31p3(resultp3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) Dblext_isnotzero_mantissap4(resultp4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) Dblext_isone_lowp2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* either exactly half way and odd or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * more than 1/2ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (Dbl_iszero_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* Round up positive results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (Dbl_isone_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Round down negative results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case ROUNDZERO:;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* truncate is simple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) } /* end switch... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (Dbl_isone_hiddenoverflow(resultp1)) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (result_exponent >= DBL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* trap if OVERFLOWTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (Is_overflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return (OPC_2E_OVERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return (OPC_2E_OVERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) Set_overflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* set result to infinity or largest number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) Dbl_setoverflow(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) } else if (result_exponent <= 0) { /* underflow case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return (OPC_2E_UNDERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) else if (inexact && is_tiny) Set_underflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) else Dbl_set_exponent(resultp1,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * Double Floating-point Multiply Negate Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) dbl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dbl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) unsigned int *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2, opnd3p1, opnd3p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) register unsigned int tmpresp1, tmpresp2, tmpresp3, tmpresp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) unsigned int rightp1, rightp2, rightp3, rightp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) unsigned int resultp1, resultp2 = 0, resultp3 = 0, resultp4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) register int mpy_exponent, add_exponent, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) boolean inexact = FALSE, is_tiny = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) unsigned int signlessleft1, signlessright1, save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) register int result_exponent, diff_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int sign_save, jumpsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) Dbl_copyfromptr(src1ptr,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) Dbl_copyfromptr(src2ptr,opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) Dbl_copyfromptr(src3ptr,opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * set sign bit of result of multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) Dbl_setzerop1(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) Dbl_setnegativezerop1(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * Generate multiply exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mpy_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) - DBL_BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * check first operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (Dbl_isinfinity_exponent(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (Dbl_isnotnan(opnd2p1,opnd2p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) Dbl_isnotnan(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * invalid since operands are infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * and zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (Dbl_isinfinity(opnd3p1,opnd3p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (Dbl_isone_signaling(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) Dbl_set_quiet(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * is second operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) else if (Dbl_is_signalingnan(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) Dbl_set_quiet(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) else if (Dbl_is_signalingnan(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * check second operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (Dbl_isinfinity_exponent(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (Dbl_isnotnan(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * invalid since multiply operands are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * zero & infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) Dbl_makequietnan(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (Dbl_isinfinity(opnd3p1,opnd3p2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (Dbl_isone_signaling(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) Dbl_set_quiet(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) else if (Dbl_is_signalingnan(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * check third operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (Dbl_isinfinity_exponent(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* return infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (Dbl_isone_signaling(opnd3p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) Dbl_set_quiet(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * Generate multiply mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (Dbl_isnotzero_exponent(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /* set hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) Dbl_clear_signexponent_set_hidden(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) Dbl_or_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) Dbl_and_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) else if (Dbl_iszero_exponent(opnd3p1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) sign_save = Dbl_signextendedsign(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) Dbl_normalize(opnd3p1,opnd3p2,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) Dbl_set_sign(opnd3p1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) Dbl_setwrapped_exponent(opnd3p1,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /* is denormalized, adjust exponent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) Dbl_clear_signexponent(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) Dbl_leftshiftby1(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) Dbl_normalize(opnd1p1,opnd1p2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* opnd2 needs to have hidden bit set with msb in hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (Dbl_isnotzero_exponent(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) Dbl_clear_signexponent_set_hidden(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) Dbl_or_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) Dbl_and_signs(opnd3p1,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) else if (Dbl_iszero_exponent(opnd3p1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) sign_save = Dbl_signextendedsign(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) Dbl_normalize(opnd3p1,opnd3p2,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) Dbl_set_sign(opnd3p1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) Dbl_setwrapped_exponent(opnd3p1,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) Dbl_copytoptr(opnd3p1,opnd3p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* is denormalized; want to normalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) Dbl_clear_signexponent(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) Dbl_leftshiftby1(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) Dbl_normalize(opnd2p1,opnd2p2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* Multiply the first two source mantissas together */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * The intermediate result will be kept in tmpres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * which needs enough room for 106 bits of mantissa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * so lets call it a Double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) Dblext_setzero(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * Four bits at a time are inspected in each loop, and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * simple shift and add multiply algorithm is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) for (count = DBL_P-1; count >= 0; count -= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) Dblext_rightshiftby4(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (Dbit28p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /* Fourword_add should be an ADD followed by 3 ADDC's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) opnd2p1<<3 | opnd2p2>>29, opnd2p2<<3, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (Dbit29p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) opnd2p1<<2 | opnd2p2>>30, opnd2p2<<2, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (Dbit30p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) opnd2p1<<1 | opnd2p2>>31, opnd2p2<<1, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (Dbit31p2(opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) opnd2p1, opnd2p2, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) Dbl_rightshiftby4(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (Is_dexthiddenoverflow(tmpresp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* result mantissa >= 2 (mantissa overflow) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) mpy_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) Dblext_rightshiftby1(tmpresp1,tmpresp2,tmpresp3,tmpresp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * Restore the sign of the mpy result which was saved in resultp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * The exponent will continue to be kept in mpy_exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) Dblext_set_sign(tmpresp1,Dbl_sign(resultp1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * No rounding is required, since the result of the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * is exact in the extended format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * Now we are ready to perform the add portion of the operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * The exponents need to be kept as integers for now, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * multiply result might not fit into the exponent field. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * can't overflow or underflow because of this yet, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * add could bring the final result back into range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) add_exponent = Dbl_exponent(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * Check for denormalized or zero add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (add_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /* right is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* Left can't be zero and must be result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * The final result is now in tmpres and mpy_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * and needs to be rounded and squeezed back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * double precision format from double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) Dblext_copy(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) sign_save = Dbl_signextendedsign(resultp1);/*save sign*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * Neither are zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * Adjust exponent and normalize add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) sign_save = Dbl_signextendedsign(opnd3p1); /* save sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) Dbl_clear_signexponent(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) Dbl_leftshiftby1(opnd3p1,opnd3p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) Dbl_normalize(opnd3p1,opnd3p2,add_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) Dbl_set_sign(opnd3p1,sign_save); /* restore sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) Dbl_clear_exponent_set_hidden(opnd3p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * Copy opnd3 to the double extended variable called right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) Dbl_copyto_dblext(opnd3p1,opnd3p2,rightp1,rightp2,rightp3,rightp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * A zero "save" helps discover equal operands (for later),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * and is used in swapping operands (if needed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) Dblext_xortointp1(tmpresp1,rightp1,/*to*/save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * Compare magnitude of operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) Dblext_copytoint_exponentmantissap1(tmpresp1,signlessleft1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) Dblext_copytoint_exponentmantissap1(rightp1,signlessright1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (mpy_exponent < add_exponent || mpy_exponent == add_exponent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) Dblext_ismagnitudeless(tmpresp2,rightp2,signlessleft1,signlessright1)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) * Set the left operand to the larger one by XOR swap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * First finish the first word "save".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) Dblext_xorfromintp1(save,rightp1,/*to*/rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) Dblext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) Dblext_swap_lower(tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) rightp2,rightp3,rightp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) diff_exponent = add_exponent - mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) result_exponent = add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) diff_exponent = mpy_exponent - add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* Invariant: left is not smaller than right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * Special case alignment of operands that would force alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * beyond the extent of the extension. A further optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * could special case this but only reduces the path length for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * this infrequent case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (diff_exponent > DBLEXT_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) diff_exponent = DBLEXT_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* Align right operand by shifting it to the right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) Dblext_clear_sign(rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) Dblext_right_align(rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /*shifted by*/diff_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /* Treat sum and difference of the operands separately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if ((int)save < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * Difference of the two operands. Overflow can occur if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * multiply overflowed. A borrow can occur out of the hidden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * bit and force a post normalization phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) Dblext_subtract(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) sign_save = Dbl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (Dbl_iszero_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /* Handle normalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /* A straightforward algorithm would now shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * result and extension left until the hidden bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * becomes one. Not all of the extension bits need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * participate in the shift. Only the two most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * significant bits (round and guard) are needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * If only a single shift is needed then the guard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * bit becomes a significant low order bit and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * extension must participate in the rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * If more than a single shift is needed, then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * bits to the right of the guard bit are zeros,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * and the guard bit may or may not be zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) Dblext_leftshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) /* Need to check for a zero result. The sign and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * exponent fields have already been zeroed. The more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * efficient test of the full object can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (Dblext_iszero(resultp1,resultp2,resultp3,resultp4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* Must have been "x-x" or "x+(-x)". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (Is_rounding_mode(ROUNDMINUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) Dbl_setone_sign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) result_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* Look to see if normalization is finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (Dbl_isone_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* No further normalization is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* Discover first one bit to determine shift amount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * Use a modified binary search. We have already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * shifted the result one position right and still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * not found a one so the remainder of the extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * must be zero and simplifies rounding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* Scan bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) while (Dbl_iszero_hiddenhigh7mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) Dblext_leftshiftby8(resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) result_exponent -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) /* Now narrow it down to the nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (Dbl_iszero_hiddenhigh3mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* The lower nibble contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * normalizing one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) Dblext_leftshiftby4(resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) result_exponent -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* Select case where first bit is set (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * normalized) otherwise select the proper shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) jumpsize = Dbl_hiddenhigh3mantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (jumpsize <= 7) switch(jumpsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) Dblext_leftshiftby3(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) result_exponent -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) Dblext_leftshiftby2(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) result_exponent -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) Dblext_leftshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) result_exponent -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) } /* end if (hidden...)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* Fall through and round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) } /* end if (save < 0)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* Add magnitudes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) Dblext_addition(tmpresp1,tmpresp2,tmpresp3,tmpresp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) rightp1,rightp2,rightp3,rightp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /*to*/resultp1,resultp2,resultp3,resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) sign_save = Dbl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (Dbl_isone_hiddenoverflow(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* Prenormalization required. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) Dblext_arithrightshiftby1(resultp1,resultp2,resultp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) resultp4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) } /* end if hiddenoverflow... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } /* end else ...add magnitudes... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) /* Round the result. If the extension and lower two words are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) * all zeros, then the result is exact. Otherwise round in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) * correct direction. Underflow is possible. If a postnormalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * is necessary, then the mantissa is all zeros so no shift is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (result_exponent <= 0 && !Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) Dblext_denormalize(resultp1,resultp2,resultp3,resultp4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) result_exponent,is_tiny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) Dbl_set_sign(resultp1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (Dblext_isnotzero_mantissap3(resultp3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) Dblext_isnotzero_mantissap4(resultp4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) switch(Rounding_mode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) case ROUNDNEAREST: /* The default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (Dblext_isone_highp3(resultp3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* at least 1/2 ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (Dblext_isnotzero_low31p3(resultp3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) Dblext_isnotzero_mantissap4(resultp4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) Dblext_isone_lowp2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* either exactly half way and odd or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * more than 1/2ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (Dbl_iszero_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /* Round up positive results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (Dbl_isone_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* Round down negative results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) Dbl_increment(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) case ROUNDZERO:;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) /* truncate is simple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) } /* end switch... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (Dbl_isone_hiddenoverflow(resultp1)) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (result_exponent >= DBL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /* Overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (Is_overflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return (OPC_2E_OVERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return (OPC_2E_OVERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) Set_overflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) Dbl_setoverflow(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) } else if (result_exponent <= 0) { /* underflow case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) Dbl_setwrapped_exponent(resultp1,result_exponent,unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return (OPC_2E_UNDERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) else if (inexact && is_tiny) Set_underflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) else Dbl_set_exponent(resultp1,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * Single Floating-point Multiply Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) sgl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) unsigned int *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) unsigned int opnd1, opnd2, opnd3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) register unsigned int tmpresp1, tmpresp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) unsigned int rightp1, rightp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) unsigned int resultp1, resultp2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) register int mpy_exponent, add_exponent, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) boolean inexact = FALSE, is_tiny = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) unsigned int signlessleft1, signlessright1, save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) register int result_exponent, diff_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) int sign_save, jumpsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) Sgl_copyfromptr(src1ptr,opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) Sgl_copyfromptr(src2ptr,opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) Sgl_copyfromptr(src3ptr,opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * set sign bit of result of multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) Sgl_setnegativezero(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) else Sgl_setzero(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * Generate multiply exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) mpy_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * check first operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (Sgl_isinfinity_exponent(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (Sgl_iszero_mantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (Sgl_isnotnan(opnd2) && Sgl_isnotnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (Sgl_iszero_exponentmantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * invalid since operands are infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * and zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (Sgl_isinfinity(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) Sgl_setinfinity_exponentmantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (Sgl_isone_signaling(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) Sgl_set_quiet(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * is second operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) else if (Sgl_is_signalingnan(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) Sgl_set_quiet(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) else if (Sgl_is_signalingnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) Sgl_copytoptr(opnd1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) * check second operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (Sgl_isinfinity_exponent(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (Sgl_iszero_mantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (Sgl_isnotnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (Sgl_iszero_exponentmantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * invalid since multiply operands are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * zero & infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) Sgl_makequietnan(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (Sgl_isinfinity(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) Sgl_setinfinity_exponentmantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (Sgl_isone_signaling(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) Sgl_set_quiet(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) else if (Sgl_is_signalingnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * check third operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (Sgl_isinfinity_exponent(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (Sgl_iszero_mantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) /* return infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (Sgl_isone_signaling(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * Generate multiply mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (Sgl_isnotzero_exponent(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) /* set hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) Sgl_clear_signexponent_set_hidden(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (Sgl_iszero_mantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (Sgl_iszero_exponentmantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) Sgl_or_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) Sgl_and_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) else if (Sgl_iszero_exponent(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) sign_save = Sgl_signextendedsign(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) Sgl_normalize(opnd3,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) Sgl_set_sign(opnd3,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) Sgl_setwrapped_exponent(opnd3,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) /* is denormalized, adjust exponent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) Sgl_clear_signexponent(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) Sgl_leftshiftby1(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) Sgl_normalize(opnd1,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) /* opnd2 needs to have hidden bit set with msb in hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (Sgl_isnotzero_exponent(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) Sgl_clear_signexponent_set_hidden(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (Sgl_iszero_mantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (Sgl_iszero_exponentmantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) Sgl_or_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) Sgl_and_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) else if (Sgl_iszero_exponent(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) sign_save = Sgl_signextendedsign(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) Sgl_normalize(opnd3,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) Sgl_set_sign(opnd3,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) Sgl_setwrapped_exponent(opnd3,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* is denormalized; want to normalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) Sgl_clear_signexponent(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) Sgl_leftshiftby1(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) Sgl_normalize(opnd2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /* Multiply the first two source mantissas together */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) * The intermediate result will be kept in tmpres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * which needs enough room for 106 bits of mantissa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) * so lets call it a Double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) Sglext_setzero(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * Four bits at a time are inspected in each loop, and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * simple shift and add multiply algorithm is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) for (count = SGL_P-1; count >= 0; count -= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) Sglext_rightshiftby4(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (Sbit28(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) /* Twoword_add should be an ADD followed by 2 ADDC's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) Twoword_add(tmpresp1, tmpresp2, opnd2<<3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (Sbit29(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) Twoword_add(tmpresp1, tmpresp2, opnd2<<2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) if (Sbit30(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) Twoword_add(tmpresp1, tmpresp2, opnd2<<1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (Sbit31(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) Twoword_add(tmpresp1, tmpresp2, opnd2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) Sgl_rightshiftby4(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (Is_sexthiddenoverflow(tmpresp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) /* result mantissa >= 2 (mantissa overflow) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) mpy_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) Sglext_rightshiftby4(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) Sglext_rightshiftby3(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * Restore the sign of the mpy result which was saved in resultp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) * The exponent will continue to be kept in mpy_exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) Sglext_set_sign(tmpresp1,Sgl_sign(resultp1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * No rounding is required, since the result of the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * is exact in the extended format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * Now we are ready to perform the add portion of the operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * The exponents need to be kept as integers for now, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) * multiply result might not fit into the exponent field. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) * can't overflow or underflow because of this yet, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) * add could bring the final result back into range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) add_exponent = Sgl_exponent(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) * Check for denormalized or zero add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (add_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (Sgl_iszero_mantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) /* right is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) /* Left can't be zero and must be result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * The final result is now in tmpres and mpy_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) * and needs to be rounded and squeezed back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) * double precision format from double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) Sglext_copy(tmpresp1,tmpresp2,resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) sign_save = Sgl_signextendedsign(resultp1);/*save sign*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) * Neither are zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) * Adjust exponent and normalize add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) sign_save = Sgl_signextendedsign(opnd3); /* save sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) Sgl_clear_signexponent(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) Sgl_normalize(opnd3,add_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) Sgl_set_sign(opnd3,sign_save); /* restore sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) Sgl_clear_exponent_set_hidden(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * Copy opnd3 to the double extended variable called right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) Sgl_copyto_sglext(opnd3,rightp1,rightp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * A zero "save" helps discover equal operands (for later),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * and is used in swapping operands (if needed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) Sglext_xortointp1(tmpresp1,rightp1,/*to*/save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) * Compare magnitude of operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) Sglext_copytoint_exponentmantissa(tmpresp1,signlessleft1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) Sglext_copytoint_exponentmantissa(rightp1,signlessright1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (mpy_exponent < add_exponent || mpy_exponent == add_exponent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) Sglext_ismagnitudeless(signlessleft1,signlessright1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) * Set the left operand to the larger one by XOR swap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) * First finish the first word "save".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) Sglext_xorfromintp1(save,rightp1,/*to*/rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) Sglext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) Sglext_swap_lower(tmpresp2,rightp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) diff_exponent = add_exponent - mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) result_exponent = add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) diff_exponent = mpy_exponent - add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) /* Invariant: left is not smaller than right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * Special case alignment of operands that would force alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) * beyond the extent of the extension. A further optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) * could special case this but only reduces the path length for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * this infrequent case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (diff_exponent > SGLEXT_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) diff_exponent = SGLEXT_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /* Align right operand by shifting it to the right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) Sglext_clear_sign(rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) Sglext_right_align(rightp1,rightp2,/*shifted by*/diff_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /* Treat sum and difference of the operands separately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if ((int)save < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) * Difference of the two operands. Overflow can occur if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) * multiply overflowed. A borrow can occur out of the hidden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) * bit and force a post normalization phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) Sglext_subtract(tmpresp1,tmpresp2, rightp1,rightp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) sign_save = Sgl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (Sgl_iszero_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /* Handle normalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) /* A straightforward algorithm would now shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) * result and extension left until the hidden bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * becomes one. Not all of the extension bits need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) * participate in the shift. Only the two most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) * significant bits (round and guard) are needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) * If only a single shift is needed then the guard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) * bit becomes a significant low order bit and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * extension must participate in the rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * If more than a single shift is needed, then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * bits to the right of the guard bit are zeros,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * and the guard bit may or may not be zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) Sglext_leftshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) /* Need to check for a zero result. The sign and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) * exponent fields have already been zeroed. The more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) * efficient test of the full object can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (Sglext_iszero(resultp1,resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /* Must have been "x-x" or "x+(-x)". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) if (Is_rounding_mode(ROUNDMINUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) Sgl_setone_sign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) result_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /* Look to see if normalization is finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (Sgl_isone_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) /* No further normalization is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) /* Discover first one bit to determine shift amount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) * Use a modified binary search. We have already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) * shifted the result one position right and still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) * not found a one so the remainder of the extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) * must be zero and simplifies rounding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) /* Scan bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) while (Sgl_iszero_hiddenhigh7mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) Sglext_leftshiftby8(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) result_exponent -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /* Now narrow it down to the nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (Sgl_iszero_hiddenhigh3mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /* The lower nibble contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) * normalizing one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) Sglext_leftshiftby4(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) result_exponent -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) /* Select case where first bit is set (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) * normalized) otherwise select the proper shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) jumpsize = Sgl_hiddenhigh3mantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (jumpsize <= 7) switch(jumpsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) Sglext_leftshiftby3(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) result_exponent -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) Sglext_leftshiftby2(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) result_exponent -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) Sglext_leftshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) result_exponent -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) } /* end if (hidden...)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) /* Fall through and round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) } /* end if (save < 0)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) /* Add magnitudes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) Sglext_addition(tmpresp1,tmpresp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) rightp1,rightp2, /*to*/resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) sign_save = Sgl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) if (Sgl_isone_hiddenoverflow(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* Prenormalization required. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) Sglext_arithrightshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) } /* end if hiddenoverflow... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) } /* end else ...add magnitudes... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /* Round the result. If the extension and lower two words are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * all zeros, then the result is exact. Otherwise round in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * correct direction. Underflow is possible. If a postnormalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * is necessary, then the mantissa is all zeros so no shift is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (result_exponent <= 0 && !Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) Sglext_denormalize(resultp1,resultp2,result_exponent,is_tiny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) Sgl_set_sign(resultp1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (Sglext_isnotzero_mantissap2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) switch(Rounding_mode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) case ROUNDNEAREST: /* The default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (Sglext_isone_highp2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) /* at least 1/2 ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (Sglext_isnotzero_low31p2(resultp2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) Sglext_isone_lowp1(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* either exactly half way and odd or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * more than 1/2ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (Sgl_iszero_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /* Round up positive results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (Sgl_isone_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) /* Round down negative results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) case ROUNDZERO:;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) /* truncate is simple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) } /* end switch... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (Sgl_isone_hiddenoverflow(resultp1)) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (result_exponent >= SGL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* Overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) if (Is_overflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) Sgl_setwrapped_exponent(resultp1,result_exponent,ovfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) return (OPC_2E_OVERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return (OPC_2E_OVERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) Set_overflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) Sgl_setoverflow(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) } else if (result_exponent <= 0) { /* underflow case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) if (Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) Sgl_setwrapped_exponent(resultp1,result_exponent,unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) return (OPC_2E_UNDERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) else if (inexact && is_tiny) Set_underflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) else Sgl_set_exponent(resultp1,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) * Single Floating-point Multiply Negate Fused Add
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) sgl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) unsigned int *status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) unsigned int opnd1, opnd2, opnd3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) register unsigned int tmpresp1, tmpresp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) unsigned int rightp1, rightp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) unsigned int resultp1, resultp2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) register int mpy_exponent, add_exponent, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) boolean inexact = FALSE, is_tiny = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) unsigned int signlessleft1, signlessright1, save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) register int result_exponent, diff_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) int sign_save, jumpsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) Sgl_copyfromptr(src1ptr,opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) Sgl_copyfromptr(src2ptr,opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) Sgl_copyfromptr(src3ptr,opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) * set sign bit of result of multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) Sgl_setzero(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) Sgl_setnegativezero(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * Generate multiply exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) mpy_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * check first operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) if (Sgl_isinfinity_exponent(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (Sgl_iszero_mantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (Sgl_isnotnan(opnd2) && Sgl_isnotnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (Sgl_iszero_exponentmantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) * invalid since operands are infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) * and zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (Sgl_isinfinity(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) Sgl_setinfinity_exponentmantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (Sgl_isone_signaling(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) Sgl_set_quiet(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) * is second operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) else if (Sgl_is_signalingnan(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) Sgl_set_quiet(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) else if (Sgl_is_signalingnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) Sgl_copytoptr(opnd1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) * check second operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (Sgl_isinfinity_exponent(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) if (Sgl_iszero_mantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (Sgl_isnotnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (Sgl_iszero_exponentmantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) * invalid since multiply operands are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) * zero & infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) Sgl_makequietnan(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) * Check third operand for infinity with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) * sign opposite of the multiply result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (Sgl_isinfinity(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) * invalid since attempting a magnitude
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) * subtraction of infinities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) Sgl_makequietnan(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) * return infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) Sgl_setinfinity_exponentmantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (Sgl_isone_signaling(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) Sgl_set_quiet(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) * is third operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) else if (Sgl_is_signalingnan(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) Sgl_copytoptr(opnd2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) * check third operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (Sgl_isinfinity_exponent(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (Sgl_iszero_mantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) /* return infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) if (Sgl_isone_signaling(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) return(OPC_2E_INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) Sgl_set_quiet(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) * Generate multiply mantissa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (Sgl_isnotzero_exponent(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) /* set hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) Sgl_clear_signexponent_set_hidden(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if (Sgl_iszero_mantissa(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) if (Sgl_iszero_exponentmantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) Sgl_or_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) Sgl_and_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) else if (Sgl_iszero_exponent(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) sign_save = Sgl_signextendedsign(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) Sgl_normalize(opnd3,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) Sgl_set_sign(opnd3,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) Sgl_setwrapped_exponent(opnd3,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) /* is denormalized, adjust exponent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) Sgl_clear_signexponent(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) Sgl_leftshiftby1(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) Sgl_normalize(opnd1,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /* opnd2 needs to have hidden bit set with msb in hidden bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if (Sgl_isnotzero_exponent(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) Sgl_clear_signexponent_set_hidden(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) if (Sgl_iszero_mantissa(opnd2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) * Perform the add opnd3 with zero here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) if (Sgl_iszero_exponentmantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (Is_rounding_mode(ROUNDMINUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) Sgl_or_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) Sgl_and_signs(opnd3,resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) * Now let's check for trapped underflow case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) else if (Sgl_iszero_exponent(opnd3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) /* need to normalize results mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) sign_save = Sgl_signextendedsign(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) result_exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) Sgl_normalize(opnd3,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) Sgl_set_sign(opnd3,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) Sgl_setwrapped_exponent(opnd3,result_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) /* inexact = FALSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) Sgl_copytoptr(opnd3,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) /* is denormalized; want to normalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) Sgl_clear_signexponent(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) Sgl_leftshiftby1(opnd2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) Sgl_normalize(opnd2,mpy_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) /* Multiply the first two source mantissas together */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) * The intermediate result will be kept in tmpres,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) * which needs enough room for 106 bits of mantissa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) * so lets call it a Double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) Sglext_setzero(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * Four bits at a time are inspected in each loop, and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) * simple shift and add multiply algorithm is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) for (count = SGL_P-1; count >= 0; count -= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) Sglext_rightshiftby4(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (Sbit28(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) /* Twoword_add should be an ADD followed by 2 ADDC's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) Twoword_add(tmpresp1, tmpresp2, opnd2<<3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) if (Sbit29(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) Twoword_add(tmpresp1, tmpresp2, opnd2<<2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (Sbit30(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) Twoword_add(tmpresp1, tmpresp2, opnd2<<1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if (Sbit31(opnd1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) Twoword_add(tmpresp1, tmpresp2, opnd2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) Sgl_rightshiftby4(opnd1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) if (Is_sexthiddenoverflow(tmpresp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) /* result mantissa >= 2 (mantissa overflow) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) mpy_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) Sglext_rightshiftby4(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) Sglext_rightshiftby3(tmpresp1,tmpresp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) * Restore the sign of the mpy result which was saved in resultp1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) * The exponent will continue to be kept in mpy_exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) Sglext_set_sign(tmpresp1,Sgl_sign(resultp1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) * No rounding is required, since the result of the multiply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) * is exact in the extended format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) * Now we are ready to perform the add portion of the operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) * The exponents need to be kept as integers for now, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) * multiply result might not fit into the exponent field. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) * can't overflow or underflow because of this yet, since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) * add could bring the final result back into range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) add_exponent = Sgl_exponent(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) * Check for denormalized or zero add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (add_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) if (Sgl_iszero_mantissa(opnd3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) /* right is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) /* Left can't be zero and must be result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) * The final result is now in tmpres and mpy_exponent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) * and needs to be rounded and squeezed back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) * double precision format from double extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) Sglext_copy(tmpresp1,tmpresp2,resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) sign_save = Sgl_signextendedsign(resultp1);/*save sign*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * Neither are zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) * Adjust exponent and normalize add operand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) sign_save = Sgl_signextendedsign(opnd3); /* save sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) Sgl_clear_signexponent(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) Sgl_leftshiftby1(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) Sgl_normalize(opnd3,add_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) Sgl_set_sign(opnd3,sign_save); /* restore sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) Sgl_clear_exponent_set_hidden(opnd3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) * Copy opnd3 to the double extended variable called right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) Sgl_copyto_sglext(opnd3,rightp1,rightp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * A zero "save" helps discover equal operands (for later),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) * and is used in swapping operands (if needed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) Sglext_xortointp1(tmpresp1,rightp1,/*to*/save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) * Compare magnitude of operands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) Sglext_copytoint_exponentmantissa(tmpresp1,signlessleft1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) Sglext_copytoint_exponentmantissa(rightp1,signlessright1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) if (mpy_exponent < add_exponent || mpy_exponent == add_exponent &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) Sglext_ismagnitudeless(signlessleft1,signlessright1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) * Set the left operand to the larger one by XOR swap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) * First finish the first word "save".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) Sglext_xorfromintp1(save,rightp1,/*to*/rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) Sglext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) Sglext_swap_lower(tmpresp2,rightp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) diff_exponent = add_exponent - mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) result_exponent = add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) /* also setup exponents used in rest of routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) diff_exponent = mpy_exponent - add_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) result_exponent = mpy_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) /* Invariant: left is not smaller than right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) * Special case alignment of operands that would force alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) * beyond the extent of the extension. A further optimization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) * could special case this but only reduces the path length for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) * this infrequent case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) if (diff_exponent > SGLEXT_THRESHOLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) diff_exponent = SGLEXT_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) /* Align right operand by shifting it to the right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) Sglext_clear_sign(rightp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) Sglext_right_align(rightp1,rightp2,/*shifted by*/diff_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) /* Treat sum and difference of the operands separately. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if ((int)save < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) * Difference of the two operands. Overflow can occur if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) * multiply overflowed. A borrow can occur out of the hidden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) * bit and force a post normalization phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) Sglext_subtract(tmpresp1,tmpresp2, rightp1,rightp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) sign_save = Sgl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) if (Sgl_iszero_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) /* Handle normalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) /* A straightforward algorithm would now shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * result and extension left until the hidden bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * becomes one. Not all of the extension bits need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) * participate in the shift. Only the two most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * significant bits (round and guard) are needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) * If only a single shift is needed then the guard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) * bit becomes a significant low order bit and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) * extension must participate in the rounding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) * If more than a single shift is needed, then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) * bits to the right of the guard bit are zeros,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) * and the guard bit may or may not be zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) Sglext_leftshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) /* Need to check for a zero result. The sign and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) * exponent fields have already been zeroed. The more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) * efficient test of the full object can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) if (Sglext_iszero(resultp1,resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) /* Must have been "x-x" or "x+(-x)". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (Is_rounding_mode(ROUNDMINUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) Sgl_setone_sign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) result_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) /* Look to see if normalization is finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) if (Sgl_isone_hidden(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) /* No further normalization is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) goto round;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) /* Discover first one bit to determine shift amount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) * Use a modified binary search. We have already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) * shifted the result one position right and still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) * not found a one so the remainder of the extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) * must be zero and simplifies rounding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) /* Scan bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) while (Sgl_iszero_hiddenhigh7mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) Sglext_leftshiftby8(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) result_exponent -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) /* Now narrow it down to the nibble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (Sgl_iszero_hiddenhigh3mantissa(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) /* The lower nibble contains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) * normalizing one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) Sglext_leftshiftby4(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) result_exponent -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) /* Select case where first bit is set (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) * normalized) otherwise select the proper shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) jumpsize = Sgl_hiddenhigh3mantissa(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (jumpsize <= 7) switch(jumpsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) Sglext_leftshiftby3(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) result_exponent -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) Sglext_leftshiftby2(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) result_exponent -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) Sglext_leftshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) result_exponent -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) } /* end if (hidden...)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) /* Fall through and round */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) } /* end if (save < 0)... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) /* Add magnitudes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) Sglext_addition(tmpresp1,tmpresp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) rightp1,rightp2, /*to*/resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) sign_save = Sgl_signextendedsign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) if (Sgl_isone_hiddenoverflow(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) /* Prenormalization required. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) Sglext_arithrightshiftby1(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) } /* end if hiddenoverflow... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) } /* end else ...add magnitudes... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) /* Round the result. If the extension and lower two words are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) * all zeros, then the result is exact. Otherwise round in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) * correct direction. Underflow is possible. If a postnormalization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) * is necessary, then the mantissa is all zeros so no shift is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) round:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) if (result_exponent <= 0 && !Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) Sglext_denormalize(resultp1,resultp2,result_exponent,is_tiny);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) Sgl_set_sign(resultp1,/*using*/sign_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) if (Sglext_isnotzero_mantissap2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) switch(Rounding_mode()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) case ROUNDNEAREST: /* The default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) if (Sglext_isone_highp2(resultp2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) /* at least 1/2 ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) if (Sglext_isnotzero_low31p2(resultp2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) Sglext_isone_lowp1(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) /* either exactly half way and odd or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) * more than 1/2ulp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) if (Sgl_iszero_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) /* Round up positive results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) if (Sgl_isone_sign(resultp1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) /* Round down negative results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) Sgl_increment(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) case ROUNDZERO:;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) /* truncate is simple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) } /* end switch... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) if (Sgl_isone_hiddenoverflow(resultp1)) result_exponent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) if (result_exponent >= SGL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) /* Overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (Is_overflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) Sgl_setwrapped_exponent(resultp1,result_exponent,ovfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) return (OPC_2E_OVERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) return (OPC_2E_OVERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) inexact = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) Set_overflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) Sgl_setoverflow(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) } else if (result_exponent <= 0) { /* underflow case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) if (Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) Sgl_setwrapped_exponent(resultp1,result_exponent,unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (Is_inexacttrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) return (OPC_2E_UNDERFLOWEXCEPTION |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) return(OPC_2E_UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) else if (inexact && is_tiny) Set_underflowflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) else Sgl_set_exponent(resultp1,result_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) Sgl_copytoptr(resultp1,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) if (inexact)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) else Set_inexactflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)