^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/fp/denormal.c $ Revision: $
^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) * <<please update with a synopsis of the functionality provided by this file>>
^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) * <<the following list was autogenerated, please review>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * dbl_denormalize(dbl_opndp1,dbl_opndp2,inexactflag,rmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * sgl_denormalize(sgl_opnd,inexactflag,rmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Internal Interfaces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * <<please update>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Theory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * <<please update with a overview of the operation of this file>>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * END_DESC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "sgl_float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "dbl_float.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "hppa.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* #include <machine/sys/mdep_private.h> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #undef Fpustatus_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define Fpustatus_register Fpu_register[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) sgl_denormalize(unsigned int *sgl_opnd, boolean *inexactflag, int rmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int opnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int sign, exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) boolean guardbit = FALSE, stickybit, inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) opnd = *sgl_opnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) stickybit = *inexactflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) exponent = Sgl_exponent(opnd) - SGL_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) sign = Sgl_sign(opnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) Sgl_denormalize(opnd,exponent,guardbit,stickybit,inexact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (inexact) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) switch (rmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (sign == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) Sgl_increment(opnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) if (sign != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) Sgl_increment(opnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case ROUNDNEAREST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (guardbit && (stickybit ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) Sgl_isone_lowmantissa(opnd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) Sgl_increment(opnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^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) Sgl_set_sign(opnd,sign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *sgl_opnd = opnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *inexactflag = inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) dbl_denormalize(unsigned int *dbl_opndp1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned int * dbl_opndp2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) boolean *inexactflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int rmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int opndp1, opndp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int sign, exponent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) boolean guardbit = FALSE, stickybit, inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) opndp1 = *dbl_opndp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) opndp2 = *dbl_opndp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) stickybit = *inexactflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) exponent = Dbl_exponent(opndp1) - DBL_WRAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) sign = Dbl_sign(opndp1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) Dbl_denormalize(opndp1,opndp2,exponent,guardbit,stickybit,inexact);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (inexact) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) switch (rmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) case ROUNDPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (sign == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) Dbl_increment(opndp1,opndp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case ROUNDMINUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (sign != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) Dbl_increment(opndp1,opndp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case ROUNDNEAREST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (guardbit && (stickybit ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) Dbl_isone_lowmantissap2(opndp2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) Dbl_increment(opndp1,opndp2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^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) Dbl_set_sign(opndp1,sign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *dbl_opndp1 = opndp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *dbl_opndp2 = opndp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *inexactflag = inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }