diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/math-emu/ieee754.h | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/math-emu/ieee754.h')
-rw-r--r-- | arch/mips/math-emu/ieee754.h | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h new file mode 100644 index 000000000..090caa740 --- /dev/null +++ b/arch/mips/math-emu/ieee754.h | |||
@@ -0,0 +1,311 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
2 | /* | ||
3 | * MIPS floating point support | ||
4 | * Copyright (C) 1994-2000 Algorithmics Ltd. | ||
5 | * | ||
6 | * Nov 7, 2000 | ||
7 | * Modification to allow integration with Linux kernel | ||
8 | * | ||
9 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com | ||
10 | * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. | ||
11 | */ | ||
12 | #ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H | ||
13 | #define __ARCH_MIPS_MATH_EMU_IEEE754_H | ||
14 | |||
15 | #include <linux/compiler.h> | ||
16 | #include <asm/byteorder.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <asm/bitfield.h> | ||
21 | |||
22 | union ieee754dp { | ||
23 | struct { | ||
24 | __BITFIELD_FIELD(unsigned int sign:1, | ||
25 | __BITFIELD_FIELD(unsigned int bexp:11, | ||
26 | __BITFIELD_FIELD(u64 mant:52, | ||
27 | ;))) | ||
28 | }; | ||
29 | u64 bits; | ||
30 | }; | ||
31 | |||
32 | union ieee754sp { | ||
33 | struct { | ||
34 | __BITFIELD_FIELD(unsigned sign:1, | ||
35 | __BITFIELD_FIELD(unsigned bexp:8, | ||
36 | __BITFIELD_FIELD(unsigned mant:23, | ||
37 | ;))) | ||
38 | }; | ||
39 | u32 bits; | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * single precision (often aka float) | ||
44 | */ | ||
45 | int ieee754sp_class(union ieee754sp x); | ||
46 | |||
47 | union ieee754sp ieee754sp_abs(union ieee754sp x); | ||
48 | union ieee754sp ieee754sp_neg(union ieee754sp x); | ||
49 | |||
50 | union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y); | ||
51 | union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y); | ||
52 | union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y); | ||
53 | union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y); | ||
54 | |||
55 | union ieee754sp ieee754sp_fint(int x); | ||
56 | union ieee754sp ieee754sp_flong(s64 x); | ||
57 | union ieee754sp ieee754sp_fdp(union ieee754dp x); | ||
58 | union ieee754sp ieee754sp_rint(union ieee754sp x); | ||
59 | |||
60 | int ieee754sp_tint(union ieee754sp x); | ||
61 | s64 ieee754sp_tlong(union ieee754sp x); | ||
62 | |||
63 | int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cop, int sig); | ||
64 | |||
65 | union ieee754sp ieee754sp_sqrt(union ieee754sp x); | ||
66 | |||
67 | union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, | ||
68 | union ieee754sp y); | ||
69 | union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, | ||
70 | union ieee754sp y); | ||
71 | union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x, | ||
72 | union ieee754sp y); | ||
73 | union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x, | ||
74 | union ieee754sp y); | ||
75 | union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x, | ||
76 | union ieee754sp y); | ||
77 | union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x, | ||
78 | union ieee754sp y); | ||
79 | int ieee754sp_2008class(union ieee754sp x); | ||
80 | union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y); | ||
81 | union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y); | ||
82 | union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y); | ||
83 | union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y); | ||
84 | |||
85 | /* | ||
86 | * double precision (often aka double) | ||
87 | */ | ||
88 | int ieee754dp_class(union ieee754dp x); | ||
89 | |||
90 | union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y); | ||
91 | union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y); | ||
92 | union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y); | ||
93 | union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y); | ||
94 | |||
95 | union ieee754dp ieee754dp_abs(union ieee754dp x); | ||
96 | union ieee754dp ieee754dp_neg(union ieee754dp x); | ||
97 | |||
98 | union ieee754dp ieee754dp_fint(int x); | ||
99 | union ieee754dp ieee754dp_flong(s64 x); | ||
100 | union ieee754dp ieee754dp_fsp(union ieee754sp x); | ||
101 | union ieee754dp ieee754dp_rint(union ieee754dp x); | ||
102 | |||
103 | int ieee754dp_tint(union ieee754dp x); | ||
104 | s64 ieee754dp_tlong(union ieee754dp x); | ||
105 | |||
106 | int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig); | ||
107 | |||
108 | union ieee754dp ieee754dp_sqrt(union ieee754dp x); | ||
109 | |||
110 | union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, | ||
111 | union ieee754dp y); | ||
112 | union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, | ||
113 | union ieee754dp y); | ||
114 | union ieee754dp ieee754dp_madd(union ieee754dp z, union ieee754dp x, | ||
115 | union ieee754dp y); | ||
116 | union ieee754dp ieee754dp_msub(union ieee754dp z, union ieee754dp x, | ||
117 | union ieee754dp y); | ||
118 | union ieee754dp ieee754dp_nmadd(union ieee754dp z, union ieee754dp x, | ||
119 | union ieee754dp y); | ||
120 | union ieee754dp ieee754dp_nmsub(union ieee754dp z, union ieee754dp x, | ||
121 | union ieee754dp y); | ||
122 | int ieee754dp_2008class(union ieee754dp x); | ||
123 | union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y); | ||
124 | union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y); | ||
125 | union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y); | ||
126 | union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y); | ||
127 | |||
128 | |||
129 | /* 5 types of floating point number | ||
130 | */ | ||
131 | enum { | ||
132 | IEEE754_CLASS_NORM = 0x00, | ||
133 | IEEE754_CLASS_ZERO = 0x01, | ||
134 | IEEE754_CLASS_DNORM = 0x02, | ||
135 | IEEE754_CLASS_INF = 0x03, | ||
136 | IEEE754_CLASS_SNAN = 0x04, | ||
137 | IEEE754_CLASS_QNAN = 0x05, | ||
138 | }; | ||
139 | |||
140 | /* exception numbers */ | ||
141 | #define IEEE754_INEXACT 0x01 | ||
142 | #define IEEE754_UNDERFLOW 0x02 | ||
143 | #define IEEE754_OVERFLOW 0x04 | ||
144 | #define IEEE754_ZERO_DIVIDE 0x08 | ||
145 | #define IEEE754_INVALID_OPERATION 0x10 | ||
146 | |||
147 | /* cmp operators | ||
148 | */ | ||
149 | #define IEEE754_CLT 0x01 | ||
150 | #define IEEE754_CEQ 0x02 | ||
151 | #define IEEE754_CGT 0x04 | ||
152 | #define IEEE754_CUN 0x08 | ||
153 | |||
154 | /* | ||
155 | * The control status register | ||
156 | */ | ||
157 | struct _ieee754_csr { | ||
158 | __BITFIELD_FIELD(unsigned fcc:7, /* condition[7:1] */ | ||
159 | __BITFIELD_FIELD(unsigned nod:1, /* set 1 for no denormals */ | ||
160 | __BITFIELD_FIELD(unsigned c:1, /* condition[0] */ | ||
161 | __BITFIELD_FIELD(unsigned pad0:3, | ||
162 | __BITFIELD_FIELD(unsigned abs2008:1, /* IEEE 754-2008 ABS/NEG.fmt */ | ||
163 | __BITFIELD_FIELD(unsigned nan2008:1, /* IEEE 754-2008 NaN mode */ | ||
164 | __BITFIELD_FIELD(unsigned cx:6, /* exceptions this operation */ | ||
165 | __BITFIELD_FIELD(unsigned mx:5, /* exception enable mask */ | ||
166 | __BITFIELD_FIELD(unsigned sx:5, /* exceptions total */ | ||
167 | __BITFIELD_FIELD(unsigned rm:2, /* current rounding mode */ | ||
168 | ;)))))))))) | ||
169 | }; | ||
170 | #define ieee754_csr (*(struct _ieee754_csr *)(¤t->thread.fpu.fcr31)) | ||
171 | |||
172 | static inline unsigned int ieee754_getrm(void) | ||
173 | { | ||
174 | return (ieee754_csr.rm); | ||
175 | } | ||
176 | |||
177 | static inline unsigned int ieee754_setrm(unsigned int rm) | ||
178 | { | ||
179 | return (ieee754_csr.rm = rm); | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * get current exceptions | ||
184 | */ | ||
185 | static inline unsigned int ieee754_getcx(void) | ||
186 | { | ||
187 | return (ieee754_csr.cx); | ||
188 | } | ||
189 | |||
190 | /* test for current exception condition | ||
191 | */ | ||
192 | static inline int ieee754_cxtest(unsigned int n) | ||
193 | { | ||
194 | return (ieee754_csr.cx & n); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * get sticky exceptions | ||
199 | */ | ||
200 | static inline unsigned int ieee754_getsx(void) | ||
201 | { | ||
202 | return (ieee754_csr.sx); | ||
203 | } | ||
204 | |||
205 | /* clear sticky conditions | ||
206 | */ | ||
207 | static inline unsigned int ieee754_clrsx(void) | ||
208 | { | ||
209 | return (ieee754_csr.sx = 0); | ||
210 | } | ||
211 | |||
212 | /* test for sticky exception condition | ||
213 | */ | ||
214 | static inline int ieee754_sxtest(unsigned int n) | ||
215 | { | ||
216 | return (ieee754_csr.sx & n); | ||
217 | } | ||
218 | |||
219 | /* debugging */ | ||
220 | union ieee754sp ieee754sp_dump(char *s, union ieee754sp x); | ||
221 | union ieee754dp ieee754dp_dump(char *s, union ieee754dp x); | ||
222 | |||
223 | #define IEEE754_SPCVAL_PZERO 0 /* +0.0 */ | ||
224 | #define IEEE754_SPCVAL_NZERO 1 /* -0.0 */ | ||
225 | #define IEEE754_SPCVAL_PONE 2 /* +1.0 */ | ||
226 | #define IEEE754_SPCVAL_NONE 3 /* -1.0 */ | ||
227 | #define IEEE754_SPCVAL_PTEN 4 /* +10.0 */ | ||
228 | #define IEEE754_SPCVAL_NTEN 5 /* -10.0 */ | ||
229 | #define IEEE754_SPCVAL_PINFINITY 6 /* +inf */ | ||
230 | #define IEEE754_SPCVAL_NINFINITY 7 /* -inf */ | ||
231 | #define IEEE754_SPCVAL_INDEF_LEG 8 /* legacy quiet NaN */ | ||
232 | #define IEEE754_SPCVAL_INDEF_2008 9 /* IEEE 754-2008 quiet NaN */ | ||
233 | #define IEEE754_SPCVAL_PMAX 10 /* +max norm */ | ||
234 | #define IEEE754_SPCVAL_NMAX 11 /* -max norm */ | ||
235 | #define IEEE754_SPCVAL_PMIN 12 /* +min norm */ | ||
236 | #define IEEE754_SPCVAL_NMIN 13 /* -min norm */ | ||
237 | #define IEEE754_SPCVAL_PMIND 14 /* +min denorm */ | ||
238 | #define IEEE754_SPCVAL_NMIND 15 /* -min denorm */ | ||
239 | #define IEEE754_SPCVAL_P1E31 16 /* + 1.0e31 */ | ||
240 | #define IEEE754_SPCVAL_P1E63 17 /* + 1.0e63 */ | ||
241 | |||
242 | extern const union ieee754dp __ieee754dp_spcvals[]; | ||
243 | extern const union ieee754sp __ieee754sp_spcvals[]; | ||
244 | #define ieee754dp_spcvals ((const union ieee754dp *)__ieee754dp_spcvals) | ||
245 | #define ieee754sp_spcvals ((const union ieee754sp *)__ieee754sp_spcvals) | ||
246 | |||
247 | /* | ||
248 | * Return infinity with given sign | ||
249 | */ | ||
250 | #define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) | ||
251 | #define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) | ||
252 | #define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) | ||
253 | #define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) | ||
254 | #define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \ | ||
255 | ieee754_csr.nan2008]) | ||
256 | #define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) | ||
257 | #define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) | ||
258 | #define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) | ||
259 | #define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31]) | ||
260 | #define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63]) | ||
261 | |||
262 | #define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) | ||
263 | #define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) | ||
264 | #define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) | ||
265 | #define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) | ||
266 | #define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \ | ||
267 | ieee754_csr.nan2008]) | ||
268 | #define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) | ||
269 | #define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) | ||
270 | #define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) | ||
271 | #define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31]) | ||
272 | #define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63]) | ||
273 | |||
274 | /* | ||
275 | * Indefinite integer value | ||
276 | */ | ||
277 | static inline int ieee754si_indef(void) | ||
278 | { | ||
279 | return ieee754_csr.nan2008 ? 0 : INT_MAX; | ||
280 | } | ||
281 | |||
282 | static inline s64 ieee754di_indef(void) | ||
283 | { | ||
284 | return ieee754_csr.nan2008 ? 0 : S64_MAX; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Overflow integer value | ||
289 | */ | ||
290 | static inline int ieee754si_overflow(int xs) | ||
291 | { | ||
292 | return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX; | ||
293 | } | ||
294 | |||
295 | static inline s64 ieee754di_overflow(int xs) | ||
296 | { | ||
297 | return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX; | ||
298 | } | ||
299 | |||
300 | /* result types for xctx.rt */ | ||
301 | #define IEEE754_RT_SP 0 | ||
302 | #define IEEE754_RT_DP 1 | ||
303 | #define IEEE754_RT_XP 2 | ||
304 | #define IEEE754_RT_SI 3 | ||
305 | #define IEEE754_RT_DI 4 | ||
306 | |||
307 | /* compat */ | ||
308 | #define ieee754dp_fix(x) ieee754dp_tint(x) | ||
309 | #define ieee754sp_fix(x) ieee754sp_tint(x) | ||
310 | |||
311 | #endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */ | ||