File Index
Files and directories
Sign in
FILE

fcnvxf.c

File preview with syntax highlighting.

linux-6.19.14/arch/parisc/math-emu/fcnvxf.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/fcnvxf.c		$Revision: 1.1 $
 13 *
 14 *  Purpose:
 15 *	Single Fixed-point to Single Floating-point
 16 *	Single Fixed-point to Double Floating-point 
 17 *	Double Fixed-point to Single Floating-point 
 18 *	Double Fixed-point to Double Floating-point 
 19 *
 20 *  External Interfaces:
 21 *	dbl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
 22 *	dbl_to_sgl_fcnvxf(srcptr,_nullptr,dstptr,status)
 23 *	sgl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
 24 *	sgl_to_sgl_fcnvxf(srcptr,_nullptr,dstptr,status)
 25 *
 26 *  Internal Interfaces:
 27 *
 28 *  Theory:
 29 *	<<please update with a overview of the operation of this file>>
 30 *
 31 * END_DESC
 32*/
 33
 34
 35#include "float.h"
 36#include "sgl_float.h"
 37#include "dbl_float.h"
 38#include "cnv_float.h"
 39
 40/*
 41 *  Convert single fixed-point to single floating-point format
 42 */
 43
 44int
 45sgl_to_sgl_fcnvxf(
 46		    int *srcptr,
 47		    unsigned int *_nullptr,
 48		    sgl_floating_point *dstptr,
 49		    unsigned int *status)
 50{
 51	register int src, dst_exponent;
 52	register unsigned int result = 0;
 53
 54	src = *srcptr;
 55	/* 
 56	 * set sign bit of result and get magnitude of source 
 57	 */
 58	if (src < 0) {
 59		Sgl_setone_sign(result);  
 60		Int_negate(src);
 61	}
 62	else {
 63		Sgl_setzero_sign(result);
 64        	/* Check for zero */ 
 65        	if (src == 0) { 
 66                	Sgl_setzero(result); 
 67			*dstptr = result;
 68                	return(NOEXCEPTION); 
 69        	} 
 70	}
 71	/*
 72	 * Generate exponent and normalized mantissa
 73	 */
 74	dst_exponent = 16;    /* initialize for normalization */
 75	/*
 76	 * Check word for most significant bit set.  Returns
 77	 * a value in dst_exponent indicating the bit position,
 78	 * between -1 and 30.
 79	 */
 80	Find_ms_one_bit(src,dst_exponent);
 81	/*  left justify source, with msb at bit position 1  */
 82	if (dst_exponent >= 0) src <<= dst_exponent;
 83	else src = 1 << 30;
 84	Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
 85	Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
 86
 87	/* check for inexact */
 88	if (Int_isinexact_to_sgl(src)) {
 89		switch (Rounding_mode()) {
 90			case ROUNDPLUS: 
 91				if (Sgl_iszero_sign(result)) 
 92					Sgl_increment(result);
 93				break;
 94			case ROUNDMINUS: 
 95				if (Sgl_isone_sign(result)) 
 96					Sgl_increment(result);
 97				break;
 98			case ROUNDNEAREST:
 99				Sgl_roundnearest_from_int(src,result);
100		}
101		if (Is_inexacttrap_enabled()) {
102			*dstptr = result;
103			return(INEXACTEXCEPTION);
104		}
105		else Set_inexactflag();
106	}
107	*dstptr = result;
108	return(NOEXCEPTION);
109}
110
111/*
112 *  Single Fixed-point to Double Floating-point 
113 */
114
115int
116sgl_to_dbl_fcnvxf(
117		    int *srcptr,
118		    unsigned int *_nullptr,
119		    dbl_floating_point *dstptr,
120		    unsigned int *status)
121{
122	register int src, dst_exponent;
123	register unsigned int resultp1 = 0, resultp2 = 0;
124
125	src = *srcptr;
126	/* 
127	 * set sign bit of result and get magnitude of source 
128	 */
129	if (src < 0) {
130		Dbl_setone_sign(resultp1);  
131		Int_negate(src);
132	}
133	else {
134		Dbl_setzero_sign(resultp1);
135        	/* Check for zero */
136        	if (src == 0) {
137                	Dbl_setzero(resultp1,resultp2);
138                	Dbl_copytoptr(resultp1,resultp2,dstptr);
139                	return(NOEXCEPTION);
140        	}
141	}
142	/*
143	 * Generate exponent and normalized mantissa
144	 */
145	dst_exponent = 16;    /* initialize for normalization */
146	/*
147	 * Check word for most significant bit set.  Returns
148	 * a value in dst_exponent indicating the bit position,
149	 * between -1 and 30.
150	 */
151	Find_ms_one_bit(src,dst_exponent);
152	/*  left justify source, with msb at bit position 1  */
153	if (dst_exponent >= 0) src <<= dst_exponent;
154	else src = 1 << 30;
155	Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
156	Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
157	Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
158	Dbl_copytoptr(resultp1,resultp2,dstptr);
159	return(NOEXCEPTION);
160}
161
162/*
163 *  Double Fixed-point to Single Floating-point 
164 */
165
166int
167dbl_to_sgl_fcnvxf(
168			dbl_integer *srcptr,
169			unsigned int *_nullptr,
170			sgl_floating_point *dstptr,
171			unsigned int *status)
172{
173	int dst_exponent, srcp1;
174	unsigned int result = 0, srcp2;
175
176	Dint_copyfromptr(srcptr,srcp1,srcp2);
177	/* 
178	 * set sign bit of result and get magnitude of source 
179	 */
180	if (srcp1 < 0) {
181		Sgl_setone_sign(result);  
182		Dint_negate(srcp1,srcp2);
183	}
184	else {
185		Sgl_setzero_sign(result);
186        	/* Check for zero */
187        	if (srcp1 == 0 && srcp2 == 0) {
188                	Sgl_setzero(result);
189                	*dstptr = result;
190                	return(NOEXCEPTION);
191		}
192        }
193	/*
194	 * Generate exponent and normalized mantissa
195	 */
196	dst_exponent = 16;    /* initialize for normalization */
197	if (srcp1 == 0) {
198		/*
199		 * Check word for most significant bit set.  Returns
200		 * a value in dst_exponent indicating the bit position,
201		 * between -1 and 30.
202		 */
203		Find_ms_one_bit(srcp2,dst_exponent);
204		/*  left justify source, with msb at bit position 1  */
205		if (dst_exponent >= 0) {
206			srcp1 = srcp2 << dst_exponent;    
207			srcp2 = 0;
208		}
209		else {
210			srcp1 = srcp2 >> 1;
211			srcp2 <<= 31; 
212		}
213		/*
214		 *  since msb set is in second word, need to 
215		 *  adjust bit position count
216		 */
217		dst_exponent += 32;
218	}
219	else {
220		/*
221		 * Check word for most significant bit set.  Returns
222		 * a value in dst_exponent indicating the bit position,
223		 * between -1 and 30.
224		 *
225		 */
226		Find_ms_one_bit(srcp1,dst_exponent);
227		/*  left justify source, with msb at bit position 1  */
228		if (dst_exponent > 0) {
229			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
230			 srcp1); 
231			srcp2 <<= dst_exponent;
232		}
233		/*
234		 * If dst_exponent = 0, we don't need to shift anything.
235		 * If dst_exponent = -1, src = - 2**63 so we won't need to 
236		 * shift srcp2.
237		 */
238		else srcp1 >>= -(dst_exponent);
239	}
240	Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
241	Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
242
243	/* check for inexact */
244	if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
245		switch (Rounding_mode()) {
246			case ROUNDPLUS: 
247				if (Sgl_iszero_sign(result)) 
248					Sgl_increment(result);
249				break;
250			case ROUNDMINUS: 
251				if (Sgl_isone_sign(result)) 
252					Sgl_increment(result);
253				break;
254			case ROUNDNEAREST:
255				Sgl_roundnearest_from_dint(srcp1,srcp2,result);
256		}
257		if (Is_inexacttrap_enabled()) {
258			*dstptr = result;
259			return(INEXACTEXCEPTION);
260		}
261		else Set_inexactflag();
262	}
263	*dstptr = result;
264	return(NOEXCEPTION);
265}
266
267/*
268 *  Double Fixed-point to Double Floating-point 
269 */
270
271int
272dbl_to_dbl_fcnvxf(
273		    dbl_integer *srcptr,
274		    unsigned int *_nullptr,
275		    dbl_floating_point *dstptr,
276		    unsigned int *status)
277{
278	register int srcp1, dst_exponent;
279	register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
280
281	Dint_copyfromptr(srcptr,srcp1,srcp2);
282	/* 
283	 * set sign bit of result and get magnitude of source 
284	 */
285	if (srcp1 < 0) {
286		Dbl_setone_sign(resultp1);
287		Dint_negate(srcp1,srcp2);
288	}
289	else {
290		Dbl_setzero_sign(resultp1);
291        	/* Check for zero */
292        	if (srcp1 == 0 && srcp2 ==0) {
293                	Dbl_setzero(resultp1,resultp2);
294                	Dbl_copytoptr(resultp1,resultp2,dstptr);
295                	return(NOEXCEPTION);
296		}
297        }
298	/*
299	 * Generate exponent and normalized mantissa
300	 */
301	dst_exponent = 16;    /* initialize for normalization */
302	if (srcp1 == 0) {
303		/*
304		 * Check word for most significant bit set.  Returns
305		 * a value in dst_exponent indicating the bit position,
306		 * between -1 and 30.
307		 */
308		Find_ms_one_bit(srcp2,dst_exponent);
309		/*  left justify source, with msb at bit position 1  */
310		if (dst_exponent >= 0) {
311			srcp1 = srcp2 << dst_exponent;    
312			srcp2 = 0;
313		}
314		else {
315			srcp1 = srcp2 >> 1;
316			srcp2 <<= 31;
317		}
318		/*
319		 *  since msb set is in second word, need to 
320		 *  adjust bit position count
321		 */
322		dst_exponent += 32;
323	}
324	else {
325		/*
326		 * Check word for most significant bit set.  Returns
327		 * a value in dst_exponent indicating the bit position,
328		 * between -1 and 30.
329		 */
330		Find_ms_one_bit(srcp1,dst_exponent);
331		/*  left justify source, with msb at bit position 1  */
332		if (dst_exponent > 0) {
333			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
334			 srcp1); 
335			srcp2 <<= dst_exponent;
336		}
337		/*
338		 * If dst_exponent = 0, we don't need to shift anything.
339		 * If dst_exponent = -1, src = - 2**63 so we won't need to 
340		 * shift srcp2.
341		 */
342		else srcp1 >>= -(dst_exponent);
343	}
344	Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
345	Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
346	Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
347
348	/* check for inexact */
349	if (Dint_isinexact_to_dbl(srcp2)) {
350		switch (Rounding_mode()) {
351			case ROUNDPLUS: 
352				if (Dbl_iszero_sign(resultp1)) {
353					Dbl_increment(resultp1,resultp2);
354				}
355				break;
356			case ROUNDMINUS: 
357				if (Dbl_isone_sign(resultp1)) {
358					Dbl_increment(resultp1,resultp2);
359				}
360				break;
361			case ROUNDNEAREST:
362				Dbl_roundnearest_from_dint(srcp2,resultp1,
363				resultp2);
364		}
365		if (Is_inexacttrap_enabled()) {
366			Dbl_copytoptr(resultp1,resultp2,dstptr);
367			return(INEXACTEXCEPTION);
368		}
369		else Set_inexactflag();
370	}
371	Dbl_copytoptr(resultp1,resultp2,dstptr);
372	return(NOEXCEPTION);
373}
~/ Read-only file preview.