1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * Linux/PA-RISC Project (http://www.parisc-linux.org/) 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Floating-point emulation code 5*1da177e4SLinus Torvalds * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 6*1da177e4SLinus Torvalds * 7*1da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 8*1da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 9*1da177e4SLinus Torvalds * the Free Software Foundation; either version 2, or (at your option) 10*1da177e4SLinus Torvalds * any later version. 11*1da177e4SLinus Torvalds * 12*1da177e4SLinus Torvalds * This program is distributed in the hope that it will be useful, 13*1da177e4SLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*1da177e4SLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*1da177e4SLinus Torvalds * GNU General Public License for more details. 16*1da177e4SLinus Torvalds * 17*1da177e4SLinus Torvalds * You should have received a copy of the GNU General Public License 18*1da177e4SLinus Torvalds * along with this program; if not, write to the Free Software 19*1da177e4SLinus Torvalds * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20*1da177e4SLinus Torvalds */ 21*1da177e4SLinus Torvalds /* 22*1da177e4SLinus Torvalds * BEGIN_DESC 23*1da177e4SLinus Torvalds * 24*1da177e4SLinus Torvalds * File: 25*1da177e4SLinus Torvalds * @(#) pa/spmath/sfdiv.c $Revision: 1.1 $ 26*1da177e4SLinus Torvalds * 27*1da177e4SLinus Torvalds * Purpose: 28*1da177e4SLinus Torvalds * Single Precision Floating-point Divide 29*1da177e4SLinus Torvalds * 30*1da177e4SLinus Torvalds * External Interfaces: 31*1da177e4SLinus Torvalds * sgl_fdiv(srcptr1,srcptr2,dstptr,status) 32*1da177e4SLinus Torvalds * 33*1da177e4SLinus Torvalds * Internal Interfaces: 34*1da177e4SLinus Torvalds * 35*1da177e4SLinus Torvalds * Theory: 36*1da177e4SLinus Torvalds * <<please update with a overview of the operation of this file>> 37*1da177e4SLinus Torvalds * 38*1da177e4SLinus Torvalds * END_DESC 39*1da177e4SLinus Torvalds */ 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds 42*1da177e4SLinus Torvalds #include "float.h" 43*1da177e4SLinus Torvalds #include "sgl_float.h" 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds /* 46*1da177e4SLinus Torvalds * Single Precision Floating-point Divide 47*1da177e4SLinus Torvalds */ 48*1da177e4SLinus Torvalds 49*1da177e4SLinus Torvalds int 50*1da177e4SLinus Torvalds sgl_fdiv (sgl_floating_point * srcptr1, sgl_floating_point * srcptr2, 51*1da177e4SLinus Torvalds sgl_floating_point * dstptr, unsigned int *status) 52*1da177e4SLinus Torvalds { 53*1da177e4SLinus Torvalds register unsigned int opnd1, opnd2, opnd3, result; 54*1da177e4SLinus Torvalds register int dest_exponent, count; 55*1da177e4SLinus Torvalds register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE; 56*1da177e4SLinus Torvalds boolean is_tiny; 57*1da177e4SLinus Torvalds 58*1da177e4SLinus Torvalds opnd1 = *srcptr1; 59*1da177e4SLinus Torvalds opnd2 = *srcptr2; 60*1da177e4SLinus Torvalds /* 61*1da177e4SLinus Torvalds * set sign bit of result 62*1da177e4SLinus Torvalds */ 63*1da177e4SLinus Torvalds if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) Sgl_setnegativezero(result); 64*1da177e4SLinus Torvalds else Sgl_setzero(result); 65*1da177e4SLinus Torvalds /* 66*1da177e4SLinus Torvalds * check first operand for NaN's or infinity 67*1da177e4SLinus Torvalds */ 68*1da177e4SLinus Torvalds if (Sgl_isinfinity_exponent(opnd1)) { 69*1da177e4SLinus Torvalds if (Sgl_iszero_mantissa(opnd1)) { 70*1da177e4SLinus Torvalds if (Sgl_isnotnan(opnd2)) { 71*1da177e4SLinus Torvalds if (Sgl_isinfinity(opnd2)) { 72*1da177e4SLinus Torvalds /* 73*1da177e4SLinus Torvalds * invalid since both operands 74*1da177e4SLinus Torvalds * are infinity 75*1da177e4SLinus Torvalds */ 76*1da177e4SLinus Torvalds if (Is_invalidtrap_enabled()) 77*1da177e4SLinus Torvalds return(INVALIDEXCEPTION); 78*1da177e4SLinus Torvalds Set_invalidflag(); 79*1da177e4SLinus Torvalds Sgl_makequietnan(result); 80*1da177e4SLinus Torvalds *dstptr = result; 81*1da177e4SLinus Torvalds return(NOEXCEPTION); 82*1da177e4SLinus Torvalds } 83*1da177e4SLinus Torvalds /* 84*1da177e4SLinus Torvalds * return infinity 85*1da177e4SLinus Torvalds */ 86*1da177e4SLinus Torvalds Sgl_setinfinity_exponentmantissa(result); 87*1da177e4SLinus Torvalds *dstptr = result; 88*1da177e4SLinus Torvalds return(NOEXCEPTION); 89*1da177e4SLinus Torvalds } 90*1da177e4SLinus Torvalds } 91*1da177e4SLinus Torvalds else { 92*1da177e4SLinus Torvalds /* 93*1da177e4SLinus Torvalds * is NaN; signaling or quiet? 94*1da177e4SLinus Torvalds */ 95*1da177e4SLinus Torvalds if (Sgl_isone_signaling(opnd1)) { 96*1da177e4SLinus Torvalds /* trap if INVALIDTRAP enabled */ 97*1da177e4SLinus Torvalds if (Is_invalidtrap_enabled()) 98*1da177e4SLinus Torvalds return(INVALIDEXCEPTION); 99*1da177e4SLinus Torvalds /* make NaN quiet */ 100*1da177e4SLinus Torvalds Set_invalidflag(); 101*1da177e4SLinus Torvalds Sgl_set_quiet(opnd1); 102*1da177e4SLinus Torvalds } 103*1da177e4SLinus Torvalds /* 104*1da177e4SLinus Torvalds * is second operand a signaling NaN? 105*1da177e4SLinus Torvalds */ 106*1da177e4SLinus Torvalds else if (Sgl_is_signalingnan(opnd2)) { 107*1da177e4SLinus Torvalds /* trap if INVALIDTRAP enabled */ 108*1da177e4SLinus Torvalds if (Is_invalidtrap_enabled()) 109*1da177e4SLinus Torvalds return(INVALIDEXCEPTION); 110*1da177e4SLinus Torvalds /* make NaN quiet */ 111*1da177e4SLinus Torvalds Set_invalidflag(); 112*1da177e4SLinus Torvalds Sgl_set_quiet(opnd2); 113*1da177e4SLinus Torvalds *dstptr = opnd2; 114*1da177e4SLinus Torvalds return(NOEXCEPTION); 115*1da177e4SLinus Torvalds } 116*1da177e4SLinus Torvalds /* 117*1da177e4SLinus Torvalds * return quiet NaN 118*1da177e4SLinus Torvalds */ 119*1da177e4SLinus Torvalds *dstptr = opnd1; 120*1da177e4SLinus Torvalds return(NOEXCEPTION); 121*1da177e4SLinus Torvalds } 122*1da177e4SLinus Torvalds } 123*1da177e4SLinus Torvalds /* 124*1da177e4SLinus Torvalds * check second operand for NaN's or infinity 125*1da177e4SLinus Torvalds */ 126*1da177e4SLinus Torvalds if (Sgl_isinfinity_exponent(opnd2)) { 127*1da177e4SLinus Torvalds if (Sgl_iszero_mantissa(opnd2)) { 128*1da177e4SLinus Torvalds /* 129*1da177e4SLinus Torvalds * return zero 130*1da177e4SLinus Torvalds */ 131*1da177e4SLinus Torvalds Sgl_setzero_exponentmantissa(result); 132*1da177e4SLinus Torvalds *dstptr = result; 133*1da177e4SLinus Torvalds return(NOEXCEPTION); 134*1da177e4SLinus Torvalds } 135*1da177e4SLinus Torvalds /* 136*1da177e4SLinus Torvalds * is NaN; signaling or quiet? 137*1da177e4SLinus Torvalds */ 138*1da177e4SLinus Torvalds if (Sgl_isone_signaling(opnd2)) { 139*1da177e4SLinus Torvalds /* trap if INVALIDTRAP enabled */ 140*1da177e4SLinus Torvalds if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 141*1da177e4SLinus Torvalds /* make NaN quiet */ 142*1da177e4SLinus Torvalds Set_invalidflag(); 143*1da177e4SLinus Torvalds Sgl_set_quiet(opnd2); 144*1da177e4SLinus Torvalds } 145*1da177e4SLinus Torvalds /* 146*1da177e4SLinus Torvalds * return quiet NaN 147*1da177e4SLinus Torvalds */ 148*1da177e4SLinus Torvalds *dstptr = opnd2; 149*1da177e4SLinus Torvalds return(NOEXCEPTION); 150*1da177e4SLinus Torvalds } 151*1da177e4SLinus Torvalds /* 152*1da177e4SLinus Torvalds * check for division by zero 153*1da177e4SLinus Torvalds */ 154*1da177e4SLinus Torvalds if (Sgl_iszero_exponentmantissa(opnd2)) { 155*1da177e4SLinus Torvalds if (Sgl_iszero_exponentmantissa(opnd1)) { 156*1da177e4SLinus Torvalds /* invalid since both operands are zero */ 157*1da177e4SLinus Torvalds if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 158*1da177e4SLinus Torvalds Set_invalidflag(); 159*1da177e4SLinus Torvalds Sgl_makequietnan(result); 160*1da177e4SLinus Torvalds *dstptr = result; 161*1da177e4SLinus Torvalds return(NOEXCEPTION); 162*1da177e4SLinus Torvalds } 163*1da177e4SLinus Torvalds if (Is_divisionbyzerotrap_enabled()) 164*1da177e4SLinus Torvalds return(DIVISIONBYZEROEXCEPTION); 165*1da177e4SLinus Torvalds Set_divisionbyzeroflag(); 166*1da177e4SLinus Torvalds Sgl_setinfinity_exponentmantissa(result); 167*1da177e4SLinus Torvalds *dstptr = result; 168*1da177e4SLinus Torvalds return(NOEXCEPTION); 169*1da177e4SLinus Torvalds } 170*1da177e4SLinus Torvalds /* 171*1da177e4SLinus Torvalds * Generate exponent 172*1da177e4SLinus Torvalds */ 173*1da177e4SLinus Torvalds dest_exponent = Sgl_exponent(opnd1) - Sgl_exponent(opnd2) + SGL_BIAS; 174*1da177e4SLinus Torvalds 175*1da177e4SLinus Torvalds /* 176*1da177e4SLinus Torvalds * Generate mantissa 177*1da177e4SLinus Torvalds */ 178*1da177e4SLinus Torvalds if (Sgl_isnotzero_exponent(opnd1)) { 179*1da177e4SLinus Torvalds /* set hidden bit */ 180*1da177e4SLinus Torvalds Sgl_clear_signexponent_set_hidden(opnd1); 181*1da177e4SLinus Torvalds } 182*1da177e4SLinus Torvalds else { 183*1da177e4SLinus Torvalds /* check for zero */ 184*1da177e4SLinus Torvalds if (Sgl_iszero_mantissa(opnd1)) { 185*1da177e4SLinus Torvalds Sgl_setzero_exponentmantissa(result); 186*1da177e4SLinus Torvalds *dstptr = result; 187*1da177e4SLinus Torvalds return(NOEXCEPTION); 188*1da177e4SLinus Torvalds } 189*1da177e4SLinus Torvalds /* is denormalized; want to normalize */ 190*1da177e4SLinus Torvalds Sgl_clear_signexponent(opnd1); 191*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd1); 192*1da177e4SLinus Torvalds Sgl_normalize(opnd1,dest_exponent); 193*1da177e4SLinus Torvalds } 194*1da177e4SLinus Torvalds /* opnd2 needs to have hidden bit set with msb in hidden bit */ 195*1da177e4SLinus Torvalds if (Sgl_isnotzero_exponent(opnd2)) { 196*1da177e4SLinus Torvalds Sgl_clear_signexponent_set_hidden(opnd2); 197*1da177e4SLinus Torvalds } 198*1da177e4SLinus Torvalds else { 199*1da177e4SLinus Torvalds /* is denormalized; want to normalize */ 200*1da177e4SLinus Torvalds Sgl_clear_signexponent(opnd2); 201*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd2); 202*1da177e4SLinus Torvalds while(Sgl_iszero_hiddenhigh7mantissa(opnd2)) { 203*1da177e4SLinus Torvalds Sgl_leftshiftby8(opnd2); 204*1da177e4SLinus Torvalds dest_exponent += 8; 205*1da177e4SLinus Torvalds } 206*1da177e4SLinus Torvalds if(Sgl_iszero_hiddenhigh3mantissa(opnd2)) { 207*1da177e4SLinus Torvalds Sgl_leftshiftby4(opnd2); 208*1da177e4SLinus Torvalds dest_exponent += 4; 209*1da177e4SLinus Torvalds } 210*1da177e4SLinus Torvalds while(Sgl_iszero_hidden(opnd2)) { 211*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd2); 212*1da177e4SLinus Torvalds dest_exponent += 1; 213*1da177e4SLinus Torvalds } 214*1da177e4SLinus Torvalds } 215*1da177e4SLinus Torvalds 216*1da177e4SLinus Torvalds /* Divide the source mantissas */ 217*1da177e4SLinus Torvalds 218*1da177e4SLinus Torvalds /* 219*1da177e4SLinus Torvalds * A non_restoring divide algorithm is used. 220*1da177e4SLinus Torvalds */ 221*1da177e4SLinus Torvalds Sgl_subtract(opnd1,opnd2,opnd1); 222*1da177e4SLinus Torvalds Sgl_setzero(opnd3); 223*1da177e4SLinus Torvalds for (count=1;count<=SGL_P && Sgl_all(opnd1);count++) { 224*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd1); 225*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd3); 226*1da177e4SLinus Torvalds if (Sgl_iszero_sign(opnd1)) { 227*1da177e4SLinus Torvalds Sgl_setone_lowmantissa(opnd3); 228*1da177e4SLinus Torvalds Sgl_subtract(opnd1,opnd2,opnd1); 229*1da177e4SLinus Torvalds } 230*1da177e4SLinus Torvalds else Sgl_addition(opnd1,opnd2,opnd1); 231*1da177e4SLinus Torvalds } 232*1da177e4SLinus Torvalds if (count <= SGL_P) { 233*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd3); 234*1da177e4SLinus Torvalds Sgl_setone_lowmantissa(opnd3); 235*1da177e4SLinus Torvalds Sgl_leftshift(opnd3,SGL_P-count); 236*1da177e4SLinus Torvalds if (Sgl_iszero_hidden(opnd3)) { 237*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd3); 238*1da177e4SLinus Torvalds dest_exponent--; 239*1da177e4SLinus Torvalds } 240*1da177e4SLinus Torvalds } 241*1da177e4SLinus Torvalds else { 242*1da177e4SLinus Torvalds if (Sgl_iszero_hidden(opnd3)) { 243*1da177e4SLinus Torvalds /* need to get one more bit of result */ 244*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd1); 245*1da177e4SLinus Torvalds Sgl_leftshiftby1(opnd3); 246*1da177e4SLinus Torvalds if (Sgl_iszero_sign(opnd1)) { 247*1da177e4SLinus Torvalds Sgl_setone_lowmantissa(opnd3); 248*1da177e4SLinus Torvalds Sgl_subtract(opnd1,opnd2,opnd1); 249*1da177e4SLinus Torvalds } 250*1da177e4SLinus Torvalds else Sgl_addition(opnd1,opnd2,opnd1); 251*1da177e4SLinus Torvalds dest_exponent--; 252*1da177e4SLinus Torvalds } 253*1da177e4SLinus Torvalds if (Sgl_iszero_sign(opnd1)) guardbit = TRUE; 254*1da177e4SLinus Torvalds stickybit = Sgl_all(opnd1); 255*1da177e4SLinus Torvalds } 256*1da177e4SLinus Torvalds inexact = guardbit | stickybit; 257*1da177e4SLinus Torvalds 258*1da177e4SLinus Torvalds /* 259*1da177e4SLinus Torvalds * round result 260*1da177e4SLinus Torvalds */ 261*1da177e4SLinus Torvalds if (inexact && (dest_exponent > 0 || Is_underflowtrap_enabled())) { 262*1da177e4SLinus Torvalds Sgl_clear_signexponent(opnd3); 263*1da177e4SLinus Torvalds switch (Rounding_mode()) { 264*1da177e4SLinus Torvalds case ROUNDPLUS: 265*1da177e4SLinus Torvalds if (Sgl_iszero_sign(result)) 266*1da177e4SLinus Torvalds Sgl_increment_mantissa(opnd3); 267*1da177e4SLinus Torvalds break; 268*1da177e4SLinus Torvalds case ROUNDMINUS: 269*1da177e4SLinus Torvalds if (Sgl_isone_sign(result)) 270*1da177e4SLinus Torvalds Sgl_increment_mantissa(opnd3); 271*1da177e4SLinus Torvalds break; 272*1da177e4SLinus Torvalds case ROUNDNEAREST: 273*1da177e4SLinus Torvalds if (guardbit) { 274*1da177e4SLinus Torvalds if (stickybit || Sgl_isone_lowmantissa(opnd3)) 275*1da177e4SLinus Torvalds Sgl_increment_mantissa(opnd3); 276*1da177e4SLinus Torvalds } 277*1da177e4SLinus Torvalds } 278*1da177e4SLinus Torvalds if (Sgl_isone_hidden(opnd3)) dest_exponent++; 279*1da177e4SLinus Torvalds } 280*1da177e4SLinus Torvalds Sgl_set_mantissa(result,opnd3); 281*1da177e4SLinus Torvalds 282*1da177e4SLinus Torvalds /* 283*1da177e4SLinus Torvalds * Test for overflow 284*1da177e4SLinus Torvalds */ 285*1da177e4SLinus Torvalds if (dest_exponent >= SGL_INFINITY_EXPONENT) { 286*1da177e4SLinus Torvalds /* trap if OVERFLOWTRAP enabled */ 287*1da177e4SLinus Torvalds if (Is_overflowtrap_enabled()) { 288*1da177e4SLinus Torvalds /* 289*1da177e4SLinus Torvalds * Adjust bias of result 290*1da177e4SLinus Torvalds */ 291*1da177e4SLinus Torvalds Sgl_setwrapped_exponent(result,dest_exponent,ovfl); 292*1da177e4SLinus Torvalds *dstptr = result; 293*1da177e4SLinus Torvalds if (inexact) 294*1da177e4SLinus Torvalds if (Is_inexacttrap_enabled()) 295*1da177e4SLinus Torvalds return(OVERFLOWEXCEPTION | INEXACTEXCEPTION); 296*1da177e4SLinus Torvalds else Set_inexactflag(); 297*1da177e4SLinus Torvalds return(OVERFLOWEXCEPTION); 298*1da177e4SLinus Torvalds } 299*1da177e4SLinus Torvalds Set_overflowflag(); 300*1da177e4SLinus Torvalds /* set result to infinity or largest number */ 301*1da177e4SLinus Torvalds Sgl_setoverflow(result); 302*1da177e4SLinus Torvalds inexact = TRUE; 303*1da177e4SLinus Torvalds } 304*1da177e4SLinus Torvalds /* 305*1da177e4SLinus Torvalds * Test for underflow 306*1da177e4SLinus Torvalds */ 307*1da177e4SLinus Torvalds else if (dest_exponent <= 0) { 308*1da177e4SLinus Torvalds /* trap if UNDERFLOWTRAP enabled */ 309*1da177e4SLinus Torvalds if (Is_underflowtrap_enabled()) { 310*1da177e4SLinus Torvalds /* 311*1da177e4SLinus Torvalds * Adjust bias of result 312*1da177e4SLinus Torvalds */ 313*1da177e4SLinus Torvalds Sgl_setwrapped_exponent(result,dest_exponent,unfl); 314*1da177e4SLinus Torvalds *dstptr = result; 315*1da177e4SLinus Torvalds if (inexact) 316*1da177e4SLinus Torvalds if (Is_inexacttrap_enabled()) 317*1da177e4SLinus Torvalds return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION); 318*1da177e4SLinus Torvalds else Set_inexactflag(); 319*1da177e4SLinus Torvalds return(UNDERFLOWEXCEPTION); 320*1da177e4SLinus Torvalds } 321*1da177e4SLinus Torvalds 322*1da177e4SLinus Torvalds /* Determine if should set underflow flag */ 323*1da177e4SLinus Torvalds is_tiny = TRUE; 324*1da177e4SLinus Torvalds if (dest_exponent == 0 && inexact) { 325*1da177e4SLinus Torvalds switch (Rounding_mode()) { 326*1da177e4SLinus Torvalds case ROUNDPLUS: 327*1da177e4SLinus Torvalds if (Sgl_iszero_sign(result)) { 328*1da177e4SLinus Torvalds Sgl_increment(opnd3); 329*1da177e4SLinus Torvalds if (Sgl_isone_hiddenoverflow(opnd3)) 330*1da177e4SLinus Torvalds is_tiny = FALSE; 331*1da177e4SLinus Torvalds Sgl_decrement(opnd3); 332*1da177e4SLinus Torvalds } 333*1da177e4SLinus Torvalds break; 334*1da177e4SLinus Torvalds case ROUNDMINUS: 335*1da177e4SLinus Torvalds if (Sgl_isone_sign(result)) { 336*1da177e4SLinus Torvalds Sgl_increment(opnd3); 337*1da177e4SLinus Torvalds if (Sgl_isone_hiddenoverflow(opnd3)) 338*1da177e4SLinus Torvalds is_tiny = FALSE; 339*1da177e4SLinus Torvalds Sgl_decrement(opnd3); 340*1da177e4SLinus Torvalds } 341*1da177e4SLinus Torvalds break; 342*1da177e4SLinus Torvalds case ROUNDNEAREST: 343*1da177e4SLinus Torvalds if (guardbit && (stickybit || 344*1da177e4SLinus Torvalds Sgl_isone_lowmantissa(opnd3))) { 345*1da177e4SLinus Torvalds Sgl_increment(opnd3); 346*1da177e4SLinus Torvalds if (Sgl_isone_hiddenoverflow(opnd3)) 347*1da177e4SLinus Torvalds is_tiny = FALSE; 348*1da177e4SLinus Torvalds Sgl_decrement(opnd3); 349*1da177e4SLinus Torvalds } 350*1da177e4SLinus Torvalds break; 351*1da177e4SLinus Torvalds } 352*1da177e4SLinus Torvalds } 353*1da177e4SLinus Torvalds 354*1da177e4SLinus Torvalds /* 355*1da177e4SLinus Torvalds * denormalize result or set to signed zero 356*1da177e4SLinus Torvalds */ 357*1da177e4SLinus Torvalds stickybit = inexact; 358*1da177e4SLinus Torvalds Sgl_denormalize(opnd3,dest_exponent,guardbit,stickybit,inexact); 359*1da177e4SLinus Torvalds 360*1da177e4SLinus Torvalds /* return rounded number */ 361*1da177e4SLinus Torvalds if (inexact) { 362*1da177e4SLinus Torvalds switch (Rounding_mode()) { 363*1da177e4SLinus Torvalds case ROUNDPLUS: 364*1da177e4SLinus Torvalds if (Sgl_iszero_sign(result)) { 365*1da177e4SLinus Torvalds Sgl_increment(opnd3); 366*1da177e4SLinus Torvalds } 367*1da177e4SLinus Torvalds break; 368*1da177e4SLinus Torvalds case ROUNDMINUS: 369*1da177e4SLinus Torvalds if (Sgl_isone_sign(result)) { 370*1da177e4SLinus Torvalds Sgl_increment(opnd3); 371*1da177e4SLinus Torvalds } 372*1da177e4SLinus Torvalds break; 373*1da177e4SLinus Torvalds case ROUNDNEAREST: 374*1da177e4SLinus Torvalds if (guardbit && (stickybit || 375*1da177e4SLinus Torvalds Sgl_isone_lowmantissa(opnd3))) { 376*1da177e4SLinus Torvalds Sgl_increment(opnd3); 377*1da177e4SLinus Torvalds } 378*1da177e4SLinus Torvalds break; 379*1da177e4SLinus Torvalds } 380*1da177e4SLinus Torvalds if (is_tiny) Set_underflowflag(); 381*1da177e4SLinus Torvalds } 382*1da177e4SLinus Torvalds Sgl_set_exponentmantissa(result,opnd3); 383*1da177e4SLinus Torvalds } 384*1da177e4SLinus Torvalds else Sgl_set_exponent(result,dest_exponent); 385*1da177e4SLinus Torvalds *dstptr = result; 386*1da177e4SLinus Torvalds /* check for inexact */ 387*1da177e4SLinus Torvalds if (inexact) { 388*1da177e4SLinus Torvalds if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 389*1da177e4SLinus Torvalds else Set_inexactflag(); 390*1da177e4SLinus Torvalds } 391*1da177e4SLinus Torvalds return(NOEXCEPTION); 392*1da177e4SLinus Torvalds } 393