Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/fcnvuf.c
26288 views
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) <[email protected]>
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
45
int
46
sgl_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
104
int
105
sgl_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
145
int
146
dbl_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
227
int
228
dbl_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
306
307