Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/fcnvxf.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/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
44
int
45
sgl_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
115
int
116
sgl_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
166
int
167
dbl_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
271
int
272
dbl_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
}
374
375