18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Linux/PA-RISC Project (http://www.parisc-linux.org/) 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Floating-point emulation code 68c2ecf20Sopenharmony_ci * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci/* 98c2ecf20Sopenharmony_ci * BEGIN_DESC 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * File: 128c2ecf20Sopenharmony_ci * @(#) pa/spmath/dfdiv.c $Revision: 1.1 $ 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Purpose: 158c2ecf20Sopenharmony_ci * Double Precision Floating-point Divide 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * External Interfaces: 188c2ecf20Sopenharmony_ci * dbl_fdiv(srcptr1,srcptr2,dstptr,status) 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Internal Interfaces: 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Theory: 238c2ecf20Sopenharmony_ci * <<please update with a overview of the operation of this file>> 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * END_DESC 268c2ecf20Sopenharmony_ci*/ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include "float.h" 308c2ecf20Sopenharmony_ci#include "dbl_float.h" 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * Double Precision Floating-point Divide 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ciint 378c2ecf20Sopenharmony_cidbl_fdiv (dbl_floating_point * srcptr1, dbl_floating_point * srcptr2, 388c2ecf20Sopenharmony_ci dbl_floating_point * dstptr, unsigned int *status) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2; 418c2ecf20Sopenharmony_ci register unsigned int opnd3p1, opnd3p2, resultp1, resultp2; 428c2ecf20Sopenharmony_ci register int dest_exponent, count; 438c2ecf20Sopenharmony_ci register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE; 448c2ecf20Sopenharmony_ci boolean is_tiny; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2); 478c2ecf20Sopenharmony_ci Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2); 488c2ecf20Sopenharmony_ci /* 498c2ecf20Sopenharmony_ci * set sign bit of result 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1)) 528c2ecf20Sopenharmony_ci Dbl_setnegativezerop1(resultp1); 538c2ecf20Sopenharmony_ci else Dbl_setzerop1(resultp1); 548c2ecf20Sopenharmony_ci /* 558c2ecf20Sopenharmony_ci * check first operand for NaN's or infinity 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_ci if (Dbl_isinfinity_exponent(opnd1p1)) { 588c2ecf20Sopenharmony_ci if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 598c2ecf20Sopenharmony_ci if (Dbl_isnotnan(opnd2p1,opnd2p2)) { 608c2ecf20Sopenharmony_ci if (Dbl_isinfinity(opnd2p1,opnd2p2)) { 618c2ecf20Sopenharmony_ci /* 628c2ecf20Sopenharmony_ci * invalid since both operands 638c2ecf20Sopenharmony_ci * are infinity 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) 668c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 678c2ecf20Sopenharmony_ci Set_invalidflag(); 688c2ecf20Sopenharmony_ci Dbl_makequietnan(resultp1,resultp2); 698c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 708c2ecf20Sopenharmony_ci return(NOEXCEPTION); 718c2ecf20Sopenharmony_ci } 728c2ecf20Sopenharmony_ci /* 738c2ecf20Sopenharmony_ci * return infinity 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 768c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 778c2ecf20Sopenharmony_ci return(NOEXCEPTION); 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci else { 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * is NaN; signaling or quiet? 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci if (Dbl_isone_signaling(opnd1p1)) { 858c2ecf20Sopenharmony_ci /* trap if INVALIDTRAP enabled */ 868c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) 878c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 888c2ecf20Sopenharmony_ci /* make NaN quiet */ 898c2ecf20Sopenharmony_ci Set_invalidflag(); 908c2ecf20Sopenharmony_ci Dbl_set_quiet(opnd1p1); 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci /* 938c2ecf20Sopenharmony_ci * is second operand a signaling NaN? 948c2ecf20Sopenharmony_ci */ 958c2ecf20Sopenharmony_ci else if (Dbl_is_signalingnan(opnd2p1)) { 968c2ecf20Sopenharmony_ci /* trap if INVALIDTRAP enabled */ 978c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) 988c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 998c2ecf20Sopenharmony_ci /* make NaN quiet */ 1008c2ecf20Sopenharmony_ci Set_invalidflag(); 1018c2ecf20Sopenharmony_ci Dbl_set_quiet(opnd2p1); 1028c2ecf20Sopenharmony_ci Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 1038c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1048c2ecf20Sopenharmony_ci } 1058c2ecf20Sopenharmony_ci /* 1068c2ecf20Sopenharmony_ci * return quiet NaN 1078c2ecf20Sopenharmony_ci */ 1088c2ecf20Sopenharmony_ci Dbl_copytoptr(opnd1p1,opnd1p2,dstptr); 1098c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci } 1128c2ecf20Sopenharmony_ci /* 1138c2ecf20Sopenharmony_ci * check second operand for NaN's or infinity 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci if (Dbl_isinfinity_exponent(opnd2p1)) { 1168c2ecf20Sopenharmony_ci if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) { 1178c2ecf20Sopenharmony_ci /* 1188c2ecf20Sopenharmony_ci * return zero 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci Dbl_setzero_exponentmantissa(resultp1,resultp2); 1218c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 1228c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci /* 1258c2ecf20Sopenharmony_ci * is NaN; signaling or quiet? 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_ci if (Dbl_isone_signaling(opnd2p1)) { 1288c2ecf20Sopenharmony_ci /* trap if INVALIDTRAP enabled */ 1298c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 1308c2ecf20Sopenharmony_ci /* make NaN quiet */ 1318c2ecf20Sopenharmony_ci Set_invalidflag(); 1328c2ecf20Sopenharmony_ci Dbl_set_quiet(opnd2p1); 1338c2ecf20Sopenharmony_ci } 1348c2ecf20Sopenharmony_ci /* 1358c2ecf20Sopenharmony_ci * return quiet NaN 1368c2ecf20Sopenharmony_ci */ 1378c2ecf20Sopenharmony_ci Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 1388c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci /* 1418c2ecf20Sopenharmony_ci * check for division by zero 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_ci if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) { 1448c2ecf20Sopenharmony_ci if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) { 1458c2ecf20Sopenharmony_ci /* invalid since both operands are zero */ 1468c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 1478c2ecf20Sopenharmony_ci Set_invalidflag(); 1488c2ecf20Sopenharmony_ci Dbl_makequietnan(resultp1,resultp2); 1498c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 1508c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1518c2ecf20Sopenharmony_ci } 1528c2ecf20Sopenharmony_ci if (Is_divisionbyzerotrap_enabled()) 1538c2ecf20Sopenharmony_ci return(DIVISIONBYZEROEXCEPTION); 1548c2ecf20Sopenharmony_ci Set_divisionbyzeroflag(); 1558c2ecf20Sopenharmony_ci Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 1568c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 1578c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci /* 1608c2ecf20Sopenharmony_ci * Generate exponent 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci dest_exponent = Dbl_exponent(opnd1p1) - Dbl_exponent(opnd2p1) + DBL_BIAS; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* 1658c2ecf20Sopenharmony_ci * Generate mantissa 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_ci if (Dbl_isnotzero_exponent(opnd1p1)) { 1688c2ecf20Sopenharmony_ci /* set hidden bit */ 1698c2ecf20Sopenharmony_ci Dbl_clear_signexponent_set_hidden(opnd1p1); 1708c2ecf20Sopenharmony_ci } 1718c2ecf20Sopenharmony_ci else { 1728c2ecf20Sopenharmony_ci /* check for zero */ 1738c2ecf20Sopenharmony_ci if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 1748c2ecf20Sopenharmony_ci Dbl_setzero_exponentmantissa(resultp1,resultp2); 1758c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 1768c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci /* is denormalized, want to normalize */ 1798c2ecf20Sopenharmony_ci Dbl_clear_signexponent(opnd1p1); 1808c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd1p1,opnd1p2); 1818c2ecf20Sopenharmony_ci Dbl_normalize(opnd1p1,opnd1p2,dest_exponent); 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci /* opnd2 needs to have hidden bit set with msb in hidden bit */ 1848c2ecf20Sopenharmony_ci if (Dbl_isnotzero_exponent(opnd2p1)) { 1858c2ecf20Sopenharmony_ci Dbl_clear_signexponent_set_hidden(opnd2p1); 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci else { 1888c2ecf20Sopenharmony_ci /* is denormalized; want to normalize */ 1898c2ecf20Sopenharmony_ci Dbl_clear_signexponent(opnd2p1); 1908c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd2p1,opnd2p2); 1918c2ecf20Sopenharmony_ci while (Dbl_iszero_hiddenhigh7mantissa(opnd2p1)) { 1928c2ecf20Sopenharmony_ci dest_exponent+=8; 1938c2ecf20Sopenharmony_ci Dbl_leftshiftby8(opnd2p1,opnd2p2); 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci if (Dbl_iszero_hiddenhigh3mantissa(opnd2p1)) { 1968c2ecf20Sopenharmony_ci dest_exponent+=4; 1978c2ecf20Sopenharmony_ci Dbl_leftshiftby4(opnd2p1,opnd2p2); 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci while (Dbl_iszero_hidden(opnd2p1)) { 2008c2ecf20Sopenharmony_ci dest_exponent++; 2018c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd2p1,opnd2p2); 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci /* Divide the source mantissas */ 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* 2088c2ecf20Sopenharmony_ci * A non-restoring divide algorithm is used. 2098c2ecf20Sopenharmony_ci */ 2108c2ecf20Sopenharmony_ci Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2); 2118c2ecf20Sopenharmony_ci Dbl_setzero(opnd3p1,opnd3p2); 2128c2ecf20Sopenharmony_ci for (count=1; count <= DBL_P && (opnd1p1 || opnd1p2); count++) { 2138c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd1p1,opnd1p2); 2148c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd3p1,opnd3p2); 2158c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(opnd1p1)) { 2168c2ecf20Sopenharmony_ci Dbl_setone_lowmantissap2(opnd3p2); 2178c2ecf20Sopenharmony_ci Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2); 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci else { 2208c2ecf20Sopenharmony_ci Twoword_add(opnd1p1, opnd1p2, opnd2p1, opnd2p2); 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci if (count <= DBL_P) { 2248c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd3p1,opnd3p2); 2258c2ecf20Sopenharmony_ci Dbl_setone_lowmantissap2(opnd3p2); 2268c2ecf20Sopenharmony_ci Dbl_leftshift(opnd3p1,opnd3p2,(DBL_P-count)); 2278c2ecf20Sopenharmony_ci if (Dbl_iszero_hidden(opnd3p1)) { 2288c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd3p1,opnd3p2); 2298c2ecf20Sopenharmony_ci dest_exponent--; 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci else { 2338c2ecf20Sopenharmony_ci if (Dbl_iszero_hidden(opnd3p1)) { 2348c2ecf20Sopenharmony_ci /* need to get one more bit of result */ 2358c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd1p1,opnd1p2); 2368c2ecf20Sopenharmony_ci Dbl_leftshiftby1(opnd3p1,opnd3p2); 2378c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(opnd1p1)) { 2388c2ecf20Sopenharmony_ci Dbl_setone_lowmantissap2(opnd3p2); 2398c2ecf20Sopenharmony_ci Twoword_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2); 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci else { 2428c2ecf20Sopenharmony_ci Twoword_add(opnd1p1,opnd1p2,opnd2p1,opnd2p2); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci dest_exponent--; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(opnd1p1)) guardbit = TRUE; 2478c2ecf20Sopenharmony_ci stickybit = Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2); 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci inexact = guardbit | stickybit; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* 2528c2ecf20Sopenharmony_ci * round result 2538c2ecf20Sopenharmony_ci */ 2548c2ecf20Sopenharmony_ci if (inexact && (dest_exponent > 0 || Is_underflowtrap_enabled())) { 2558c2ecf20Sopenharmony_ci Dbl_clear_signexponent(opnd3p1); 2568c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 2578c2ecf20Sopenharmony_ci case ROUNDPLUS: 2588c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(resultp1)) 2598c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 2608c2ecf20Sopenharmony_ci break; 2618c2ecf20Sopenharmony_ci case ROUNDMINUS: 2628c2ecf20Sopenharmony_ci if (Dbl_isone_sign(resultp1)) 2638c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 2648c2ecf20Sopenharmony_ci break; 2658c2ecf20Sopenharmony_ci case ROUNDNEAREST: 2668c2ecf20Sopenharmony_ci if (guardbit && (stickybit || 2678c2ecf20Sopenharmony_ci Dbl_isone_lowmantissap2(opnd3p2))) { 2688c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci if (Dbl_isone_hidden(opnd3p1)) dest_exponent++; 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci Dbl_set_mantissa(resultp1,resultp2,opnd3p1,opnd3p2); 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* 2768c2ecf20Sopenharmony_ci * Test for overflow 2778c2ecf20Sopenharmony_ci */ 2788c2ecf20Sopenharmony_ci if (dest_exponent >= DBL_INFINITY_EXPONENT) { 2798c2ecf20Sopenharmony_ci /* trap if OVERFLOWTRAP enabled */ 2808c2ecf20Sopenharmony_ci if (Is_overflowtrap_enabled()) { 2818c2ecf20Sopenharmony_ci /* 2828c2ecf20Sopenharmony_ci * Adjust bias of result 2838c2ecf20Sopenharmony_ci */ 2848c2ecf20Sopenharmony_ci Dbl_setwrapped_exponent(resultp1,dest_exponent,ovfl); 2858c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 2868c2ecf20Sopenharmony_ci if (inexact) 2878c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) 2888c2ecf20Sopenharmony_ci return(OVERFLOWEXCEPTION | INEXACTEXCEPTION); 2898c2ecf20Sopenharmony_ci else Set_inexactflag(); 2908c2ecf20Sopenharmony_ci return(OVERFLOWEXCEPTION); 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci Set_overflowflag(); 2938c2ecf20Sopenharmony_ci /* set result to infinity or largest number */ 2948c2ecf20Sopenharmony_ci Dbl_setoverflow(resultp1,resultp2); 2958c2ecf20Sopenharmony_ci inexact = TRUE; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci /* 2988c2ecf20Sopenharmony_ci * Test for underflow 2998c2ecf20Sopenharmony_ci */ 3008c2ecf20Sopenharmony_ci else if (dest_exponent <= 0) { 3018c2ecf20Sopenharmony_ci /* trap if UNDERFLOWTRAP enabled */ 3028c2ecf20Sopenharmony_ci if (Is_underflowtrap_enabled()) { 3038c2ecf20Sopenharmony_ci /* 3048c2ecf20Sopenharmony_ci * Adjust bias of result 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_ci Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl); 3078c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 3088c2ecf20Sopenharmony_ci if (inexact) 3098c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) 3108c2ecf20Sopenharmony_ci return(UNDERFLOWEXCEPTION | INEXACTEXCEPTION); 3118c2ecf20Sopenharmony_ci else Set_inexactflag(); 3128c2ecf20Sopenharmony_ci return(UNDERFLOWEXCEPTION); 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci /* Determine if should set underflow flag */ 3168c2ecf20Sopenharmony_ci is_tiny = TRUE; 3178c2ecf20Sopenharmony_ci if (dest_exponent == 0 && inexact) { 3188c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 3198c2ecf20Sopenharmony_ci case ROUNDPLUS: 3208c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(resultp1)) { 3218c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3228c2ecf20Sopenharmony_ci if (Dbl_isone_hiddenoverflow(opnd3p1)) 3238c2ecf20Sopenharmony_ci is_tiny = FALSE; 3248c2ecf20Sopenharmony_ci Dbl_decrement(opnd3p1,opnd3p2); 3258c2ecf20Sopenharmony_ci } 3268c2ecf20Sopenharmony_ci break; 3278c2ecf20Sopenharmony_ci case ROUNDMINUS: 3288c2ecf20Sopenharmony_ci if (Dbl_isone_sign(resultp1)) { 3298c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3308c2ecf20Sopenharmony_ci if (Dbl_isone_hiddenoverflow(opnd3p1)) 3318c2ecf20Sopenharmony_ci is_tiny = FALSE; 3328c2ecf20Sopenharmony_ci Dbl_decrement(opnd3p1,opnd3p2); 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci break; 3358c2ecf20Sopenharmony_ci case ROUNDNEAREST: 3368c2ecf20Sopenharmony_ci if (guardbit && (stickybit || 3378c2ecf20Sopenharmony_ci Dbl_isone_lowmantissap2(opnd3p2))) { 3388c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3398c2ecf20Sopenharmony_ci if (Dbl_isone_hiddenoverflow(opnd3p1)) 3408c2ecf20Sopenharmony_ci is_tiny = FALSE; 3418c2ecf20Sopenharmony_ci Dbl_decrement(opnd3p1,opnd3p2); 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci break; 3448c2ecf20Sopenharmony_ci } 3458c2ecf20Sopenharmony_ci } 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci /* 3488c2ecf20Sopenharmony_ci * denormalize result or set to signed zero 3498c2ecf20Sopenharmony_ci */ 3508c2ecf20Sopenharmony_ci stickybit = inexact; 3518c2ecf20Sopenharmony_ci Dbl_denormalize(opnd3p1,opnd3p2,dest_exponent,guardbit, 3528c2ecf20Sopenharmony_ci stickybit,inexact); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci /* return rounded number */ 3558c2ecf20Sopenharmony_ci if (inexact) { 3568c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 3578c2ecf20Sopenharmony_ci case ROUNDPLUS: 3588c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(resultp1)) { 3598c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci break; 3628c2ecf20Sopenharmony_ci case ROUNDMINUS: 3638c2ecf20Sopenharmony_ci if (Dbl_isone_sign(resultp1)) { 3648c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3658c2ecf20Sopenharmony_ci } 3668c2ecf20Sopenharmony_ci break; 3678c2ecf20Sopenharmony_ci case ROUNDNEAREST: 3688c2ecf20Sopenharmony_ci if (guardbit && (stickybit || 3698c2ecf20Sopenharmony_ci Dbl_isone_lowmantissap2(opnd3p2))) { 3708c2ecf20Sopenharmony_ci Dbl_increment(opnd3p1,opnd3p2); 3718c2ecf20Sopenharmony_ci } 3728c2ecf20Sopenharmony_ci break; 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci if (is_tiny) Set_underflowflag(); 3758c2ecf20Sopenharmony_ci } 3768c2ecf20Sopenharmony_ci Dbl_set_exponentmantissa(resultp1,resultp2,opnd3p1,opnd3p2); 3778c2ecf20Sopenharmony_ci } 3788c2ecf20Sopenharmony_ci else Dbl_set_exponent(resultp1,dest_exponent); 3798c2ecf20Sopenharmony_ci Dbl_copytoptr(resultp1,resultp2,dstptr); 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci /* check for inexact */ 3828c2ecf20Sopenharmony_ci if (inexact) { 3838c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 3848c2ecf20Sopenharmony_ci else Set_inexactflag(); 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci return(NOEXCEPTION); 3878c2ecf20Sopenharmony_ci} 388