^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/dfrem.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 Precision Floating-point Remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * External Interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * dbl_frem(srcptr1,srcptr2,dstptr,status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Internal Interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Theory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * <<please update with a overview of the operation of this file>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * END_DESC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "dbl_float.h"
^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) * Double Precision Floating-point Remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) dbl_frem (dbl_floating_point * srcptr1, dbl_floating_point * srcptr2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dbl_floating_point * dstptr, unsigned int *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) register unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) register unsigned int resultp1, resultp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) register int opnd1_exponent, opnd2_exponent, dest_exponent, stepcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) register boolean roundup = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) Dbl_copyfromptr(srcptr1,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) Dbl_copyfromptr(srcptr2,opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * check first operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if ((opnd1_exponent = Dbl_exponent(opnd1p1)) == DBL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (Dbl_isnotnan(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* invalid since first operand is infinity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return(INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (Dbl_isone_signaling(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return(INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) Dbl_set_quiet(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * is second operand a signaling NaN?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else if (Dbl_is_signalingnan(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (Is_invalidtrap_enabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return(INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) Dbl_set_quiet(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * return quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * check second operand for NaN's or infinity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if ((opnd2_exponent = Dbl_exponent(opnd2p1)) == DBL_INFINITY_EXPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * return first operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * is NaN; signaling or quiet?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (Dbl_isone_signaling(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* trap if INVALIDTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* make NaN quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) Dbl_set_quiet(opnd2p1);
^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 quiet NaN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) Dbl_copytoptr(opnd2p1,opnd2p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * check second operand for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* invalid since second operand is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) Set_invalidflag();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) Dbl_makequietnan(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * get sign of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) resultp1 = opnd1p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * check for denormalized operands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (opnd1_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* check for zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) Dbl_copytoptr(opnd1p1,opnd1p2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* normalize, then continue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) opnd1_exponent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) Dbl_normalize(opnd1p1,opnd1p2,opnd1_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) Dbl_clear_signexponent_set_hidden(opnd1p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (opnd2_exponent == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* normalize, then continue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) opnd2_exponent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) Dbl_normalize(opnd2p1,opnd2p2,opnd2_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) Dbl_clear_signexponent_set_hidden(opnd2p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* find result exponent and divide step loop count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dest_exponent = opnd2_exponent - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) stepcount = opnd1_exponent - opnd2_exponent;
^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) * check for opnd1/opnd2 < 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (stepcount < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * check for opnd1/opnd2 > 1/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * In this case n will round to 1, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * r = opnd1 - opnd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (stepcount == -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* set sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) Dbl_allp1(resultp1) = ~Dbl_allp1(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* align opnd2 with opnd1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Dbl_leftshiftby1(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* now normalize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) while (Dbl_iszero_hidden(opnd2p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) Dbl_leftshiftby1(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dest_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) Dbl_set_exponentmantissa(resultp1,resultp2,opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) goto testforunderflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * opnd1/opnd2 <= 1/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * In this case n will round to zero, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * r = opnd1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dest_exponent = opnd1_exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) goto testforunderflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Generate result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * Do iterative subtract until remainder is less than operand 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) while (stepcount-- > 0 && (Dbl_allp1(opnd1p1) || Dbl_allp2(opnd1p2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) Dbl_leftshiftby1(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * Do last subtract, then determine which way to round if remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * is exactly 1/2 of opnd2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (Dbl_isnotlessthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) Dbl_subtract(opnd1p1,opnd1p2,opnd2p1,opnd2p2,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) roundup = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (stepcount > 0 || Dbl_iszero(opnd1p1,opnd1p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* division is exact, remainder is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) Dbl_setzero_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * Check for cases where opnd1/opnd2 < n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * In this case the result's sign will be opposite that of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * opnd1. The mantissa also needs some correction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) Dbl_leftshiftby1(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (Dbl_isgreaterthan(opnd1p1,opnd1p2,opnd2p1,opnd2p2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) Dbl_invert_sign(resultp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) Dbl_leftshiftby1(opnd2p1,opnd2p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) Dbl_subtract(opnd2p1,opnd2p2,opnd1p1,opnd1p2,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* check for remainder being exactly 1/2 of opnd2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) else if (Dbl_isequal(opnd1p1,opnd1p2,opnd2p1,opnd2p2) && roundup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) Dbl_invert_sign(resultp1);
^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) /* normalize result's mantissa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) while (Dbl_iszero_hidden(opnd1p1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) dest_exponent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) Dbl_leftshiftby1(opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) Dbl_set_exponentmantissa(resultp1,resultp2,opnd1p1,opnd1p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Test for underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) testforunderflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (dest_exponent <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* trap if UNDERFLOWTRAP enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (Is_underflowtrap_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * Adjust bias of result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) Dbl_setwrapped_exponent(resultp1,dest_exponent,unfl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* frem is always exact */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return(UNDERFLOWEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * denormalize result or set to signed zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (dest_exponent >= (1 - DBL_P)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) Dbl_rightshift_exponentmantissa(resultp1,resultp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 1-dest_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) Dbl_setzero_exponentmantissa(resultp1,resultp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else Dbl_set_exponent(resultp1,dest_exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) Dbl_copytoptr(resultp1,resultp2,dstptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return(NOEXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }