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