Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/fcnvfxt.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/fcnvfxt.c $Revision: 1.1 $
13
*
14
* Purpose:
15
* Single Floating-point to Single Fixed-point /w truncated result
16
* Single Floating-point to Double Fixed-point /w truncated result
17
* Double Floating-point to Single Fixed-point /w truncated result
18
* Double Floating-point to Double Fixed-point /w truncated result
19
*
20
* External Interfaces:
21
* dbl_to_dbl_fcnvfxt(srcptr,_nullptr,dstptr,status)
22
* dbl_to_sgl_fcnvfxt(srcptr,_nullptr,dstptr,status)
23
* sgl_to_dbl_fcnvfxt(srcptr,_nullptr,dstptr,status)
24
* sgl_to_sgl_fcnvfxt(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 floating-point to single fixed-point format
42
* with truncated result
43
*/
44
/*ARGSUSED*/
45
int
46
sgl_to_sgl_fcnvfxt(
47
sgl_floating_point *srcptr,
48
unsigned int *_nullptr,
49
int *dstptr,
50
unsigned int *status)
51
{
52
register unsigned int src, temp;
53
register int src_exponent, result;
54
55
src = *srcptr;
56
src_exponent = Sgl_exponent(src) - SGL_BIAS;
57
58
/*
59
* Test for overflow
60
*/
61
if (src_exponent > SGL_FX_MAX_EXP) {
62
/* check for MININT */
63
if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
64
Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
65
if (Sgl_iszero_sign(src)) result = 0x7fffffff;
66
else result = 0x80000000;
67
68
if (Is_invalidtrap_enabled()) {
69
return(INVALIDEXCEPTION);
70
}
71
Set_invalidflag();
72
*dstptr = result;
73
return(NOEXCEPTION);
74
}
75
}
76
/*
77
* Generate result
78
*/
79
if (src_exponent >= 0) {
80
temp = src;
81
Sgl_clear_signexponent_set_hidden(temp);
82
Int_from_sgl_mantissa(temp,src_exponent);
83
if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
84
else result = Sgl_all(temp);
85
*dstptr = result;
86
87
/* check for inexact */
88
if (Sgl_isinexact_to_fix(src,src_exponent)) {
89
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
90
else Set_inexactflag();
91
}
92
}
93
else {
94
*dstptr = 0;
95
96
/* check for inexact */
97
if (Sgl_isnotzero_exponentmantissa(src)) {
98
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
99
else Set_inexactflag();
100
}
101
}
102
return(NOEXCEPTION);
103
}
104
105
/*
106
* Single Floating-point to Double Fixed-point
107
*/
108
/*ARGSUSED*/
109
int
110
sgl_to_dbl_fcnvfxt(
111
sgl_floating_point *srcptr,
112
unsigned int *_nullptr,
113
dbl_integer *dstptr,
114
unsigned int *status)
115
{
116
register int src_exponent, resultp1;
117
register unsigned int src, temp, resultp2;
118
119
src = *srcptr;
120
src_exponent = Sgl_exponent(src) - SGL_BIAS;
121
122
/*
123
* Test for overflow
124
*/
125
if (src_exponent > DBL_FX_MAX_EXP) {
126
/* check for MININT */
127
if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
128
Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
129
if (Sgl_iszero_sign(src)) {
130
resultp1 = 0x7fffffff;
131
resultp2 = 0xffffffff;
132
}
133
else {
134
resultp1 = 0x80000000;
135
resultp2 = 0;
136
}
137
if (Is_invalidtrap_enabled()) {
138
return(INVALIDEXCEPTION);
139
}
140
Set_invalidflag();
141
Dint_copytoptr(resultp1,resultp2,dstptr);
142
return(NOEXCEPTION);
143
}
144
Dint_set_minint(resultp1,resultp2);
145
Dint_copytoptr(resultp1,resultp2,dstptr);
146
return(NOEXCEPTION);
147
}
148
/*
149
* Generate result
150
*/
151
if (src_exponent >= 0) {
152
temp = src;
153
Sgl_clear_signexponent_set_hidden(temp);
154
Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
155
if (Sgl_isone_sign(src)) {
156
Dint_setone_sign(resultp1,resultp2);
157
}
158
Dint_copytoptr(resultp1,resultp2,dstptr);
159
160
/* check for inexact */
161
if (Sgl_isinexact_to_fix(src,src_exponent)) {
162
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
163
else Set_inexactflag();
164
}
165
}
166
else {
167
Dint_setzero(resultp1,resultp2);
168
Dint_copytoptr(resultp1,resultp2,dstptr);
169
170
/* check for inexact */
171
if (Sgl_isnotzero_exponentmantissa(src)) {
172
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
173
else Set_inexactflag();
174
}
175
}
176
return(NOEXCEPTION);
177
}
178
179
/*
180
* Double Floating-point to Single Fixed-point
181
*/
182
/*ARGSUSED*/
183
int
184
dbl_to_sgl_fcnvfxt(
185
dbl_floating_point *srcptr,
186
unsigned int *_nullptr,
187
int *dstptr,
188
unsigned int *status)
189
{
190
register unsigned int srcp1, srcp2, tempp1, tempp2;
191
register int src_exponent, result;
192
193
Dbl_copyfromptr(srcptr,srcp1,srcp2);
194
src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
195
196
/*
197
* Test for overflow
198
*/
199
if (src_exponent > SGL_FX_MAX_EXP) {
200
/* check for MININT */
201
if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
202
if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
203
else result = 0x80000000;
204
205
if (Is_invalidtrap_enabled()) {
206
return(INVALIDEXCEPTION);
207
}
208
Set_invalidflag();
209
*dstptr = result;
210
return(NOEXCEPTION);
211
}
212
}
213
/*
214
* Generate result
215
*/
216
if (src_exponent >= 0) {
217
tempp1 = srcp1;
218
tempp2 = srcp2;
219
Dbl_clear_signexponent_set_hidden(tempp1);
220
Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
221
if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
222
result = -Dbl_allp1(tempp1);
223
else result = Dbl_allp1(tempp1);
224
*dstptr = result;
225
226
/* check for inexact */
227
if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
228
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
229
else Set_inexactflag();
230
}
231
}
232
else {
233
*dstptr = 0;
234
235
/* check for inexact */
236
if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
237
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
238
else Set_inexactflag();
239
}
240
}
241
return(NOEXCEPTION);
242
}
243
244
/*
245
* Double Floating-point to Double Fixed-point
246
*/
247
/*ARGSUSED*/
248
int
249
dbl_to_dbl_fcnvfxt(
250
dbl_floating_point *srcptr,
251
unsigned int *_nullptr,
252
dbl_integer *dstptr,
253
unsigned int *status)
254
{
255
register int src_exponent, resultp1;
256
register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
257
258
Dbl_copyfromptr(srcptr,srcp1,srcp2);
259
src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
260
261
/*
262
* Test for overflow
263
*/
264
if (src_exponent > DBL_FX_MAX_EXP) {
265
/* check for MININT */
266
if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
267
Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
268
if (Dbl_iszero_sign(srcp1)) {
269
resultp1 = 0x7fffffff;
270
resultp2 = 0xffffffff;
271
}
272
else {
273
resultp1 = 0x80000000;
274
resultp2 = 0;
275
}
276
if (Is_invalidtrap_enabled()) {
277
return(INVALIDEXCEPTION);
278
}
279
Set_invalidflag();
280
Dint_copytoptr(resultp1,resultp2,dstptr);
281
return(NOEXCEPTION);
282
}
283
}
284
/*
285
* Generate result
286
*/
287
if (src_exponent >= 0) {
288
tempp1 = srcp1;
289
tempp2 = srcp2;
290
Dbl_clear_signexponent_set_hidden(tempp1);
291
Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
292
resultp1,resultp2);
293
if (Dbl_isone_sign(srcp1)) {
294
Dint_setone_sign(resultp1,resultp2);
295
}
296
Dint_copytoptr(resultp1,resultp2,dstptr);
297
298
/* check for inexact */
299
if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
300
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
301
else Set_inexactflag();
302
}
303
}
304
else {
305
Dint_setzero(resultp1,resultp2);
306
Dint_copytoptr(resultp1,resultp2,dstptr);
307
308
/* check for inexact */
309
if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
310
if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
311
else Set_inexactflag();
312
}
313
}
314
return(NOEXCEPTION);
315
}
316
317