Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/cnv_float.h
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
#ifdef __NO_PA_HDRS
10
PA header file -- do not include this header file for non-PA builds.
11
#endif
12
13
/*
14
* Some more constants
15
*/
16
#define SGL_FX_MAX_EXP 30
17
#define DBL_FX_MAX_EXP 62
18
#define QUAD_FX_MAX_EXP 126
19
20
#define Dintp1(object) (object)
21
#define Dintp2(object) (object)
22
23
#define Duintp1(object) (object)
24
#define Duintp2(object) (object)
25
26
#define Qintp0(object) (object)
27
#define Qintp1(object) (object)
28
#define Qintp2(object) (object)
29
#define Qintp3(object) (object)
30
31
32
/*
33
* These macros will be used specifically by the convert instructions.
34
*
35
*
36
* Single format macros
37
*/
38
39
#define Sgl_to_dbl_exponent(src_exponent,dest) \
40
Deposit_dexponent(dest,src_exponent+(DBL_BIAS-SGL_BIAS))
41
42
#define Sgl_to_dbl_mantissa(src_mantissa,destA,destB) \
43
Deposit_dmantissap1(destA,src_mantissa>>3); \
44
Dmantissap2(destB) = src_mantissa << 29
45
46
#define Sgl_isinexact_to_fix(sgl_value,exponent) \
47
((exponent < (SGL_P - 1)) ? \
48
(Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
49
50
#define Int_isinexact_to_sgl(int_value) ((int_value << 33 - SGL_EXP_LENGTH) != 0)
51
52
#define Sgl_roundnearest_from_int(int_value,sgl_value) \
53
if (int_value & 1<<(SGL_EXP_LENGTH - 2)) /* round bit */ \
54
if (((int_value << 34 - SGL_EXP_LENGTH) != 0) || Slow(sgl_value)) \
55
Sall(sgl_value)++
56
57
#define Dint_isinexact_to_sgl(dint_valueA,dint_valueB) \
58
(((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) != 0) || Dintp2(dint_valueB))
59
60
#define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value) \
61
if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2)) \
62
if (((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) != 0) || \
63
Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
64
65
#define Dint_isinexact_to_dbl(dint_value) \
66
(Dintp2(dint_value) << 33 - DBL_EXP_LENGTH)
67
68
#define Dbl_roundnearest_from_dint(dint_opndB,dbl_opndA,dbl_opndB) \
69
if (Dintp2(dint_opndB) & 1<<(DBL_EXP_LENGTH - 2)) \
70
if ((Dintp2(dint_opndB) << 34 - DBL_EXP_LENGTH) || Dlowp2(dbl_opndB)) \
71
if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
72
73
#define Sgl_isone_roundbit(sgl_value,exponent) \
74
((Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) >> 31)
75
76
#define Sgl_isone_stickybit(sgl_value,exponent) \
77
(exponent < (SGL_P - 2) ? \
78
Sall(sgl_value) << (SGL_EXP_LENGTH + 2 + exponent) : FALSE)
79
80
81
/*
82
* Double format macros
83
*/
84
85
#define Dbl_to_sgl_exponent(src_exponent,dest) \
86
dest = src_exponent + (SGL_BIAS - DBL_BIAS)
87
88
#define Dbl_to_sgl_mantissa(srcA,srcB,dest,inexact,guard,sticky,odd) \
89
Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \
90
guard = Dbit3p2(srcB); \
91
sticky = Dallp2(srcB)<<4; \
92
inexact = guard | sticky; \
93
odd = Dbit2p2(srcB)
94
95
#define Dbl_to_sgl_denormalized(srcA,srcB,exp,dest,inexact,guard,sticky,odd,tiny) \
96
Deposit_dexponent(srcA,1); \
97
tiny = TRUE; \
98
if (exp >= -2) { \
99
if (exp == 0) { \
100
inexact = Dallp2(srcB) << 3; \
101
guard = inexact >> 31; \
102
sticky = inexact << 1; \
103
Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest); \
104
odd = dest << 31; \
105
if (inexact) { \
106
switch(Rounding_mode()) { \
107
case ROUNDPLUS: \
108
if (Dbl_iszero_sign(srcA)) { \
109
dest++; \
110
if (Sgl_isone_hidden(dest)) \
111
tiny = FALSE; \
112
dest--; \
113
} \
114
break; \
115
case ROUNDMINUS: \
116
if (Dbl_isone_sign(srcA)) { \
117
dest++; \
118
if (Sgl_isone_hidden(dest)) \
119
tiny = FALSE; \
120
dest--; \
121
} \
122
break; \
123
case ROUNDNEAREST: \
124
if (guard && (sticky || odd)) { \
125
dest++; \
126
if (Sgl_isone_hidden(dest)) \
127
tiny = FALSE; \
128
dest--; \
129
} \
130
break; \
131
} \
132
} \
133
/* shift right by one to get correct result */ \
134
guard = odd; \
135
sticky = inexact; \
136
inexact |= guard; \
137
dest >>= 1; \
138
Deposit_dsign(srcA,0); \
139
Shiftdouble(Dallp1(srcA),Dallp2(srcB),30,dest); \
140
odd = dest << 31; \
141
} \
142
else { \
143
inexact = Dallp2(srcB) << (2 + exp); \
144
guard = inexact >> 31; \
145
sticky = inexact << 1; \
146
Deposit_dsign(srcA,0); \
147
if (exp == -2) dest = Dallp1(srcA); \
148
else Variable_shift_double(Dallp1(srcA),Dallp2(srcB),30-exp,dest); \
149
odd = dest << 31; \
150
} \
151
} \
152
else { \
153
Deposit_dsign(srcA,0); \
154
if (exp > (1 - SGL_P)) { \
155
dest = Dallp1(srcA) >> (- 2 - exp); \
156
inexact = Dallp1(srcA) << (34 + exp); \
157
guard = inexact >> 31; \
158
sticky = (inexact << 1) | Dallp2(srcB); \
159
inexact |= Dallp2(srcB); \
160
odd = dest << 31; \
161
} \
162
else { \
163
dest = 0; \
164
inexact = Dallp1(srcA) | Dallp2(srcB); \
165
if (exp == (1 - SGL_P)) { \
166
guard = Dhidden(srcA); \
167
sticky = Dmantissap1(srcA) | Dallp2(srcB); \
168
} \
169
else { \
170
guard = 0; \
171
sticky = inexact; \
172
} \
173
odd = 0; \
174
} \
175
} \
176
exp = 0
177
178
#define Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent) \
179
(exponent < (DBL_P-33) ? \
180
Dallp2(dbl_valueB) || Dallp1(dbl_valueA) << (DBL_EXP_LENGTH+1+exponent) : \
181
(exponent < (DBL_P-1) ? Dallp2(dbl_valueB) << (exponent + (33-DBL_P)) : \
182
FALSE))
183
184
#define Dbl_isoverflow_to_int(exponent,dbl_valueA,dbl_valueB) \
185
((exponent > SGL_FX_MAX_EXP + 1) || Dsign(dbl_valueA)==0 || \
186
Dmantissap1(dbl_valueA)!=0 || (Dallp2(dbl_valueB)>>21)!=0 )
187
188
#define Dbl_isone_roundbit(dbl_valueA,dbl_valueB,exponent) \
189
((exponent < (DBL_P - 33) ? \
190
Dallp1(dbl_valueA) >> ((30 - DBL_EXP_LENGTH) - exponent) : \
191
Dallp2(dbl_valueB) >> ((DBL_P - 2) - exponent)) & 1)
192
193
#define Dbl_isone_stickybit(dbl_valueA,dbl_valueB,exponent) \
194
(exponent < (DBL_P-34) ? \
195
(Dallp2(dbl_valueB) || Dallp1(dbl_valueA)<<(DBL_EXP_LENGTH+2+exponent)) : \
196
(exponent<(DBL_P-2) ? (Dallp2(dbl_valueB) << (exponent + (34-DBL_P))) : \
197
FALSE))
198
199
200
/* Int macros */
201
202
#define Int_from_sgl_mantissa(sgl_value,exponent) \
203
Sall(sgl_value) = \
204
(unsigned)(Sall(sgl_value) << SGL_EXP_LENGTH)>>(31 - exponent)
205
206
#define Int_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent) \
207
Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),22,Dallp1(dbl_valueA)); \
208
if (exponent < 31) Dallp1(dbl_valueA) >>= 30 - exponent; \
209
else Dallp1(dbl_valueA) <<= 1
210
211
#define Int_negate(int_value) int_value = -int_value
212
213
214
/* Dint macros */
215
216
#define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
217
{Sall(sgl_value) <<= SGL_EXP_LENGTH; /* left-justify */ \
218
if (exponent <= 31) { \
219
Dintp1(dresultA) = 0; \
220
Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \
221
} \
222
else { \
223
Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent); \
224
Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31); \
225
}}
226
227
228
#define Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
229
{if (exponent < 32) { \
230
Dintp1(destA) = 0; \
231
if (exponent <= 20) \
232
Dintp2(destB) = Dallp1(dbl_valueA) >> 20-exponent; \
233
else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
234
52-exponent,Dintp2(destB)); \
235
} \
236
else { \
237
if (exponent <= 52) { \
238
Dintp1(destA) = Dallp1(dbl_valueA) >> 52-exponent; \
239
if (exponent == 52) Dintp2(destB) = Dallp2(dbl_valueB); \
240
else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
241
52-exponent,Dintp2(destB)); \
242
} \
243
else { \
244
Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
245
84-exponent,Dintp1(destA)); \
246
Dintp2(destB) = Dallp2(dbl_valueB) << exponent-52; \
247
} \
248
}}
249
250
#define Dint_setzero(dresultA,dresultB) \
251
Dintp1(dresultA) = 0; \
252
Dintp2(dresultB) = 0
253
254
#define Dint_setone_sign(dresultA,dresultB) \
255
Dintp1(dresultA) = ~Dintp1(dresultA); \
256
if ((Dintp2(dresultB) = -Dintp2(dresultB)) == 0) Dintp1(dresultA)++
257
258
#define Dint_set_minint(dresultA,dresultB) \
259
Dintp1(dresultA) = (unsigned int)1<<31; \
260
Dintp2(dresultB) = 0
261
262
#define Dint_isone_lowp2(dresultB) (Dintp2(dresultB) & 01)
263
264
#define Dint_increment(dresultA,dresultB) \
265
if ((++Dintp2(dresultB))==0) Dintp1(dresultA)++
266
267
#define Dint_decrement(dresultA,dresultB) \
268
if ((Dintp2(dresultB)--)==0) Dintp1(dresultA)--
269
270
#define Dint_negate(dresultA,dresultB) \
271
Dintp1(dresultA) = ~Dintp1(dresultA); \
272
if ((Dintp2(dresultB) = -Dintp2(dresultB))==0) Dintp1(dresultA)++
273
274
#define Dint_copyfromptr(src,destA,destB) \
275
Dintp1(destA) = src->wd0; \
276
Dintp2(destB) = src->wd1
277
#define Dint_copytoptr(srcA,srcB,dest) \
278
dest->wd0 = Dintp1(srcA); \
279
dest->wd1 = Dintp2(srcB)
280
281
282
/* other macros */
283
284
#define Find_ms_one_bit(value, position) \
285
{ \
286
int var; \
287
for (var=8; var >=1; var >>= 1) { \
288
if (value >> 32 - position) \
289
position -= var; \
290
else position += var; \
291
} \
292
if ((value >> 32 - position) == 0) \
293
position--; \
294
else position -= 2; \
295
}
296
297
298
/*
299
* Unsigned int macros
300
*/
301
#define Duint_copyfromptr(src,destA,destB) \
302
Dint_copyfromptr(src,destA,destB)
303
#define Duint_copytoptr(srcA,srcB,dest) \
304
Dint_copytoptr(srcA,srcB,dest)
305
306
#define Suint_isinexact_to_sgl(int_value) \
307
(int_value << 32 - SGL_EXP_LENGTH)
308
309
#define Sgl_roundnearest_from_suint(suint_value,sgl_value) \
310
if (suint_value & 1<<(SGL_EXP_LENGTH - 1)) /* round bit */ \
311
if ((suint_value << 33 - SGL_EXP_LENGTH) || Slow(sgl_value)) \
312
Sall(sgl_value)++
313
314
#define Duint_isinexact_to_sgl(duint_valueA,duint_valueB) \
315
((Duintp1(duint_valueA) << 32 - SGL_EXP_LENGTH) || Duintp2(duint_valueB))
316
317
#define Sgl_roundnearest_from_duint(duint_valueA,duint_valueB,sgl_value) \
318
if (Duintp1(duint_valueA) & 1<<(SGL_EXP_LENGTH - 1)) \
319
if ((Duintp1(duint_valueA) << 33 - SGL_EXP_LENGTH) || \
320
Duintp2(duint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
321
322
#define Duint_isinexact_to_dbl(duint_value) \
323
(Duintp2(duint_value) << 32 - DBL_EXP_LENGTH)
324
325
#define Dbl_roundnearest_from_duint(duint_opndB,dbl_opndA,dbl_opndB) \
326
if (Duintp2(duint_opndB) & 1<<(DBL_EXP_LENGTH - 1)) \
327
if ((Duintp2(duint_opndB) << 33 - DBL_EXP_LENGTH) || Dlowp2(dbl_opndB)) \
328
if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
329
330
#define Suint_from_sgl_mantissa(src,exponent,result) \
331
Sall(result) = (unsigned)(Sall(src) << SGL_EXP_LENGTH)>>(31 - exponent)
332
333
#define Sgl_isinexact_to_unsigned(sgl_value,exponent) \
334
Sgl_isinexact_to_fix(sgl_value,exponent)
335
336
#define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
337
{unsigned int val = Sall(sgl_value) << SGL_EXP_LENGTH; \
338
if (exponent <= 31) { \
339
Dintp1(dresultA) = 0; \
340
Dintp2(dresultB) = val >> (31 - exponent); \
341
} \
342
else { \
343
Dintp1(dresultA) = val >> (63 - exponent); \
344
Dintp2(dresultB) = exponent <= 62 ? val << (exponent - 31) : 0; \
345
} \
346
}
347
348
#define Duint_setzero(dresultA,dresultB) \
349
Dint_setzero(dresultA,dresultB)
350
351
#define Duint_increment(dresultA,dresultB) Dint_increment(dresultA,dresultB)
352
353
#define Duint_isone_lowp2(dresultB) Dint_isone_lowp2(dresultB)
354
355
#define Suint_from_dbl_mantissa(srcA,srcB,exponent,dest) \
356
Shiftdouble(Dallp1(srcA),Dallp2(srcB),21,dest); \
357
dest = (unsigned)dest >> 31 - exponent
358
359
#define Dbl_isinexact_to_unsigned(dbl_valueA,dbl_valueB,exponent) \
360
Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent)
361
362
#define Duint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
363
Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB)
364
365