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/fcnvfu.c $Revision: 1.1 $ 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Purpose: 158c2ecf20Sopenharmony_ci * Floating-point to Unsigned Fixed-point Converts 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * External Interfaces: 188c2ecf20Sopenharmony_ci * dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status) 198c2ecf20Sopenharmony_ci * dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status) 208c2ecf20Sopenharmony_ci * sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status) 218c2ecf20Sopenharmony_ci * sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status) 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Internal Interfaces: 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * Theory: 268c2ecf20Sopenharmony_ci * <<please update with a overview of the operation of this file>> 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * END_DESC 298c2ecf20Sopenharmony_ci*/ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include "float.h" 338c2ecf20Sopenharmony_ci#include "sgl_float.h" 348c2ecf20Sopenharmony_ci#include "dbl_float.h" 358c2ecf20Sopenharmony_ci#include "cnv_float.h" 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/************************************************************************ 388c2ecf20Sopenharmony_ci * Floating-point to Unsigned Fixed-point Converts * 398c2ecf20Sopenharmony_ci ************************************************************************/ 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* 428c2ecf20Sopenharmony_ci * Single Floating-point to Single Unsigned Fixed 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci/*ARGSUSED*/ 458c2ecf20Sopenharmony_ciint 468c2ecf20Sopenharmony_cisgl_to_sgl_fcnvfu( 478c2ecf20Sopenharmony_ci sgl_floating_point *srcptr, 488c2ecf20Sopenharmony_ci unsigned int *nullptr, 498c2ecf20Sopenharmony_ci unsigned int *dstptr, 508c2ecf20Sopenharmony_ci unsigned int *status) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci register unsigned int src, result; 538c2ecf20Sopenharmony_ci register int src_exponent; 548c2ecf20Sopenharmony_ci register boolean inexact = FALSE; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci src = *srcptr; 578c2ecf20Sopenharmony_ci src_exponent = Sgl_exponent(src) - SGL_BIAS; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* 608c2ecf20Sopenharmony_ci * Test for overflow 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_ci if (src_exponent > SGL_FX_MAX_EXP + 1) { 638c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 648c2ecf20Sopenharmony_ci result = 0; 658c2ecf20Sopenharmony_ci } else { 668c2ecf20Sopenharmony_ci result = 0xffffffff; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 698c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci Set_invalidflag(); 728c2ecf20Sopenharmony_ci *dstptr = result; 738c2ecf20Sopenharmony_ci return(NOEXCEPTION); 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci /* 768c2ecf20Sopenharmony_ci * Generate result 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci if (src_exponent >= 0) { 798c2ecf20Sopenharmony_ci /* 808c2ecf20Sopenharmony_ci * Check sign. 818c2ecf20Sopenharmony_ci * If negative, trap unimplemented. 828c2ecf20Sopenharmony_ci */ 838c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 848c2ecf20Sopenharmony_ci result = 0; 858c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 868c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 878c2ecf20Sopenharmony_ci } 888c2ecf20Sopenharmony_ci Set_invalidflag(); 898c2ecf20Sopenharmony_ci *dstptr = result; 908c2ecf20Sopenharmony_ci return(NOEXCEPTION); 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci Sgl_clear_signexponent_set_hidden(src); 938c2ecf20Sopenharmony_ci Suint_from_sgl_mantissa(src,src_exponent,result); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* check for inexact */ 968c2ecf20Sopenharmony_ci if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 978c2ecf20Sopenharmony_ci inexact = TRUE; 988c2ecf20Sopenharmony_ci /* round result */ 998c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 1008c2ecf20Sopenharmony_ci case ROUNDPLUS: 1018c2ecf20Sopenharmony_ci result++; 1028c2ecf20Sopenharmony_ci break; 1038c2ecf20Sopenharmony_ci case ROUNDMINUS: /* never negative */ 1048c2ecf20Sopenharmony_ci break; 1058c2ecf20Sopenharmony_ci case ROUNDNEAREST: 1068c2ecf20Sopenharmony_ci if (Sgl_isone_roundbit(src,src_exponent) && 1078c2ecf20Sopenharmony_ci (Sgl_isone_stickybit(src,src_exponent) || 1088c2ecf20Sopenharmony_ci (result & 1))) { 1098c2ecf20Sopenharmony_ci result++; 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci } else { 1158c2ecf20Sopenharmony_ci result = 0; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci /* check for inexact */ 1188c2ecf20Sopenharmony_ci if (Sgl_isnotzero_exponentmantissa(src)) { 1198c2ecf20Sopenharmony_ci inexact = TRUE; 1208c2ecf20Sopenharmony_ci /* round result */ 1218c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 1228c2ecf20Sopenharmony_ci case ROUNDPLUS: 1238c2ecf20Sopenharmony_ci if (Sgl_iszero_sign(src)) { 1248c2ecf20Sopenharmony_ci result++; 1258c2ecf20Sopenharmony_ci } 1268c2ecf20Sopenharmony_ci break; 1278c2ecf20Sopenharmony_ci case ROUNDMINUS: 1288c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 1298c2ecf20Sopenharmony_ci result = 0; 1308c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 1318c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci Set_invalidflag(); 1348c2ecf20Sopenharmony_ci inexact = FALSE; 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci break; 1378c2ecf20Sopenharmony_ci case ROUNDNEAREST: 1388c2ecf20Sopenharmony_ci if (src_exponent == -1 && 1398c2ecf20Sopenharmony_ci Sgl_isnotzero_mantissa(src)) { 1408c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 1418c2ecf20Sopenharmony_ci result = 0; 1428c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 1438c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci Set_invalidflag(); 1468c2ecf20Sopenharmony_ci inexact = FALSE; 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci else result++; 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci break; 1518c2ecf20Sopenharmony_ci } 1528c2ecf20Sopenharmony_ci } 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci *dstptr = result; 1558c2ecf20Sopenharmony_ci if (inexact) { 1568c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 1578c2ecf20Sopenharmony_ci else Set_inexactflag(); 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/* 1638c2ecf20Sopenharmony_ci * Single Floating-point to Double Unsigned Fixed 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_ci/*ARGSUSED*/ 1668c2ecf20Sopenharmony_ciint 1678c2ecf20Sopenharmony_cisgl_to_dbl_fcnvfu( 1688c2ecf20Sopenharmony_ci sgl_floating_point *srcptr, 1698c2ecf20Sopenharmony_ci unsigned int *nullptr, 1708c2ecf20Sopenharmony_ci dbl_unsigned *dstptr, 1718c2ecf20Sopenharmony_ci unsigned int *status) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci register int src_exponent; 1748c2ecf20Sopenharmony_ci register unsigned int src, resultp1, resultp2; 1758c2ecf20Sopenharmony_ci register boolean inexact = FALSE; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci src = *srcptr; 1788c2ecf20Sopenharmony_ci src_exponent = Sgl_exponent(src) - SGL_BIAS; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci /* 1818c2ecf20Sopenharmony_ci * Test for overflow 1828c2ecf20Sopenharmony_ci */ 1838c2ecf20Sopenharmony_ci if (src_exponent > DBL_FX_MAX_EXP + 1) { 1848c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 1858c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 1868c2ecf20Sopenharmony_ci } else { 1878c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0xffffffff; 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 1908c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci Set_invalidflag(); 1938c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 1948c2ecf20Sopenharmony_ci return(NOEXCEPTION); 1958c2ecf20Sopenharmony_ci } 1968c2ecf20Sopenharmony_ci /* 1978c2ecf20Sopenharmony_ci * Generate result 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci if (src_exponent >= 0) { 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * Check sign. 2028c2ecf20Sopenharmony_ci * If negative, trap unimplemented. 2038c2ecf20Sopenharmony_ci */ 2048c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 2058c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 2068c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 2078c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci Set_invalidflag(); 2108c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 2118c2ecf20Sopenharmony_ci return(NOEXCEPTION); 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci Sgl_clear_signexponent_set_hidden(src); 2148c2ecf20Sopenharmony_ci Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* check for inexact */ 2178c2ecf20Sopenharmony_ci if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 2188c2ecf20Sopenharmony_ci inexact = TRUE; 2198c2ecf20Sopenharmony_ci /* round result */ 2208c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 2218c2ecf20Sopenharmony_ci case ROUNDPLUS: 2228c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 2238c2ecf20Sopenharmony_ci break; 2248c2ecf20Sopenharmony_ci case ROUNDMINUS: /* never negative */ 2258c2ecf20Sopenharmony_ci break; 2268c2ecf20Sopenharmony_ci case ROUNDNEAREST: 2278c2ecf20Sopenharmony_ci if (Sgl_isone_roundbit(src,src_exponent) && 2288c2ecf20Sopenharmony_ci (Sgl_isone_stickybit(src,src_exponent) || 2298c2ecf20Sopenharmony_ci Duint_isone_lowp2(resultp2))) { 2308c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci break; 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci } 2358c2ecf20Sopenharmony_ci } else { 2368c2ecf20Sopenharmony_ci Duint_setzero(resultp1,resultp2); 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* check for inexact */ 2398c2ecf20Sopenharmony_ci if (Sgl_isnotzero_exponentmantissa(src)) { 2408c2ecf20Sopenharmony_ci inexact = TRUE; 2418c2ecf20Sopenharmony_ci /* round result */ 2428c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 2438c2ecf20Sopenharmony_ci case ROUNDPLUS: 2448c2ecf20Sopenharmony_ci if (Sgl_iszero_sign(src)) { 2458c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci break; 2488c2ecf20Sopenharmony_ci case ROUNDMINUS: 2498c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 2508c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 2518c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 2528c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci Set_invalidflag(); 2558c2ecf20Sopenharmony_ci inexact = FALSE; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci break; 2588c2ecf20Sopenharmony_ci case ROUNDNEAREST: 2598c2ecf20Sopenharmony_ci if (src_exponent == -1 && 2608c2ecf20Sopenharmony_ci Sgl_isnotzero_mantissa(src)) { 2618c2ecf20Sopenharmony_ci if (Sgl_isone_sign(src)) { 2628c2ecf20Sopenharmony_ci resultp1 = 0; 2638c2ecf20Sopenharmony_ci resultp2 = 0; 2648c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 2658c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 2668c2ecf20Sopenharmony_ci } 2678c2ecf20Sopenharmony_ci Set_invalidflag(); 2688c2ecf20Sopenharmony_ci inexact = FALSE; 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci else Duint_increment(resultp1,resultp2); 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 2768c2ecf20Sopenharmony_ci if (inexact) { 2778c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 2788c2ecf20Sopenharmony_ci else Set_inexactflag(); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci return(NOEXCEPTION); 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci/* 2848c2ecf20Sopenharmony_ci * Double Floating-point to Single Unsigned Fixed 2858c2ecf20Sopenharmony_ci */ 2868c2ecf20Sopenharmony_ci/*ARGSUSED*/ 2878c2ecf20Sopenharmony_ciint 2888c2ecf20Sopenharmony_cidbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr, 2898c2ecf20Sopenharmony_ci unsigned int *dstptr, unsigned int *status) 2908c2ecf20Sopenharmony_ci{ 2918c2ecf20Sopenharmony_ci register unsigned int srcp1, srcp2, result; 2928c2ecf20Sopenharmony_ci register int src_exponent; 2938c2ecf20Sopenharmony_ci register boolean inexact = FALSE; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci Dbl_copyfromptr(srcptr,srcp1,srcp2); 2968c2ecf20Sopenharmony_ci src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci /* 2998c2ecf20Sopenharmony_ci * Test for overflow 3008c2ecf20Sopenharmony_ci */ 3018c2ecf20Sopenharmony_ci if (src_exponent > SGL_FX_MAX_EXP + 1) { 3028c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 3038c2ecf20Sopenharmony_ci result = 0; 3048c2ecf20Sopenharmony_ci } else { 3058c2ecf20Sopenharmony_ci result = 0xffffffff; 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 3088c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci Set_invalidflag(); 3118c2ecf20Sopenharmony_ci *dstptr = result; 3128c2ecf20Sopenharmony_ci return(NOEXCEPTION); 3138c2ecf20Sopenharmony_ci } 3148c2ecf20Sopenharmony_ci /* 3158c2ecf20Sopenharmony_ci * Generate result 3168c2ecf20Sopenharmony_ci */ 3178c2ecf20Sopenharmony_ci if (src_exponent >= 0) { 3188c2ecf20Sopenharmony_ci /* 3198c2ecf20Sopenharmony_ci * Check sign. 3208c2ecf20Sopenharmony_ci * If negative, trap unimplemented. 3218c2ecf20Sopenharmony_ci */ 3228c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 3238c2ecf20Sopenharmony_ci result = 0; 3248c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 3258c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci Set_invalidflag(); 3288c2ecf20Sopenharmony_ci *dstptr = result; 3298c2ecf20Sopenharmony_ci return(NOEXCEPTION); 3308c2ecf20Sopenharmony_ci } 3318c2ecf20Sopenharmony_ci Dbl_clear_signexponent_set_hidden(srcp1); 3328c2ecf20Sopenharmony_ci Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci /* check for inexact */ 3358c2ecf20Sopenharmony_ci if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 3368c2ecf20Sopenharmony_ci inexact = TRUE; 3378c2ecf20Sopenharmony_ci /* round result */ 3388c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 3398c2ecf20Sopenharmony_ci case ROUNDPLUS: 3408c2ecf20Sopenharmony_ci result++; 3418c2ecf20Sopenharmony_ci break; 3428c2ecf20Sopenharmony_ci case ROUNDMINUS: /* never negative */ 3438c2ecf20Sopenharmony_ci break; 3448c2ecf20Sopenharmony_ci case ROUNDNEAREST: 3458c2ecf20Sopenharmony_ci if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent) && 3468c2ecf20Sopenharmony_ci (Dbl_isone_stickybit(srcp1,srcp2,src_exponent)|| 3478c2ecf20Sopenharmony_ci result&1)) 3488c2ecf20Sopenharmony_ci result++; 3498c2ecf20Sopenharmony_ci break; 3508c2ecf20Sopenharmony_ci } 3518c2ecf20Sopenharmony_ci /* check for overflow */ 3528c2ecf20Sopenharmony_ci if (result == 0) { 3538c2ecf20Sopenharmony_ci result = 0xffffffff; 3548c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 3558c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci Set_invalidflag(); 3588c2ecf20Sopenharmony_ci *dstptr = result; 3598c2ecf20Sopenharmony_ci return(NOEXCEPTION); 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci } 3628c2ecf20Sopenharmony_ci } else { 3638c2ecf20Sopenharmony_ci result = 0; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci /* check for inexact */ 3668c2ecf20Sopenharmony_ci if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 3678c2ecf20Sopenharmony_ci inexact = TRUE; 3688c2ecf20Sopenharmony_ci /* round result */ 3698c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 3708c2ecf20Sopenharmony_ci case ROUNDPLUS: 3718c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(srcp1)) result++; 3728c2ecf20Sopenharmony_ci break; 3738c2ecf20Sopenharmony_ci case ROUNDMINUS: 3748c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 3758c2ecf20Sopenharmony_ci result = 0; 3768c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 3778c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 3788c2ecf20Sopenharmony_ci } 3798c2ecf20Sopenharmony_ci Set_invalidflag(); 3808c2ecf20Sopenharmony_ci inexact = FALSE; 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci break; 3838c2ecf20Sopenharmony_ci case ROUNDNEAREST: 3848c2ecf20Sopenharmony_ci if (src_exponent == -1 && 3858c2ecf20Sopenharmony_ci Dbl_isnotzero_mantissa(srcp1,srcp2)) 3868c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 3878c2ecf20Sopenharmony_ci result = 0; 3888c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 3898c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 3908c2ecf20Sopenharmony_ci } 3918c2ecf20Sopenharmony_ci Set_invalidflag(); 3928c2ecf20Sopenharmony_ci inexact = FALSE; 3938c2ecf20Sopenharmony_ci } 3948c2ecf20Sopenharmony_ci else result++; 3958c2ecf20Sopenharmony_ci } 3968c2ecf20Sopenharmony_ci } 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci *dstptr = result; 3998c2ecf20Sopenharmony_ci if (inexact) { 4008c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 4018c2ecf20Sopenharmony_ci else Set_inexactflag(); 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci return(NOEXCEPTION); 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci/* 4078c2ecf20Sopenharmony_ci * Double Floating-point to Double Unsigned Fixed 4088c2ecf20Sopenharmony_ci */ 4098c2ecf20Sopenharmony_ci/*ARGSUSED*/ 4108c2ecf20Sopenharmony_ciint 4118c2ecf20Sopenharmony_cidbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr, 4128c2ecf20Sopenharmony_ci dbl_unsigned * dstptr, unsigned int *status) 4138c2ecf20Sopenharmony_ci{ 4148c2ecf20Sopenharmony_ci register int src_exponent; 4158c2ecf20Sopenharmony_ci register unsigned int srcp1, srcp2, resultp1, resultp2; 4168c2ecf20Sopenharmony_ci register boolean inexact = FALSE; 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci Dbl_copyfromptr(srcptr,srcp1,srcp2); 4198c2ecf20Sopenharmony_ci src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci /* 4228c2ecf20Sopenharmony_ci * Test for overflow 4238c2ecf20Sopenharmony_ci */ 4248c2ecf20Sopenharmony_ci if (src_exponent > DBL_FX_MAX_EXP + 1) { 4258c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 4268c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 4278c2ecf20Sopenharmony_ci } else { 4288c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0xffffffff; 4298c2ecf20Sopenharmony_ci } 4308c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 4318c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 4328c2ecf20Sopenharmony_ci } 4338c2ecf20Sopenharmony_ci Set_invalidflag(); 4348c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 4358c2ecf20Sopenharmony_ci return(NOEXCEPTION); 4368c2ecf20Sopenharmony_ci } 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci /* 4398c2ecf20Sopenharmony_ci * Generate result 4408c2ecf20Sopenharmony_ci */ 4418c2ecf20Sopenharmony_ci if (src_exponent >= 0) { 4428c2ecf20Sopenharmony_ci /* 4438c2ecf20Sopenharmony_ci * Check sign. 4448c2ecf20Sopenharmony_ci * If negative, trap unimplemented. 4458c2ecf20Sopenharmony_ci */ 4468c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 4478c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 4488c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 4498c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 4508c2ecf20Sopenharmony_ci } 4518c2ecf20Sopenharmony_ci Set_invalidflag(); 4528c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 4538c2ecf20Sopenharmony_ci return(NOEXCEPTION); 4548c2ecf20Sopenharmony_ci } 4558c2ecf20Sopenharmony_ci Dbl_clear_signexponent_set_hidden(srcp1); 4568c2ecf20Sopenharmony_ci Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,resultp1, 4578c2ecf20Sopenharmony_ci resultp2); 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci /* check for inexact */ 4608c2ecf20Sopenharmony_ci if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 4618c2ecf20Sopenharmony_ci inexact = TRUE; 4628c2ecf20Sopenharmony_ci /* round result */ 4638c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 4648c2ecf20Sopenharmony_ci case ROUNDPLUS: 4658c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 4668c2ecf20Sopenharmony_ci break; 4678c2ecf20Sopenharmony_ci case ROUNDMINUS: /* never negative */ 4688c2ecf20Sopenharmony_ci break; 4698c2ecf20Sopenharmony_ci case ROUNDNEAREST: 4708c2ecf20Sopenharmony_ci if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent)) 4718c2ecf20Sopenharmony_ci if(Dbl_isone_stickybit(srcp1,srcp2,src_exponent) || 4728c2ecf20Sopenharmony_ci Duint_isone_lowp2(resultp2)) 4738c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 4748c2ecf20Sopenharmony_ci } 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci } else { 4778c2ecf20Sopenharmony_ci Duint_setzero(resultp1,resultp2); 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci /* check for inexact */ 4808c2ecf20Sopenharmony_ci if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 4818c2ecf20Sopenharmony_ci inexact = TRUE; 4828c2ecf20Sopenharmony_ci /* round result */ 4838c2ecf20Sopenharmony_ci switch (Rounding_mode()) { 4848c2ecf20Sopenharmony_ci case ROUNDPLUS: 4858c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(srcp1)) { 4868c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 4878c2ecf20Sopenharmony_ci } 4888c2ecf20Sopenharmony_ci break; 4898c2ecf20Sopenharmony_ci case ROUNDMINUS: 4908c2ecf20Sopenharmony_ci if (Dbl_isone_sign(srcp1)) { 4918c2ecf20Sopenharmony_ci resultp1 = resultp2 = 0; 4928c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 4938c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 4948c2ecf20Sopenharmony_ci } 4958c2ecf20Sopenharmony_ci Set_invalidflag(); 4968c2ecf20Sopenharmony_ci inexact = FALSE; 4978c2ecf20Sopenharmony_ci } 4988c2ecf20Sopenharmony_ci break; 4998c2ecf20Sopenharmony_ci case ROUNDNEAREST: 5008c2ecf20Sopenharmony_ci if (src_exponent == -1 && 5018c2ecf20Sopenharmony_ci Dbl_isnotzero_mantissa(srcp1,srcp2)) 5028c2ecf20Sopenharmony_ci if (Dbl_iszero_sign(srcp1)) { 5038c2ecf20Sopenharmony_ci Duint_increment(resultp1,resultp2); 5048c2ecf20Sopenharmony_ci } else { 5058c2ecf20Sopenharmony_ci resultp1 = 0; 5068c2ecf20Sopenharmony_ci resultp2 = 0; 5078c2ecf20Sopenharmony_ci if (Is_invalidtrap_enabled()) { 5088c2ecf20Sopenharmony_ci return(INVALIDEXCEPTION); 5098c2ecf20Sopenharmony_ci } 5108c2ecf20Sopenharmony_ci Set_invalidflag(); 5118c2ecf20Sopenharmony_ci inexact = FALSE; 5128c2ecf20Sopenharmony_ci } 5138c2ecf20Sopenharmony_ci } 5148c2ecf20Sopenharmony_ci } 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci Duint_copytoptr(resultp1,resultp2,dstptr); 5178c2ecf20Sopenharmony_ci if (inexact) { 5188c2ecf20Sopenharmony_ci if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 5198c2ecf20Sopenharmony_ci else Set_inexactflag(); 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci return(NOEXCEPTION); 5228c2ecf20Sopenharmony_ci} 5238c2ecf20Sopenharmony_ci 524