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