File Index
Files and directories
Sign in
FILE

fcnvuf.c

File preview with syntax highlighting.

linux-6.19.14/arch/parisc/math-emu/fcnvuf.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  4 *
  5 * Floating-point emulation code
  6 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  7 */
  8/*
  9 * BEGIN_DESC
 10 *
 11 *  File:
 12 *	@(#)	pa/spmath/fcnvuf.c		$Revision: 1.1 $
 13 *
 14 *  Purpose:
 15 *	Fixed point to Floating-point Converts
 16 *
 17 *  External Interfaces:
 18 *	dbl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)
 19 *	dbl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)
 20 *	sgl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)
 21 *	sgl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)
 22 *
 23 *  Internal Interfaces:
 24 *
 25 *  Theory:
 26 *	<<please update with a overview of the operation of this file>>
 27 *
 28 * END_DESC
 29*/
 30
 31
 32#include "float.h"
 33#include "sgl_float.h"
 34#include "dbl_float.h"
 35#include "cnv_float.h"
 36
 37/************************************************************************
 38 *  Fixed point to Floating-point Converts				*
 39 ************************************************************************/
 40
 41/*
 42 *  Convert Single Unsigned Fixed to Single Floating-point format
 43 */
 44
 45int
 46sgl_to_sgl_fcnvuf(
 47			unsigned int *srcptr,
 48			unsigned int *_nullptr,
 49			sgl_floating_point *dstptr,
 50			unsigned int *status)
 51{
 52	register unsigned int src, result = 0;
 53	register int dst_exponent;
 54
 55	src = *srcptr;
 56
 57	/* Check for zero */ 
 58	if (src == 0) { 
 59	       	Sgl_setzero(result); 
 60		*dstptr = result;
 61	       	return(NOEXCEPTION); 
 62	} 
 63	/*
 64	 * Generate exponent and normalized mantissa
 65	 */
 66	dst_exponent = 16;    /* initialize for normalization */
 67	/*
 68	 * Check word for most significant bit set.  Returns
 69	 * a value in dst_exponent indicating the bit position,
 70	 * between -1 and 30.
 71	 */
 72	Find_ms_one_bit(src,dst_exponent);
 73	/*  left justify source, with msb at bit position 0  */
 74	src <<= dst_exponent+1;
 75	Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);
 76	Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
 77
 78	/* check for inexact */
 79	if (Suint_isinexact_to_sgl(src)) {
 80		switch (Rounding_mode()) {
 81			case ROUNDPLUS: 
 82				Sgl_increment(result);
 83				break;
 84			case ROUNDMINUS: /* never negative */
 85				break;
 86			case ROUNDNEAREST:
 87				Sgl_roundnearest_from_suint(src,result);
 88				break;
 89		}
 90		if (Is_inexacttrap_enabled()) {
 91			*dstptr = result;
 92			return(INEXACTEXCEPTION);
 93		}
 94		else Set_inexactflag();
 95	}
 96	*dstptr = result;
 97	return(NOEXCEPTION);
 98}
 99
100/*
101 *  Single Unsigned Fixed to Double Floating-point 
102 */
103
104int
105sgl_to_dbl_fcnvuf(
106			unsigned int *srcptr,
107			unsigned int *_nullptr,
108			dbl_floating_point *dstptr,
109			unsigned int *status)
110{
111	register int dst_exponent;
112	register unsigned int src, resultp1 = 0, resultp2 = 0;
113
114	src = *srcptr;
115
116	/* Check for zero */
117	if (src == 0) {
118	       	Dbl_setzero(resultp1,resultp2);
119	       	Dbl_copytoptr(resultp1,resultp2,dstptr);
120	       	return(NOEXCEPTION);
121	}
122	/*
123	 * Generate exponent and normalized mantissa
124	 */
125	dst_exponent = 16;    /* initialize for normalization */
126	/*
127	 * Check word for most significant bit set.  Returns
128	 * a value in dst_exponent indicating the bit position,
129	 * between -1 and 30.
130	 */
131	Find_ms_one_bit(src,dst_exponent);
132	/*  left justify source, with msb at bit position 0  */
133	src <<= dst_exponent+1;
134	Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);
135	Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));
136	Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
137	Dbl_copytoptr(resultp1,resultp2,dstptr);
138	return(NOEXCEPTION);
139}
140
141/*
142 *  Double Unsigned Fixed to Single Floating-point 
143 */
144
145int
146dbl_to_sgl_fcnvuf(
147			dbl_unsigned *srcptr,
148			unsigned int *_nullptr,
149			sgl_floating_point *dstptr,
150			unsigned int *status)
151{
152	int dst_exponent;
153	unsigned int srcp1, srcp2, result = 0;
154
155	Duint_copyfromptr(srcptr,srcp1,srcp2);
156
157	/* Check for zero */
158	if (srcp1 == 0 && srcp2 == 0) {
159	       	Sgl_setzero(result);
160	       	*dstptr = result;
161	       	return(NOEXCEPTION);
162	}
163	/*
164	 * Generate exponent and normalized mantissa
165	 */
166	dst_exponent = 16;    /* initialize for normalization */
167	if (srcp1 == 0) {
168		/*
169		 * Check word for most significant bit set.  Returns
170		 * a value in dst_exponent indicating the bit position,
171		 * between -1 and 30.
172		 */
173		Find_ms_one_bit(srcp2,dst_exponent);
174		/*  left justify source, with msb at bit position 0  */
175		srcp1 = srcp2 << dst_exponent+1;    
176		srcp2 = 0;
177		/*
178		 *  since msb set is in second word, need to 
179		 *  adjust bit position count
180		 */
181		dst_exponent += 32;
182	}
183	else {
184		/*
185		 * Check word for most significant bit set.  Returns
186		 * a value in dst_exponent indicating the bit position,
187		 * between -1 and 30.
188		 *
189		 */
190		Find_ms_one_bit(srcp1,dst_exponent);
191		/*  left justify source, with msb at bit position 0  */
192		if (dst_exponent >= 0) {
193			Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
194			 srcp1); 
195			srcp2 <<= dst_exponent+1;
196		}
197	}
198	Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);
199	Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
200
201	/* check for inexact */
202	if (Duint_isinexact_to_sgl(srcp1,srcp2)) {
203		switch (Rounding_mode()) {
204			case ROUNDPLUS: 
205				Sgl_increment(result);
206				break;
207			case ROUNDMINUS: /* never negative */
208				break;
209			case ROUNDNEAREST:
210				Sgl_roundnearest_from_duint(srcp1,srcp2,result);
211				break;
212		}
213		if (Is_inexacttrap_enabled()) {
214			*dstptr = result;
215			return(INEXACTEXCEPTION);
216		}
217		else Set_inexactflag();
218	}
219	*dstptr = result;
220	return(NOEXCEPTION);
221}
222
223/*
224 *  Double Unsigned Fixed to Double Floating-point 
225 */
226
227int
228dbl_to_dbl_fcnvuf(
229		    dbl_unsigned *srcptr,
230		    unsigned int *_nullptr,
231		    dbl_floating_point *dstptr,
232		    unsigned int *status)
233{
234	register int dst_exponent;
235	register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;
236
237	Duint_copyfromptr(srcptr,srcp1,srcp2);
238
239	/* Check for zero */
240	if (srcp1 == 0 && srcp2 ==0) {
241	       	Dbl_setzero(resultp1,resultp2);
242	       	Dbl_copytoptr(resultp1,resultp2,dstptr);
243	       	return(NOEXCEPTION);
244	}
245	/*
246	 * Generate exponent and normalized mantissa
247	 */
248	dst_exponent = 16;    /* initialize for normalization */
249	if (srcp1 == 0) {
250		/*
251		 * Check word for most significant bit set.  Returns
252		 * a value in dst_exponent indicating the bit position,
253		 * between -1 and 30.
254		 */
255		Find_ms_one_bit(srcp2,dst_exponent);
256		/*  left justify source, with msb at bit position 0  */
257		srcp1 = srcp2 << dst_exponent+1;
258		srcp2 = 0;
259		/*
260		 *  since msb set is in second word, need to 
261		 *  adjust bit position count
262		 */
263		dst_exponent += 32;
264	}
265	else {
266		/*
267		 * Check word for most significant bit set.  Returns
268		 * a value in dst_exponent indicating the bit position,
269		 * between -1 and 30.
270		 */
271		Find_ms_one_bit(srcp1,dst_exponent);
272		/*  left justify source, with msb at bit position 0  */
273		if (dst_exponent >= 0) {
274			Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
275			 srcp1); 
276			srcp2 <<= dst_exponent+1;
277		}
278	}
279	Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);
280	Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);
281	Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
282
283	/* check for inexact */
284	if (Duint_isinexact_to_dbl(srcp2)) {
285		switch (Rounding_mode()) {
286			case ROUNDPLUS: 
287				Dbl_increment(resultp1,resultp2);
288				break;
289			case ROUNDMINUS: /* never negative */
290				break;
291			case ROUNDNEAREST:
292				Dbl_roundnearest_from_duint(srcp2,resultp1,
293				resultp2);
294				break;
295		}
296		if (Is_inexacttrap_enabled()) {
297			Dbl_copytoptr(resultp1,resultp2,dstptr);
298			return(INEXACTEXCEPTION);
299		}
300		else Set_inexactflag();
301	}
302	Dbl_copytoptr(resultp1,resultp2,dstptr);
303	return(NOEXCEPTION);
304}
305
~/ Read-only file preview.