// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Linux/PA-RISC Project (http://www.parisc-linux.org/)3*4* Floating-point emulation code5* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <[email protected]>6*/7/*8* BEGIN_DESC9*10* File:11* @(#) pa/spmath/fcnvuf.c $Revision: 1.1 $12*13* Purpose:14* Fixed point to Floating-point Converts15*16* External Interfaces:17* dbl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)18* dbl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)19* sgl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)20* sgl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)21*22* Internal Interfaces:23*24* Theory:25* <<please update with a overview of the operation of this file>>26*27* END_DESC28*/293031#include "float.h"32#include "sgl_float.h"33#include "dbl_float.h"34#include "cnv_float.h"3536/************************************************************************37* Fixed point to Floating-point Converts *38************************************************************************/3940/*41* Convert Single Unsigned Fixed to Single Floating-point format42*/4344int45sgl_to_sgl_fcnvuf(46unsigned int *srcptr,47unsigned int *_nullptr,48sgl_floating_point *dstptr,49unsigned int *status)50{51register unsigned int src, result = 0;52register int dst_exponent;5354src = *srcptr;5556/* Check for zero */57if (src == 0) {58Sgl_setzero(result);59*dstptr = result;60return(NOEXCEPTION);61}62/*63* Generate exponent and normalized mantissa64*/65dst_exponent = 16; /* initialize for normalization */66/*67* Check word for most significant bit set. Returns68* a value in dst_exponent indicating the bit position,69* between -1 and 30.70*/71Find_ms_one_bit(src,dst_exponent);72/* left justify source, with msb at bit position 0 */73src <<= dst_exponent+1;74Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);75Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);7677/* check for inexact */78if (Suint_isinexact_to_sgl(src)) {79switch (Rounding_mode()) {80case ROUNDPLUS:81Sgl_increment(result);82break;83case ROUNDMINUS: /* never negative */84break;85case ROUNDNEAREST:86Sgl_roundnearest_from_suint(src,result);87break;88}89if (Is_inexacttrap_enabled()) {90*dstptr = result;91return(INEXACTEXCEPTION);92}93else Set_inexactflag();94}95*dstptr = result;96return(NOEXCEPTION);97}9899/*100* Single Unsigned Fixed to Double Floating-point101*/102103int104sgl_to_dbl_fcnvuf(105unsigned int *srcptr,106unsigned int *_nullptr,107dbl_floating_point *dstptr,108unsigned int *status)109{110register int dst_exponent;111register unsigned int src, resultp1 = 0, resultp2 = 0;112113src = *srcptr;114115/* Check for zero */116if (src == 0) {117Dbl_setzero(resultp1,resultp2);118Dbl_copytoptr(resultp1,resultp2,dstptr);119return(NOEXCEPTION);120}121/*122* Generate exponent and normalized mantissa123*/124dst_exponent = 16; /* initialize for normalization */125/*126* Check word for most significant bit set. Returns127* a value in dst_exponent indicating the bit position,128* between -1 and 30.129*/130Find_ms_one_bit(src,dst_exponent);131/* left justify source, with msb at bit position 0 */132src <<= dst_exponent+1;133Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);134Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));135Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);136Dbl_copytoptr(resultp1,resultp2,dstptr);137return(NOEXCEPTION);138}139140/*141* Double Unsigned Fixed to Single Floating-point142*/143144int145dbl_to_sgl_fcnvuf(146dbl_unsigned *srcptr,147unsigned int *_nullptr,148sgl_floating_point *dstptr,149unsigned int *status)150{151int dst_exponent;152unsigned int srcp1, srcp2, result = 0;153154Duint_copyfromptr(srcptr,srcp1,srcp2);155156/* Check for zero */157if (srcp1 == 0 && srcp2 == 0) {158Sgl_setzero(result);159*dstptr = result;160return(NOEXCEPTION);161}162/*163* Generate exponent and normalized mantissa164*/165dst_exponent = 16; /* initialize for normalization */166if (srcp1 == 0) {167/*168* Check word for most significant bit set. Returns169* a value in dst_exponent indicating the bit position,170* between -1 and 30.171*/172Find_ms_one_bit(srcp2,dst_exponent);173/* left justify source, with msb at bit position 0 */174srcp1 = srcp2 << dst_exponent+1;175srcp2 = 0;176/*177* since msb set is in second word, need to178* adjust bit position count179*/180dst_exponent += 32;181}182else {183/*184* Check word for most significant bit set. Returns185* a value in dst_exponent indicating the bit position,186* between -1 and 30.187*188*/189Find_ms_one_bit(srcp1,dst_exponent);190/* left justify source, with msb at bit position 0 */191if (dst_exponent >= 0) {192Variable_shift_double(srcp1,srcp2,(31-dst_exponent),193srcp1);194srcp2 <<= dst_exponent+1;195}196}197Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);198Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);199200/* check for inexact */201if (Duint_isinexact_to_sgl(srcp1,srcp2)) {202switch (Rounding_mode()) {203case ROUNDPLUS:204Sgl_increment(result);205break;206case ROUNDMINUS: /* never negative */207break;208case ROUNDNEAREST:209Sgl_roundnearest_from_duint(srcp1,srcp2,result);210break;211}212if (Is_inexacttrap_enabled()) {213*dstptr = result;214return(INEXACTEXCEPTION);215}216else Set_inexactflag();217}218*dstptr = result;219return(NOEXCEPTION);220}221222/*223* Double Unsigned Fixed to Double Floating-point224*/225226int227dbl_to_dbl_fcnvuf(228dbl_unsigned *srcptr,229unsigned int *_nullptr,230dbl_floating_point *dstptr,231unsigned int *status)232{233register int dst_exponent;234register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;235236Duint_copyfromptr(srcptr,srcp1,srcp2);237238/* Check for zero */239if (srcp1 == 0 && srcp2 ==0) {240Dbl_setzero(resultp1,resultp2);241Dbl_copytoptr(resultp1,resultp2,dstptr);242return(NOEXCEPTION);243}244/*245* Generate exponent and normalized mantissa246*/247dst_exponent = 16; /* initialize for normalization */248if (srcp1 == 0) {249/*250* Check word for most significant bit set. Returns251* a value in dst_exponent indicating the bit position,252* between -1 and 30.253*/254Find_ms_one_bit(srcp2,dst_exponent);255/* left justify source, with msb at bit position 0 */256srcp1 = srcp2 << dst_exponent+1;257srcp2 = 0;258/*259* since msb set is in second word, need to260* adjust bit position count261*/262dst_exponent += 32;263}264else {265/*266* Check word for most significant bit set. Returns267* a value in dst_exponent indicating the bit position,268* between -1 and 30.269*/270Find_ms_one_bit(srcp1,dst_exponent);271/* left justify source, with msb at bit position 0 */272if (dst_exponent >= 0) {273Variable_shift_double(srcp1,srcp2,(31-dst_exponent),274srcp1);275srcp2 <<= dst_exponent+1;276}277}278Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);279Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);280Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);281282/* check for inexact */283if (Duint_isinexact_to_dbl(srcp2)) {284switch (Rounding_mode()) {285case ROUNDPLUS:286Dbl_increment(resultp1,resultp2);287break;288case ROUNDMINUS: /* never negative */289break;290case ROUNDNEAREST:291Dbl_roundnearest_from_duint(srcp2,resultp1,292resultp2);293break;294}295if (Is_inexacttrap_enabled()) {296Dbl_copytoptr(resultp1,resultp2,dstptr);297return(INEXACTEXCEPTION);298}299else Set_inexactflag();300}301Dbl_copytoptr(resultp1,resultp2,dstptr);302return(NOEXCEPTION);303}304305306307