/*1* Linux/PA-RISC Project (http://www.parisc-linux.org/)2*3* Floating-point emulation code4* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2, or (at your option)9* any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19*/20/*21* BEGIN_DESC22*23* File:24* @(#) pa/spmath/fcnvuf.c $Revision: 1.1 $25*26* Purpose:27* Fixed point to Floating-point Converts28*29* External Interfaces:30* dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)31* dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)32* sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)33* sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)34*35* Internal Interfaces:36*37* Theory:38* <<please update with a overview of the operation of this file>>39*40* END_DESC41*/424344#include "float.h"45#include "sgl_float.h"46#include "dbl_float.h"47#include "cnv_float.h"4849/************************************************************************50* Fixed point to Floating-point Converts *51************************************************************************/5253/*54* Convert Single Unsigned Fixed to Single Floating-point format55*/5657int58sgl_to_sgl_fcnvuf(59unsigned int *srcptr,60unsigned int *nullptr,61sgl_floating_point *dstptr,62unsigned int *status)63{64register unsigned int src, result = 0;65register int dst_exponent;6667src = *srcptr;6869/* Check for zero */70if (src == 0) {71Sgl_setzero(result);72*dstptr = result;73return(NOEXCEPTION);74}75/*76* Generate exponent and normalized mantissa77*/78dst_exponent = 16; /* initialize for normalization */79/*80* Check word for most significant bit set. Returns81* a value in dst_exponent indicating the bit position,82* between -1 and 30.83*/84Find_ms_one_bit(src,dst_exponent);85/* left justify source, with msb at bit position 0 */86src <<= dst_exponent+1;87Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);88Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);8990/* check for inexact */91if (Suint_isinexact_to_sgl(src)) {92switch (Rounding_mode()) {93case ROUNDPLUS:94Sgl_increment(result);95break;96case ROUNDMINUS: /* never negative */97break;98case ROUNDNEAREST:99Sgl_roundnearest_from_suint(src,result);100break;101}102if (Is_inexacttrap_enabled()) {103*dstptr = result;104return(INEXACTEXCEPTION);105}106else Set_inexactflag();107}108*dstptr = result;109return(NOEXCEPTION);110}111112/*113* Single Unsigned Fixed to Double Floating-point114*/115116int117sgl_to_dbl_fcnvuf(118unsigned int *srcptr,119unsigned int *nullptr,120dbl_floating_point *dstptr,121unsigned int *status)122{123register int dst_exponent;124register unsigned int src, resultp1 = 0, resultp2 = 0;125126src = *srcptr;127128/* Check for zero */129if (src == 0) {130Dbl_setzero(resultp1,resultp2);131Dbl_copytoptr(resultp1,resultp2,dstptr);132return(NOEXCEPTION);133}134/*135* Generate exponent and normalized mantissa136*/137dst_exponent = 16; /* initialize for normalization */138/*139* Check word for most significant bit set. Returns140* a value in dst_exponent indicating the bit position,141* between -1 and 30.142*/143Find_ms_one_bit(src,dst_exponent);144/* left justify source, with msb at bit position 0 */145src <<= dst_exponent+1;146Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);147Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));148Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);149Dbl_copytoptr(resultp1,resultp2,dstptr);150return(NOEXCEPTION);151}152153/*154* Double Unsigned Fixed to Single Floating-point155*/156157int158dbl_to_sgl_fcnvuf(159dbl_unsigned *srcptr,160unsigned int *nullptr,161sgl_floating_point *dstptr,162unsigned int *status)163{164int dst_exponent;165unsigned int srcp1, srcp2, result = 0;166167Duint_copyfromptr(srcptr,srcp1,srcp2);168169/* Check for zero */170if (srcp1 == 0 && srcp2 == 0) {171Sgl_setzero(result);172*dstptr = result;173return(NOEXCEPTION);174}175/*176* Generate exponent and normalized mantissa177*/178dst_exponent = 16; /* initialize for normalization */179if (srcp1 == 0) {180/*181* Check word for most significant bit set. Returns182* a value in dst_exponent indicating the bit position,183* between -1 and 30.184*/185Find_ms_one_bit(srcp2,dst_exponent);186/* left justify source, with msb at bit position 0 */187srcp1 = srcp2 << dst_exponent+1;188srcp2 = 0;189/*190* since msb set is in second word, need to191* adjust bit position count192*/193dst_exponent += 32;194}195else {196/*197* Check word for most significant bit set. Returns198* a value in dst_exponent indicating the bit position,199* between -1 and 30.200*201*/202Find_ms_one_bit(srcp1,dst_exponent);203/* left justify source, with msb at bit position 0 */204if (dst_exponent >= 0) {205Variable_shift_double(srcp1,srcp2,(31-dst_exponent),206srcp1);207srcp2 <<= dst_exponent+1;208}209}210Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);211Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);212213/* check for inexact */214if (Duint_isinexact_to_sgl(srcp1,srcp2)) {215switch (Rounding_mode()) {216case ROUNDPLUS:217Sgl_increment(result);218break;219case ROUNDMINUS: /* never negative */220break;221case ROUNDNEAREST:222Sgl_roundnearest_from_duint(srcp1,srcp2,result);223break;224}225if (Is_inexacttrap_enabled()) {226*dstptr = result;227return(INEXACTEXCEPTION);228}229else Set_inexactflag();230}231*dstptr = result;232return(NOEXCEPTION);233}234235/*236* Double Unsigned Fixed to Double Floating-point237*/238239int240dbl_to_dbl_fcnvuf(241dbl_unsigned *srcptr,242unsigned int *nullptr,243dbl_floating_point *dstptr,244unsigned int *status)245{246register int dst_exponent;247register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;248249Duint_copyfromptr(srcptr,srcp1,srcp2);250251/* Check for zero */252if (srcp1 == 0 && srcp2 ==0) {253Dbl_setzero(resultp1,resultp2);254Dbl_copytoptr(resultp1,resultp2,dstptr);255return(NOEXCEPTION);256}257/*258* Generate exponent and normalized mantissa259*/260dst_exponent = 16; /* initialize for normalization */261if (srcp1 == 0) {262/*263* Check word for most significant bit set. Returns264* a value in dst_exponent indicating the bit position,265* between -1 and 30.266*/267Find_ms_one_bit(srcp2,dst_exponent);268/* left justify source, with msb at bit position 0 */269srcp1 = srcp2 << dst_exponent+1;270srcp2 = 0;271/*272* since msb set is in second word, need to273* adjust bit position count274*/275dst_exponent += 32;276}277else {278/*279* Check word for most significant bit set. Returns280* a value in dst_exponent indicating the bit position,281* between -1 and 30.282*/283Find_ms_one_bit(srcp1,dst_exponent);284/* left justify source, with msb at bit position 0 */285if (dst_exponent >= 0) {286Variable_shift_double(srcp1,srcp2,(31-dst_exponent),287srcp1);288srcp2 <<= dst_exponent+1;289}290}291Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);292Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);293Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);294295/* check for inexact */296if (Duint_isinexact_to_dbl(srcp2)) {297switch (Rounding_mode()) {298case ROUNDPLUS:299Dbl_increment(resultp1,resultp2);300break;301case ROUNDMINUS: /* never negative */302break;303case ROUNDNEAREST:304Dbl_roundnearest_from_duint(srcp2,resultp1,305resultp2);306break;307}308if (Is_inexacttrap_enabled()) {309Dbl_copytoptr(resultp1,resultp2,dstptr);310return(INEXACTEXCEPTION);311}312else Set_inexactflag();313}314Dbl_copytoptr(resultp1,resultp2,dstptr);315return(NOEXCEPTION);316}317318319320