xref: /openbmc/qemu/target/mips/tcg/fpu_helper.c (revision 907a2af1)
1 /*
2  *  Helpers for emulation of FPU-related MIPS instructions.
3  *
4  *  Copyright (C) 2004-2005  Jocelyn Mayer
5  *  Copyright (C) 2020  Wave Computing, Inc.
6  *  Copyright (C) 2020  Aleksandar Markovic <amarkovic@wavecomp.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include "qemu/osdep.h"
24 #include "cpu.h"
25 #include "internal.h"
26 #include "exec/helper-proto.h"
27 #include "exec/exec-all.h"
28 #include "fpu/softfloat.h"
29 #include "fpu_helper.h"
30 
31 
32 /* Complex FPU operations which may need stack space. */
33 
34 #define FLOAT_TWO32 make_float32(1 << 30)
35 #define FLOAT_TWO64 make_float64(1ULL << 62)
36 
37 #define FP_TO_INT32_OVERFLOW 0x7fffffff
38 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
39 
helper_cfc1(CPUMIPSState * env,uint32_t reg)40 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
41 {
42     target_ulong arg1 = 0;
43 
44     switch (reg) {
45     case 0:
46         arg1 = (int32_t)env->active_fpu.fcr0;
47         break;
48     case 1:
49         /* UFR Support - Read Status FR */
50         if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
51             if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
52                 arg1 = (int32_t)
53                        ((env->CP0_Status & (1  << CP0St_FR)) >> CP0St_FR);
54             } else {
55                 do_raise_exception(env, EXCP_RI, GETPC());
56             }
57         }
58         break;
59     case 5:
60         /* FRE Support - read Config5.FRE bit */
61         if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
62             if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
63                 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
64             } else {
65                 helper_raise_exception(env, EXCP_RI);
66             }
67         }
68         break;
69     case 25:
70         arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
71                ((env->active_fpu.fcr31 >> 23) & 0x1);
72         break;
73     case 26:
74         arg1 = env->active_fpu.fcr31 & 0x0003f07c;
75         break;
76     case 28:
77         arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
78                ((env->active_fpu.fcr31 >> 22) & 0x4);
79         break;
80     default:
81         arg1 = (int32_t)env->active_fpu.fcr31;
82         break;
83     }
84 
85     return arg1;
86 }
87 
helper_ctc1(CPUMIPSState * env,target_ulong arg1,uint32_t fs,uint32_t rt)88 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
89 {
90     switch (fs) {
91     case 1:
92         /* UFR Alias - Reset Status FR */
93         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
94             return;
95         }
96         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
97             env->CP0_Status &= ~(1 << CP0St_FR);
98             compute_hflags(env);
99         } else {
100             do_raise_exception(env, EXCP_RI, GETPC());
101         }
102         break;
103     case 4:
104         /* UNFR Alias - Set Status FR */
105         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
106             return;
107         }
108         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
109             env->CP0_Status |= (1 << CP0St_FR);
110             compute_hflags(env);
111         } else {
112             do_raise_exception(env, EXCP_RI, GETPC());
113         }
114         break;
115     case 5:
116         /* FRE Support - clear Config5.FRE bit */
117         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
118             return;
119         }
120         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
121             env->CP0_Config5 &= ~(1 << CP0C5_FRE);
122             compute_hflags(env);
123         } else {
124             helper_raise_exception(env, EXCP_RI);
125         }
126         break;
127     case 6:
128         /* FRE Support - set Config5.FRE bit */
129         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
130             return;
131         }
132         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
133             env->CP0_Config5 |= (1 << CP0C5_FRE);
134             compute_hflags(env);
135         } else {
136             helper_raise_exception(env, EXCP_RI);
137         }
138         break;
139     case 25:
140         if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) {
141             return;
142         }
143         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
144                                 ((arg1 & 0xfe) << 24) |
145                                 ((arg1 & 0x1) << 23);
146         break;
147     case 26:
148         if (arg1 & 0x007c0000) {
149             return;
150         }
151         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
152                                 (arg1 & 0x0003f07c);
153         break;
154     case 28:
155         if (arg1 & 0x007c0000) {
156             return;
157         }
158         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
159                                 (arg1 & 0x00000f83) |
160                                 ((arg1 & 0x4) << 22);
161         break;
162     case 31:
163         env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
164                (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
165         break;
166     default:
167         if (env->insn_flags & ISA_MIPS_R6) {
168             do_raise_exception(env, EXCP_RI, GETPC());
169         }
170         return;
171     }
172     restore_fp_status(env);
173     set_float_exception_flags(0, &env->active_fpu.fp_status);
174     if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
175         GET_FP_CAUSE(env->active_fpu.fcr31)) {
176         do_raise_exception(env, EXCP_FPE, GETPC());
177     }
178 }
179 
ieee_to_mips_xcpt(int ieee_xcpt)180 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
181 {
182     int mips_xcpt = 0;
183 
184     if (ieee_xcpt & float_flag_invalid) {
185         mips_xcpt |= FP_INVALID;
186     }
187     if (ieee_xcpt & float_flag_overflow) {
188         mips_xcpt |= FP_OVERFLOW;
189     }
190     if (ieee_xcpt & float_flag_underflow) {
191         mips_xcpt |= FP_UNDERFLOW;
192     }
193     if (ieee_xcpt & float_flag_divbyzero) {
194         mips_xcpt |= FP_DIV0;
195     }
196     if (ieee_xcpt & float_flag_inexact) {
197         mips_xcpt |= FP_INEXACT;
198     }
199 
200     return mips_xcpt;
201 }
202 
update_fcr31(CPUMIPSState * env,uintptr_t pc)203 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
204 {
205     int ieee_exception_flags = get_float_exception_flags(
206                                    &env->active_fpu.fp_status);
207     int mips_exception_flags = 0;
208 
209     if (ieee_exception_flags) {
210         mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
211     }
212 
213     SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
214 
215     if (mips_exception_flags)  {
216         set_float_exception_flags(0, &env->active_fpu.fp_status);
217 
218         if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
219             do_raise_exception(env, EXCP_FPE, pc);
220         } else {
221             UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
222         }
223     }
224 }
225 
226 /*
227  * Float support.
228  * Single precition routines have a "s" suffix, double precision a
229  * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
230  * paired single lower "pl", paired single upper "pu".
231  */
232 
233 /* unary operations, modifying fp status  */
helper_float_sqrt_d(CPUMIPSState * env,uint64_t fdt0)234 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
235 {
236     fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
237     update_fcr31(env, GETPC());
238     return fdt0;
239 }
240 
helper_float_sqrt_s(CPUMIPSState * env,uint32_t fst0)241 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
242 {
243     fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
244     update_fcr31(env, GETPC());
245     return fst0;
246 }
247 
helper_float_cvtd_s(CPUMIPSState * env,uint32_t fst0)248 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
249 {
250     uint64_t fdt2;
251 
252     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
253     update_fcr31(env, GETPC());
254     return fdt2;
255 }
256 
helper_float_cvtd_w(CPUMIPSState * env,uint32_t wt0)257 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
258 {
259     uint64_t fdt2;
260 
261     fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
262     update_fcr31(env, GETPC());
263     return fdt2;
264 }
265 
helper_float_cvtd_l(CPUMIPSState * env,uint64_t dt0)266 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
267 {
268     uint64_t fdt2;
269 
270     fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
271     update_fcr31(env, GETPC());
272     return fdt2;
273 }
274 
helper_float_cvt_l_d(CPUMIPSState * env,uint64_t fdt0)275 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
276 {
277     uint64_t dt2;
278 
279     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
280     if (get_float_exception_flags(&env->active_fpu.fp_status)
281         & (float_flag_invalid | float_flag_overflow)) {
282         dt2 = FP_TO_INT64_OVERFLOW;
283     }
284     update_fcr31(env, GETPC());
285     return dt2;
286 }
287 
helper_float_cvt_l_s(CPUMIPSState * env,uint32_t fst0)288 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
289 {
290     uint64_t dt2;
291 
292     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
293     if (get_float_exception_flags(&env->active_fpu.fp_status)
294         & (float_flag_invalid | float_flag_overflow)) {
295         dt2 = FP_TO_INT64_OVERFLOW;
296     }
297     update_fcr31(env, GETPC());
298     return dt2;
299 }
300 
helper_float_cvtps_pw(CPUMIPSState * env,uint64_t dt0)301 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
302 {
303     uint32_t fst2;
304     uint32_t fsth2;
305 
306     fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
307     fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
308     update_fcr31(env, GETPC());
309     return ((uint64_t)fsth2 << 32) | fst2;
310 }
311 
helper_float_cvtpw_ps(CPUMIPSState * env,uint64_t fdt0)312 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
313 {
314     uint32_t wt2;
315     uint32_t wth2;
316     int excp, excph;
317 
318     wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
319     excp = get_float_exception_flags(&env->active_fpu.fp_status);
320     if (excp & (float_flag_overflow | float_flag_invalid)) {
321         wt2 = FP_TO_INT32_OVERFLOW;
322     }
323 
324     set_float_exception_flags(0, &env->active_fpu.fp_status);
325     wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
326     excph = get_float_exception_flags(&env->active_fpu.fp_status);
327     if (excph & (float_flag_overflow | float_flag_invalid)) {
328         wth2 = FP_TO_INT32_OVERFLOW;
329     }
330 
331     set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
332     update_fcr31(env, GETPC());
333 
334     return ((uint64_t)wth2 << 32) | wt2;
335 }
336 
helper_float_cvts_d(CPUMIPSState * env,uint64_t fdt0)337 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
338 {
339     uint32_t fst2;
340 
341     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
342     update_fcr31(env, GETPC());
343     return fst2;
344 }
345 
helper_float_cvts_w(CPUMIPSState * env,uint32_t wt0)346 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
347 {
348     uint32_t fst2;
349 
350     fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
351     update_fcr31(env, GETPC());
352     return fst2;
353 }
354 
helper_float_cvts_l(CPUMIPSState * env,uint64_t dt0)355 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
356 {
357     uint32_t fst2;
358 
359     fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
360     update_fcr31(env, GETPC());
361     return fst2;
362 }
363 
helper_float_cvts_pl(CPUMIPSState * env,uint32_t wt0)364 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
365 {
366     uint32_t wt2;
367 
368     wt2 = wt0;
369     update_fcr31(env, GETPC());
370     return wt2;
371 }
372 
helper_float_cvts_pu(CPUMIPSState * env,uint32_t wth0)373 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
374 {
375     uint32_t wt2;
376 
377     wt2 = wth0;
378     update_fcr31(env, GETPC());
379     return wt2;
380 }
381 
helper_float_cvt_w_s(CPUMIPSState * env,uint32_t fst0)382 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
383 {
384     uint32_t wt2;
385 
386     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
387     if (get_float_exception_flags(&env->active_fpu.fp_status)
388         & (float_flag_invalid | float_flag_overflow)) {
389         wt2 = FP_TO_INT32_OVERFLOW;
390     }
391     update_fcr31(env, GETPC());
392     return wt2;
393 }
394 
helper_float_cvt_w_d(CPUMIPSState * env,uint64_t fdt0)395 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
396 {
397     uint32_t wt2;
398 
399     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
400     if (get_float_exception_flags(&env->active_fpu.fp_status)
401         & (float_flag_invalid | float_flag_overflow)) {
402         wt2 = FP_TO_INT32_OVERFLOW;
403     }
404     update_fcr31(env, GETPC());
405     return wt2;
406 }
407 
helper_float_round_l_d(CPUMIPSState * env,uint64_t fdt0)408 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
409 {
410     uint64_t dt2;
411 
412     set_float_rounding_mode(float_round_nearest_even,
413                             &env->active_fpu.fp_status);
414     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
415     restore_rounding_mode(env);
416     if (get_float_exception_flags(&env->active_fpu.fp_status)
417         & (float_flag_invalid | float_flag_overflow)) {
418         dt2 = FP_TO_INT64_OVERFLOW;
419     }
420     update_fcr31(env, GETPC());
421     return dt2;
422 }
423 
helper_float_round_l_s(CPUMIPSState * env,uint32_t fst0)424 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
425 {
426     uint64_t dt2;
427 
428     set_float_rounding_mode(float_round_nearest_even,
429                             &env->active_fpu.fp_status);
430     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
431     restore_rounding_mode(env);
432     if (get_float_exception_flags(&env->active_fpu.fp_status)
433         & (float_flag_invalid | float_flag_overflow)) {
434         dt2 = FP_TO_INT64_OVERFLOW;
435     }
436     update_fcr31(env, GETPC());
437     return dt2;
438 }
439 
helper_float_round_w_d(CPUMIPSState * env,uint64_t fdt0)440 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
441 {
442     uint32_t wt2;
443 
444     set_float_rounding_mode(float_round_nearest_even,
445                             &env->active_fpu.fp_status);
446     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
447     restore_rounding_mode(env);
448     if (get_float_exception_flags(&env->active_fpu.fp_status)
449         & (float_flag_invalid | float_flag_overflow)) {
450         wt2 = FP_TO_INT32_OVERFLOW;
451     }
452     update_fcr31(env, GETPC());
453     return wt2;
454 }
455 
helper_float_round_w_s(CPUMIPSState * env,uint32_t fst0)456 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
457 {
458     uint32_t wt2;
459 
460     set_float_rounding_mode(float_round_nearest_even,
461                             &env->active_fpu.fp_status);
462     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
463     restore_rounding_mode(env);
464     if (get_float_exception_flags(&env->active_fpu.fp_status)
465         & (float_flag_invalid | float_flag_overflow)) {
466         wt2 = FP_TO_INT32_OVERFLOW;
467     }
468     update_fcr31(env, GETPC());
469     return wt2;
470 }
471 
helper_float_trunc_l_d(CPUMIPSState * env,uint64_t fdt0)472 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
473 {
474     uint64_t dt2;
475 
476     dt2 = float64_to_int64_round_to_zero(fdt0,
477                                          &env->active_fpu.fp_status);
478     if (get_float_exception_flags(&env->active_fpu.fp_status)
479         & (float_flag_invalid | float_flag_overflow)) {
480         dt2 = FP_TO_INT64_OVERFLOW;
481     }
482     update_fcr31(env, GETPC());
483     return dt2;
484 }
485 
helper_float_trunc_l_s(CPUMIPSState * env,uint32_t fst0)486 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
487 {
488     uint64_t dt2;
489 
490     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
491     if (get_float_exception_flags(&env->active_fpu.fp_status)
492         & (float_flag_invalid | float_flag_overflow)) {
493         dt2 = FP_TO_INT64_OVERFLOW;
494     }
495     update_fcr31(env, GETPC());
496     return dt2;
497 }
498 
helper_float_trunc_w_d(CPUMIPSState * env,uint64_t fdt0)499 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
500 {
501     uint32_t wt2;
502 
503     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
504     if (get_float_exception_flags(&env->active_fpu.fp_status)
505         & (float_flag_invalid | float_flag_overflow)) {
506         wt2 = FP_TO_INT32_OVERFLOW;
507     }
508     update_fcr31(env, GETPC());
509     return wt2;
510 }
511 
helper_float_trunc_w_s(CPUMIPSState * env,uint32_t fst0)512 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
513 {
514     uint32_t wt2;
515 
516     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
517     if (get_float_exception_flags(&env->active_fpu.fp_status)
518         & (float_flag_invalid | float_flag_overflow)) {
519         wt2 = FP_TO_INT32_OVERFLOW;
520     }
521     update_fcr31(env, GETPC());
522     return wt2;
523 }
524 
helper_float_ceil_l_d(CPUMIPSState * env,uint64_t fdt0)525 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
526 {
527     uint64_t dt2;
528 
529     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
530     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
531     restore_rounding_mode(env);
532     if (get_float_exception_flags(&env->active_fpu.fp_status)
533         & (float_flag_invalid | float_flag_overflow)) {
534         dt2 = FP_TO_INT64_OVERFLOW;
535     }
536     update_fcr31(env, GETPC());
537     return dt2;
538 }
539 
helper_float_ceil_l_s(CPUMIPSState * env,uint32_t fst0)540 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
541 {
542     uint64_t dt2;
543 
544     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
545     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
546     restore_rounding_mode(env);
547     if (get_float_exception_flags(&env->active_fpu.fp_status)
548         & (float_flag_invalid | float_flag_overflow)) {
549         dt2 = FP_TO_INT64_OVERFLOW;
550     }
551     update_fcr31(env, GETPC());
552     return dt2;
553 }
554 
helper_float_ceil_w_d(CPUMIPSState * env,uint64_t fdt0)555 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
556 {
557     uint32_t wt2;
558 
559     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
560     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
561     restore_rounding_mode(env);
562     if (get_float_exception_flags(&env->active_fpu.fp_status)
563         & (float_flag_invalid | float_flag_overflow)) {
564         wt2 = FP_TO_INT32_OVERFLOW;
565     }
566     update_fcr31(env, GETPC());
567     return wt2;
568 }
569 
helper_float_ceil_w_s(CPUMIPSState * env,uint32_t fst0)570 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
571 {
572     uint32_t wt2;
573 
574     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
575     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
576     restore_rounding_mode(env);
577     if (get_float_exception_flags(&env->active_fpu.fp_status)
578         & (float_flag_invalid | float_flag_overflow)) {
579         wt2 = FP_TO_INT32_OVERFLOW;
580     }
581     update_fcr31(env, GETPC());
582     return wt2;
583 }
584 
helper_float_floor_l_d(CPUMIPSState * env,uint64_t fdt0)585 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
586 {
587     uint64_t dt2;
588 
589     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
590     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
591     restore_rounding_mode(env);
592     if (get_float_exception_flags(&env->active_fpu.fp_status)
593         & (float_flag_invalid | float_flag_overflow)) {
594         dt2 = FP_TO_INT64_OVERFLOW;
595     }
596     update_fcr31(env, GETPC());
597     return dt2;
598 }
599 
helper_float_floor_l_s(CPUMIPSState * env,uint32_t fst0)600 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
601 {
602     uint64_t dt2;
603 
604     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
605     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
606     restore_rounding_mode(env);
607     if (get_float_exception_flags(&env->active_fpu.fp_status)
608         & (float_flag_invalid | float_flag_overflow)) {
609         dt2 = FP_TO_INT64_OVERFLOW;
610     }
611     update_fcr31(env, GETPC());
612     return dt2;
613 }
614 
helper_float_floor_w_d(CPUMIPSState * env,uint64_t fdt0)615 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
616 {
617     uint32_t wt2;
618 
619     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
620     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
621     restore_rounding_mode(env);
622     if (get_float_exception_flags(&env->active_fpu.fp_status)
623         & (float_flag_invalid | float_flag_overflow)) {
624         wt2 = FP_TO_INT32_OVERFLOW;
625     }
626     update_fcr31(env, GETPC());
627     return wt2;
628 }
629 
helper_float_floor_w_s(CPUMIPSState * env,uint32_t fst0)630 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
631 {
632     uint32_t wt2;
633 
634     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
635     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
636     restore_rounding_mode(env);
637     if (get_float_exception_flags(&env->active_fpu.fp_status)
638         & (float_flag_invalid | float_flag_overflow)) {
639         wt2 = FP_TO_INT32_OVERFLOW;
640     }
641     update_fcr31(env, GETPC());
642     return wt2;
643 }
644 
helper_float_cvt_2008_l_d(CPUMIPSState * env,uint64_t fdt0)645 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
646 {
647     uint64_t dt2;
648 
649     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
650     if (get_float_exception_flags(&env->active_fpu.fp_status)
651             & float_flag_invalid) {
652         if (float64_is_any_nan(fdt0)) {
653             dt2 = 0;
654         }
655     }
656     update_fcr31(env, GETPC());
657     return dt2;
658 }
659 
helper_float_cvt_2008_l_s(CPUMIPSState * env,uint32_t fst0)660 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
661 {
662     uint64_t dt2;
663 
664     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
665     if (get_float_exception_flags(&env->active_fpu.fp_status)
666             & float_flag_invalid) {
667         if (float32_is_any_nan(fst0)) {
668             dt2 = 0;
669         }
670     }
671     update_fcr31(env, GETPC());
672     return dt2;
673 }
674 
helper_float_cvt_2008_w_d(CPUMIPSState * env,uint64_t fdt0)675 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
676 {
677     uint32_t wt2;
678 
679     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
680     if (get_float_exception_flags(&env->active_fpu.fp_status)
681             & float_flag_invalid) {
682         if (float64_is_any_nan(fdt0)) {
683             wt2 = 0;
684         }
685     }
686     update_fcr31(env, GETPC());
687     return wt2;
688 }
689 
helper_float_cvt_2008_w_s(CPUMIPSState * env,uint32_t fst0)690 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
691 {
692     uint32_t wt2;
693 
694     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
695     if (get_float_exception_flags(&env->active_fpu.fp_status)
696             & float_flag_invalid) {
697         if (float32_is_any_nan(fst0)) {
698             wt2 = 0;
699         }
700     }
701     update_fcr31(env, GETPC());
702     return wt2;
703 }
704 
helper_float_round_2008_l_d(CPUMIPSState * env,uint64_t fdt0)705 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
706 {
707     uint64_t dt2;
708 
709     set_float_rounding_mode(float_round_nearest_even,
710             &env->active_fpu.fp_status);
711     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
712     restore_rounding_mode(env);
713     if (get_float_exception_flags(&env->active_fpu.fp_status)
714             & float_flag_invalid) {
715         if (float64_is_any_nan(fdt0)) {
716             dt2 = 0;
717         }
718     }
719     update_fcr31(env, GETPC());
720     return dt2;
721 }
722 
helper_float_round_2008_l_s(CPUMIPSState * env,uint32_t fst0)723 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
724 {
725     uint64_t dt2;
726 
727     set_float_rounding_mode(float_round_nearest_even,
728             &env->active_fpu.fp_status);
729     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
730     restore_rounding_mode(env);
731     if (get_float_exception_flags(&env->active_fpu.fp_status)
732             & float_flag_invalid) {
733         if (float32_is_any_nan(fst0)) {
734             dt2 = 0;
735         }
736     }
737     update_fcr31(env, GETPC());
738     return dt2;
739 }
740 
helper_float_round_2008_w_d(CPUMIPSState * env,uint64_t fdt0)741 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
742 {
743     uint32_t wt2;
744 
745     set_float_rounding_mode(float_round_nearest_even,
746             &env->active_fpu.fp_status);
747     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
748     restore_rounding_mode(env);
749     if (get_float_exception_flags(&env->active_fpu.fp_status)
750             & float_flag_invalid) {
751         if (float64_is_any_nan(fdt0)) {
752             wt2 = 0;
753         }
754     }
755     update_fcr31(env, GETPC());
756     return wt2;
757 }
758 
helper_float_round_2008_w_s(CPUMIPSState * env,uint32_t fst0)759 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
760 {
761     uint32_t wt2;
762 
763     set_float_rounding_mode(float_round_nearest_even,
764             &env->active_fpu.fp_status);
765     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
766     restore_rounding_mode(env);
767     if (get_float_exception_flags(&env->active_fpu.fp_status)
768             & float_flag_invalid) {
769         if (float32_is_any_nan(fst0)) {
770             wt2 = 0;
771         }
772     }
773     update_fcr31(env, GETPC());
774     return wt2;
775 }
776 
helper_float_trunc_2008_l_d(CPUMIPSState * env,uint64_t fdt0)777 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
778 {
779     uint64_t dt2;
780 
781     dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
782     if (get_float_exception_flags(&env->active_fpu.fp_status)
783             & float_flag_invalid) {
784         if (float64_is_any_nan(fdt0)) {
785             dt2 = 0;
786         }
787     }
788     update_fcr31(env, GETPC());
789     return dt2;
790 }
791 
helper_float_trunc_2008_l_s(CPUMIPSState * env,uint32_t fst0)792 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
793 {
794     uint64_t dt2;
795 
796     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
797     if (get_float_exception_flags(&env->active_fpu.fp_status)
798             & float_flag_invalid) {
799         if (float32_is_any_nan(fst0)) {
800             dt2 = 0;
801         }
802     }
803     update_fcr31(env, GETPC());
804     return dt2;
805 }
806 
helper_float_trunc_2008_w_d(CPUMIPSState * env,uint64_t fdt0)807 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
808 {
809     uint32_t wt2;
810 
811     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
812     if (get_float_exception_flags(&env->active_fpu.fp_status)
813             & float_flag_invalid) {
814         if (float64_is_any_nan(fdt0)) {
815             wt2 = 0;
816         }
817     }
818     update_fcr31(env, GETPC());
819     return wt2;
820 }
821 
helper_float_trunc_2008_w_s(CPUMIPSState * env,uint32_t fst0)822 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
823 {
824     uint32_t wt2;
825 
826     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
827     if (get_float_exception_flags(&env->active_fpu.fp_status)
828             & float_flag_invalid) {
829         if (float32_is_any_nan(fst0)) {
830             wt2 = 0;
831         }
832     }
833     update_fcr31(env, GETPC());
834     return wt2;
835 }
836 
helper_float_ceil_2008_l_d(CPUMIPSState * env,uint64_t fdt0)837 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
838 {
839     uint64_t dt2;
840 
841     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
842     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
843     restore_rounding_mode(env);
844     if (get_float_exception_flags(&env->active_fpu.fp_status)
845             & float_flag_invalid) {
846         if (float64_is_any_nan(fdt0)) {
847             dt2 = 0;
848         }
849     }
850     update_fcr31(env, GETPC());
851     return dt2;
852 }
853 
helper_float_ceil_2008_l_s(CPUMIPSState * env,uint32_t fst0)854 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
855 {
856     uint64_t dt2;
857 
858     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
859     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
860     restore_rounding_mode(env);
861     if (get_float_exception_flags(&env->active_fpu.fp_status)
862             & float_flag_invalid) {
863         if (float32_is_any_nan(fst0)) {
864             dt2 = 0;
865         }
866     }
867     update_fcr31(env, GETPC());
868     return dt2;
869 }
870 
helper_float_ceil_2008_w_d(CPUMIPSState * env,uint64_t fdt0)871 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
872 {
873     uint32_t wt2;
874 
875     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
876     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
877     restore_rounding_mode(env);
878     if (get_float_exception_flags(&env->active_fpu.fp_status)
879             & float_flag_invalid) {
880         if (float64_is_any_nan(fdt0)) {
881             wt2 = 0;
882         }
883     }
884     update_fcr31(env, GETPC());
885     return wt2;
886 }
887 
helper_float_ceil_2008_w_s(CPUMIPSState * env,uint32_t fst0)888 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
889 {
890     uint32_t wt2;
891 
892     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
893     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
894     restore_rounding_mode(env);
895     if (get_float_exception_flags(&env->active_fpu.fp_status)
896             & float_flag_invalid) {
897         if (float32_is_any_nan(fst0)) {
898             wt2 = 0;
899         }
900     }
901     update_fcr31(env, GETPC());
902     return wt2;
903 }
904 
helper_float_floor_2008_l_d(CPUMIPSState * env,uint64_t fdt0)905 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
906 {
907     uint64_t dt2;
908 
909     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
910     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
911     restore_rounding_mode(env);
912     if (get_float_exception_flags(&env->active_fpu.fp_status)
913             & float_flag_invalid) {
914         if (float64_is_any_nan(fdt0)) {
915             dt2 = 0;
916         }
917     }
918     update_fcr31(env, GETPC());
919     return dt2;
920 }
921 
helper_float_floor_2008_l_s(CPUMIPSState * env,uint32_t fst0)922 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
923 {
924     uint64_t dt2;
925 
926     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
927     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
928     restore_rounding_mode(env);
929     if (get_float_exception_flags(&env->active_fpu.fp_status)
930             & float_flag_invalid) {
931         if (float32_is_any_nan(fst0)) {
932             dt2 = 0;
933         }
934     }
935     update_fcr31(env, GETPC());
936     return dt2;
937 }
938 
helper_float_floor_2008_w_d(CPUMIPSState * env,uint64_t fdt0)939 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
940 {
941     uint32_t wt2;
942 
943     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
944     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
945     restore_rounding_mode(env);
946     if (get_float_exception_flags(&env->active_fpu.fp_status)
947             & float_flag_invalid) {
948         if (float64_is_any_nan(fdt0)) {
949             wt2 = 0;
950         }
951     }
952     update_fcr31(env, GETPC());
953     return wt2;
954 }
955 
helper_float_floor_2008_w_s(CPUMIPSState * env,uint32_t fst0)956 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
957 {
958     uint32_t wt2;
959 
960     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
961     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
962     restore_rounding_mode(env);
963     if (get_float_exception_flags(&env->active_fpu.fp_status)
964             & float_flag_invalid) {
965         if (float32_is_any_nan(fst0)) {
966             wt2 = 0;
967         }
968     }
969     update_fcr31(env, GETPC());
970     return wt2;
971 }
972 
973 /* unary operations, not modifying fp status  */
974 
helper_float_abs_d(uint64_t fdt0)975 uint64_t helper_float_abs_d(uint64_t fdt0)
976 {
977    return float64_abs(fdt0);
978 }
979 
helper_float_abs_s(uint32_t fst0)980 uint32_t helper_float_abs_s(uint32_t fst0)
981 {
982     return float32_abs(fst0);
983 }
984 
helper_float_abs_ps(uint64_t fdt0)985 uint64_t helper_float_abs_ps(uint64_t fdt0)
986 {
987     uint32_t wt0;
988     uint32_t wth0;
989 
990     wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
991     wth0 = float32_abs(fdt0 >> 32);
992     return ((uint64_t)wth0 << 32) | wt0;
993 }
994 
helper_float_chs_d(uint64_t fdt0)995 uint64_t helper_float_chs_d(uint64_t fdt0)
996 {
997    return float64_chs(fdt0);
998 }
999 
helper_float_chs_s(uint32_t fst0)1000 uint32_t helper_float_chs_s(uint32_t fst0)
1001 {
1002     return float32_chs(fst0);
1003 }
1004 
helper_float_chs_ps(uint64_t fdt0)1005 uint64_t helper_float_chs_ps(uint64_t fdt0)
1006 {
1007     uint32_t wt0;
1008     uint32_t wth0;
1009 
1010     wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
1011     wth0 = float32_chs(fdt0 >> 32);
1012     return ((uint64_t)wth0 << 32) | wt0;
1013 }
1014 
1015 /* MIPS specific unary operations */
helper_float_recip_d(CPUMIPSState * env,uint64_t fdt0)1016 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1017 {
1018     uint64_t fdt2;
1019 
1020     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1021     update_fcr31(env, GETPC());
1022     return fdt2;
1023 }
1024 
helper_float_recip_s(CPUMIPSState * env,uint32_t fst0)1025 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1026 {
1027     uint32_t fst2;
1028 
1029     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1030     update_fcr31(env, GETPC());
1031     return fst2;
1032 }
1033 
helper_float_rsqrt_d(CPUMIPSState * env,uint64_t fdt0)1034 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1035 {
1036     uint64_t fdt2;
1037 
1038     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1039     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1040     update_fcr31(env, GETPC());
1041     return fdt2;
1042 }
1043 
helper_float_rsqrt_s(CPUMIPSState * env,uint32_t fst0)1044 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1045 {
1046     uint32_t fst2;
1047 
1048     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1049     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1050     update_fcr31(env, GETPC());
1051     return fst2;
1052 }
1053 
helper_float_recip1_d(CPUMIPSState * env,uint64_t fdt0)1054 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1055 {
1056     uint64_t fdt2;
1057 
1058     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1059     update_fcr31(env, GETPC());
1060     return fdt2;
1061 }
1062 
helper_float_recip1_s(CPUMIPSState * env,uint32_t fst0)1063 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1064 {
1065     uint32_t fst2;
1066 
1067     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1068     update_fcr31(env, GETPC());
1069     return fst2;
1070 }
1071 
helper_float_recip1_ps(CPUMIPSState * env,uint64_t fdt0)1072 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1073 {
1074     uint32_t fstl2;
1075     uint32_t fsth2;
1076 
1077     fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
1078                         &env->active_fpu.fp_status);
1079     fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
1080     update_fcr31(env, GETPC());
1081     return ((uint64_t)fsth2 << 32) | fstl2;
1082 }
1083 
helper_float_rsqrt1_d(CPUMIPSState * env,uint64_t fdt0)1084 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1085 {
1086     uint64_t fdt2;
1087 
1088     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1089     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1090     update_fcr31(env, GETPC());
1091     return fdt2;
1092 }
1093 
helper_float_rsqrt1_s(CPUMIPSState * env,uint32_t fst0)1094 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1095 {
1096     uint32_t fst2;
1097 
1098     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1099     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1100     update_fcr31(env, GETPC());
1101     return fst2;
1102 }
1103 
helper_float_rsqrt1_ps(CPUMIPSState * env,uint64_t fdt0)1104 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1105 {
1106     uint32_t fstl2;
1107     uint32_t fsth2;
1108 
1109     fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
1110     fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1111     fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
1112     fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
1113     update_fcr31(env, GETPC());
1114     return ((uint64_t)fsth2 << 32) | fstl2;
1115 }
1116 
helper_float_rint_d(CPUMIPSState * env,uint64_t fs)1117 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1118 {
1119     uint64_t fdret;
1120 
1121     fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1122     update_fcr31(env, GETPC());
1123     return fdret;
1124 }
1125 
helper_float_rint_s(CPUMIPSState * env,uint32_t fs)1126 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1127 {
1128     uint32_t fdret;
1129 
1130     fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1131     update_fcr31(env, GETPC());
1132     return fdret;
1133 }
1134 
1135 #define FLOAT_CLASS_SIGNALING_NAN      0x001
1136 #define FLOAT_CLASS_QUIET_NAN          0x002
1137 #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
1138 #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
1139 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1140 #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
1141 #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
1142 #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
1143 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1144 #define FLOAT_CLASS_POSITIVE_ZERO      0x200
1145 
float_class_d(uint64_t arg,float_status * status)1146 uint64_t float_class_d(uint64_t arg, float_status *status)
1147 {
1148     if (float64_is_signaling_nan(arg, status)) {
1149         return FLOAT_CLASS_SIGNALING_NAN;
1150     } else if (float64_is_quiet_nan(arg, status)) {
1151         return FLOAT_CLASS_QUIET_NAN;
1152     } else if (float64_is_neg(arg)) {
1153         if (float64_is_infinity(arg)) {
1154             return FLOAT_CLASS_NEGATIVE_INFINITY;
1155         } else if (float64_is_zero(arg)) {
1156             return FLOAT_CLASS_NEGATIVE_ZERO;
1157         } else if (float64_is_zero_or_denormal(arg)) {
1158             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1159         } else {
1160             return FLOAT_CLASS_NEGATIVE_NORMAL;
1161         }
1162     } else {
1163         if (float64_is_infinity(arg)) {
1164             return FLOAT_CLASS_POSITIVE_INFINITY;
1165         } else if (float64_is_zero(arg)) {
1166             return FLOAT_CLASS_POSITIVE_ZERO;
1167         } else if (float64_is_zero_or_denormal(arg)) {
1168             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1169         } else {
1170             return FLOAT_CLASS_POSITIVE_NORMAL;
1171         }
1172     }
1173 }
1174 
helper_float_class_d(CPUMIPSState * env,uint64_t arg)1175 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1176 {
1177     return float_class_d(arg, &env->active_fpu.fp_status);
1178 }
1179 
float_class_s(uint32_t arg,float_status * status)1180 uint32_t float_class_s(uint32_t arg, float_status *status)
1181 {
1182     if (float32_is_signaling_nan(arg, status)) {
1183         return FLOAT_CLASS_SIGNALING_NAN;
1184     } else if (float32_is_quiet_nan(arg, status)) {
1185         return FLOAT_CLASS_QUIET_NAN;
1186     } else if (float32_is_neg(arg)) {
1187         if (float32_is_infinity(arg)) {
1188             return FLOAT_CLASS_NEGATIVE_INFINITY;
1189         } else if (float32_is_zero(arg)) {
1190             return FLOAT_CLASS_NEGATIVE_ZERO;
1191         } else if (float32_is_zero_or_denormal(arg)) {
1192             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1193         } else {
1194             return FLOAT_CLASS_NEGATIVE_NORMAL;
1195         }
1196     } else {
1197         if (float32_is_infinity(arg)) {
1198             return FLOAT_CLASS_POSITIVE_INFINITY;
1199         } else if (float32_is_zero(arg)) {
1200             return FLOAT_CLASS_POSITIVE_ZERO;
1201         } else if (float32_is_zero_or_denormal(arg)) {
1202             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1203         } else {
1204             return FLOAT_CLASS_POSITIVE_NORMAL;
1205         }
1206     }
1207 }
1208 
helper_float_class_s(CPUMIPSState * env,uint32_t arg)1209 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1210 {
1211     return float_class_s(arg, &env->active_fpu.fp_status);
1212 }
1213 
1214 /* binary operations */
1215 
helper_float_add_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1216 uint64_t helper_float_add_d(CPUMIPSState *env,
1217                             uint64_t fdt0, uint64_t fdt1)
1218 {
1219     uint64_t dt2;
1220 
1221     dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1222     update_fcr31(env, GETPC());
1223     return dt2;
1224 }
1225 
helper_float_add_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1226 uint32_t helper_float_add_s(CPUMIPSState *env,
1227                             uint32_t fst0, uint32_t fst1)
1228 {
1229     uint32_t wt2;
1230 
1231     wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
1232     update_fcr31(env, GETPC());
1233     return wt2;
1234 }
1235 
helper_float_add_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1236 uint64_t helper_float_add_ps(CPUMIPSState *env,
1237                              uint64_t fdt0, uint64_t fdt1)
1238 {
1239     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1240     uint32_t fsth0 = fdt0 >> 32;
1241     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1242     uint32_t fsth1 = fdt1 >> 32;
1243     uint32_t wtl2;
1244     uint32_t wth2;
1245 
1246     wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
1247     wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
1248     update_fcr31(env, GETPC());
1249     return ((uint64_t)wth2 << 32) | wtl2;
1250 }
1251 
helper_float_sub_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1252 uint64_t helper_float_sub_d(CPUMIPSState *env,
1253                             uint64_t fdt0, uint64_t fdt1)
1254 {
1255     uint64_t dt2;
1256 
1257     dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1258     update_fcr31(env, GETPC());
1259     return dt2;
1260 }
1261 
helper_float_sub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1262 uint32_t helper_float_sub_s(CPUMIPSState *env,
1263                             uint32_t fst0, uint32_t fst1)
1264 {
1265     uint32_t wt2;
1266 
1267     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1268     update_fcr31(env, GETPC());
1269     return wt2;
1270 }
1271 
helper_float_sub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1272 uint64_t helper_float_sub_ps(CPUMIPSState *env,
1273                              uint64_t fdt0, uint64_t fdt1)
1274 {
1275     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1276     uint32_t fsth0 = fdt0 >> 32;
1277     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1278     uint32_t fsth1 = fdt1 >> 32;
1279     uint32_t wtl2;
1280     uint32_t wth2;
1281 
1282     wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1283     wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1284     update_fcr31(env, GETPC());
1285     return ((uint64_t)wth2 << 32) | wtl2;
1286 }
1287 
helper_float_mul_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1288 uint64_t helper_float_mul_d(CPUMIPSState *env,
1289                             uint64_t fdt0, uint64_t fdt1)
1290 {
1291     uint64_t dt2;
1292 
1293     dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1294     update_fcr31(env, GETPC());
1295     return dt2;
1296 }
1297 
helper_float_mul_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1298 uint32_t helper_float_mul_s(CPUMIPSState *env,
1299                             uint32_t fst0, uint32_t fst1)
1300 {
1301     uint32_t wt2;
1302 
1303     wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1304     update_fcr31(env, GETPC());
1305     return wt2;
1306 }
1307 
helper_float_mul_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1308 uint64_t helper_float_mul_ps(CPUMIPSState *env,
1309                              uint64_t fdt0, uint64_t fdt1)
1310 {
1311     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1312     uint32_t fsth0 = fdt0 >> 32;
1313     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1314     uint32_t fsth1 = fdt1 >> 32;
1315     uint32_t wtl2;
1316     uint32_t wth2;
1317 
1318     wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1319     wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1320     update_fcr31(env, GETPC());
1321     return ((uint64_t)wth2 << 32) | wtl2;
1322 }
1323 
helper_float_div_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1324 uint64_t helper_float_div_d(CPUMIPSState *env,
1325                             uint64_t fdt0, uint64_t fdt1)
1326 {
1327     uint64_t dt2;
1328 
1329     dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1330     update_fcr31(env, GETPC());
1331     return dt2;
1332 }
1333 
helper_float_div_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1334 uint32_t helper_float_div_s(CPUMIPSState *env,
1335                             uint32_t fst0, uint32_t fst1)
1336 {
1337     uint32_t wt2;
1338 
1339     wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1340     update_fcr31(env, GETPC());
1341     return wt2;
1342 }
1343 
helper_float_div_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1344 uint64_t helper_float_div_ps(CPUMIPSState *env,
1345                              uint64_t fdt0, uint64_t fdt1)
1346 {
1347     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1348     uint32_t fsth0 = fdt0 >> 32;
1349     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1350     uint32_t fsth1 = fdt1 >> 32;
1351     uint32_t wtl2;
1352     uint32_t wth2;
1353 
1354     wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1355     wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1356     update_fcr31(env, GETPC());
1357     return ((uint64_t)wth2 << 32) | wtl2;
1358 }
1359 
1360 
1361 /* MIPS specific binary operations */
helper_float_recip2_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1362 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1363 {
1364     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1365     fdt2 = float64_chs(float64_sub(fdt2, float64_one,
1366                                    &env->active_fpu.fp_status));
1367     update_fcr31(env, GETPC());
1368     return fdt2;
1369 }
1370 
helper_float_recip2_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst2)1371 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1372 {
1373     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1374     fst2 = float32_chs(float32_sub(fst2, float32_one,
1375                                        &env->active_fpu.fp_status));
1376     update_fcr31(env, GETPC());
1377     return fst2;
1378 }
1379 
helper_float_recip2_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1380 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1381 {
1382     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1383     uint32_t fsth0 = fdt0 >> 32;
1384     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1385     uint32_t fsth2 = fdt2 >> 32;
1386 
1387     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1388     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1389     fstl2 = float32_chs(float32_sub(fstl2, float32_one,
1390                                        &env->active_fpu.fp_status));
1391     fsth2 = float32_chs(float32_sub(fsth2, float32_one,
1392                                        &env->active_fpu.fp_status));
1393     update_fcr31(env, GETPC());
1394     return ((uint64_t)fsth2 << 32) | fstl2;
1395 }
1396 
helper_float_rsqrt2_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1397 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1398 {
1399     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1400     fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
1401     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
1402                                        &env->active_fpu.fp_status));
1403     update_fcr31(env, GETPC());
1404     return fdt2;
1405 }
1406 
helper_float_rsqrt2_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst2)1407 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1408 {
1409     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1410     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
1411     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
1412                                        &env->active_fpu.fp_status));
1413     update_fcr31(env, GETPC());
1414     return fst2;
1415 }
1416 
helper_float_rsqrt2_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1417 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1418 {
1419     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1420     uint32_t fsth0 = fdt0 >> 32;
1421     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1422     uint32_t fsth2 = fdt2 >> 32;
1423 
1424     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1425     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1426     fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
1427     fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1428     fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
1429                                        &env->active_fpu.fp_status));
1430     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
1431                                        &env->active_fpu.fp_status));
1432     update_fcr31(env, GETPC());
1433     return ((uint64_t)fsth2 << 32) | fstl2;
1434 }
1435 
helper_float_addr_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1436 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1437 {
1438     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1439     uint32_t fsth0 = fdt0 >> 32;
1440     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1441     uint32_t fsth1 = fdt1 >> 32;
1442     uint32_t fstl2;
1443     uint32_t fsth2;
1444 
1445     fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1446     fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
1447     update_fcr31(env, GETPC());
1448     return ((uint64_t)fsth2 << 32) | fstl2;
1449 }
1450 
helper_float_mulr_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1451 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1452 {
1453     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1454     uint32_t fsth0 = fdt0 >> 32;
1455     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1456     uint32_t fsth1 = fdt1 >> 32;
1457     uint32_t fstl2;
1458     uint32_t fsth2;
1459 
1460     fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1461     fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
1462     update_fcr31(env, GETPC());
1463     return ((uint64_t)fsth2 << 32) | fstl2;
1464 }
1465 
1466 
helper_float_max_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1467 uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1468 {
1469     uint32_t fdret;
1470 
1471     fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
1472 
1473     update_fcr31(env, GETPC());
1474     return fdret;
1475 }
1476 
helper_float_max_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1477 uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1478 {
1479     uint64_t fdret;
1480 
1481     fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
1482 
1483     update_fcr31(env, GETPC());
1484     return fdret;
1485 }
1486 
helper_float_maxa_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1487 uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1488 {
1489     uint32_t fdret;
1490 
1491     fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
1492 
1493     update_fcr31(env, GETPC());
1494     return fdret;
1495 }
1496 
helper_float_maxa_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1497 uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1498 {
1499     uint64_t fdret;
1500 
1501     fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
1502 
1503     update_fcr31(env, GETPC());
1504     return fdret;
1505 }
1506 
helper_float_min_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1507 uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1508 {
1509     uint32_t fdret;
1510 
1511     fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
1512 
1513     update_fcr31(env, GETPC());
1514     return fdret;
1515 }
1516 
helper_float_min_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1517 uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1518 {
1519     uint64_t fdret;
1520 
1521     fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
1522 
1523     update_fcr31(env, GETPC());
1524     return fdret;
1525 }
1526 
helper_float_mina_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1527 uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1528 {
1529     uint32_t fdret;
1530 
1531     fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
1532 
1533     update_fcr31(env, GETPC());
1534     return fdret;
1535 }
1536 
helper_float_mina_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1537 uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1538 {
1539     uint64_t fdret;
1540 
1541     fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
1542 
1543     update_fcr31(env, GETPC());
1544     return fdret;
1545 }
1546 
1547 
1548 /* ternary operations */
1549 
helper_float_madd_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1550 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1551                              uint64_t fst1, uint64_t fst2)
1552 {
1553     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1554     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1555 
1556     update_fcr31(env, GETPC());
1557     return fst0;
1558 }
1559 
helper_float_madd_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1560 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1561                              uint32_t fst1, uint32_t fst2)
1562 {
1563     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1564     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1565 
1566     update_fcr31(env, GETPC());
1567     return fst0;
1568 }
1569 
helper_float_madd_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1570 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1571                               uint64_t fdt1, uint64_t fdt2)
1572 {
1573     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1574     uint32_t fsth0 = fdt0 >> 32;
1575     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1576     uint32_t fsth1 = fdt1 >> 32;
1577     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1578     uint32_t fsth2 = fdt2 >> 32;
1579 
1580     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1581     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1582     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1583     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1584 
1585     update_fcr31(env, GETPC());
1586     return ((uint64_t)fsth0 << 32) | fstl0;
1587 }
1588 
helper_float_msub_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1589 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1590                              uint64_t fst1, uint64_t fst2)
1591 {
1592     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1593     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1594 
1595     update_fcr31(env, GETPC());
1596     return fst0;
1597 }
1598 
helper_float_msub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1599 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1600                              uint32_t fst1, uint32_t fst2)
1601 {
1602     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1603     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1604 
1605     update_fcr31(env, GETPC());
1606     return fst0;
1607 }
1608 
helper_float_msub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1609 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1610                               uint64_t fdt1, uint64_t fdt2)
1611 {
1612     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1613     uint32_t fsth0 = fdt0 >> 32;
1614     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1615     uint32_t fsth1 = fdt1 >> 32;
1616     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1617     uint32_t fsth2 = fdt2 >> 32;
1618 
1619     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1620     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1621     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1622     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1623 
1624     update_fcr31(env, GETPC());
1625     return ((uint64_t)fsth0 << 32) | fstl0;
1626 }
1627 
helper_float_nmadd_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1628 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1629                              uint64_t fst1, uint64_t fst2)
1630 {
1631     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1632     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1633     fst0 = float64_chs(fst0);
1634 
1635     update_fcr31(env, GETPC());
1636     return fst0;
1637 }
1638 
helper_float_nmadd_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1639 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1640                              uint32_t fst1, uint32_t fst2)
1641 {
1642     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1643     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1644     fst0 = float32_chs(fst0);
1645 
1646     update_fcr31(env, GETPC());
1647     return fst0;
1648 }
1649 
helper_float_nmadd_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1650 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1651                               uint64_t fdt1, uint64_t fdt2)
1652 {
1653     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1654     uint32_t fsth0 = fdt0 >> 32;
1655     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1656     uint32_t fsth1 = fdt1 >> 32;
1657     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1658     uint32_t fsth2 = fdt2 >> 32;
1659 
1660     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1661     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1662     fstl0 = float32_chs(fstl0);
1663     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1664     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1665     fsth0 = float32_chs(fsth0);
1666 
1667     update_fcr31(env, GETPC());
1668     return ((uint64_t)fsth0 << 32) | fstl0;
1669 }
1670 
helper_float_nmsub_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1671 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1672                              uint64_t fst1, uint64_t fst2)
1673 {
1674     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1675     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1676     fst0 = float64_chs(fst0);
1677 
1678     update_fcr31(env, GETPC());
1679     return fst0;
1680 }
1681 
helper_float_nmsub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1682 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1683                              uint32_t fst1, uint32_t fst2)
1684 {
1685     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1686     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1687     fst0 = float32_chs(fst0);
1688 
1689     update_fcr31(env, GETPC());
1690     return fst0;
1691 }
1692 
helper_float_nmsub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1693 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1694                               uint64_t fdt1, uint64_t fdt2)
1695 {
1696     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1697     uint32_t fsth0 = fdt0 >> 32;
1698     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1699     uint32_t fsth1 = fdt1 >> 32;
1700     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1701     uint32_t fsth2 = fdt2 >> 32;
1702 
1703     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1704     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1705     fstl0 = float32_chs(fstl0);
1706     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1707     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1708     fsth0 = float32_chs(fsth0);
1709 
1710     update_fcr31(env, GETPC());
1711     return ((uint64_t)fsth0 << 32) | fstl0;
1712 }
1713 
1714 
helper_float_maddf_s(CPUMIPSState * env,uint32_t fs,uint32_t ft,uint32_t fd)1715 uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
1716                               uint32_t ft, uint32_t fd)
1717 {
1718     uint32_t fdret;
1719 
1720     fdret = float32_muladd(fs, ft, fd, 0,
1721                            &env->active_fpu.fp_status);
1722 
1723     update_fcr31(env, GETPC());
1724     return fdret;
1725 }
1726 
helper_float_maddf_d(CPUMIPSState * env,uint64_t fs,uint64_t ft,uint64_t fd)1727 uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
1728                               uint64_t ft, uint64_t fd)
1729 {
1730     uint64_t fdret;
1731 
1732     fdret = float64_muladd(fs, ft, fd, 0,
1733                            &env->active_fpu.fp_status);
1734 
1735     update_fcr31(env, GETPC());
1736     return fdret;
1737 }
1738 
helper_float_msubf_s(CPUMIPSState * env,uint32_t fs,uint32_t ft,uint32_t fd)1739 uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
1740                               uint32_t ft, uint32_t fd)
1741 {
1742     uint32_t fdret;
1743 
1744     fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
1745                            &env->active_fpu.fp_status);
1746 
1747     update_fcr31(env, GETPC());
1748     return fdret;
1749 }
1750 
helper_float_msubf_d(CPUMIPSState * env,uint64_t fs,uint64_t ft,uint64_t fd)1751 uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
1752                               uint64_t ft, uint64_t fd)
1753 {
1754     uint64_t fdret;
1755 
1756     fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
1757                            &env->active_fpu.fp_status);
1758 
1759     update_fcr31(env, GETPC());
1760     return fdret;
1761 }
1762 
1763 
1764 /* compare operations */
1765 #define FOP_COND_D(op, cond)                                   \
1766 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
1767                          uint64_t fdt1, int cc)                \
1768 {                                                              \
1769     int c;                                                     \
1770     c = cond;                                                  \
1771     update_fcr31(env, GETPC());                                \
1772     if (c)                                                     \
1773         SET_FP_COND(cc, env->active_fpu);                      \
1774     else                                                       \
1775         CLEAR_FP_COND(cc, env->active_fpu);                    \
1776 }                                                              \
1777 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
1778                             uint64_t fdt1, int cc)             \
1779 {                                                              \
1780     int c;                                                     \
1781     fdt0 = float64_abs(fdt0);                                  \
1782     fdt1 = float64_abs(fdt1);                                  \
1783     c = cond;                                                  \
1784     update_fcr31(env, GETPC());                                \
1785     if (c)                                                     \
1786         SET_FP_COND(cc, env->active_fpu);                      \
1787     else                                                       \
1788         CLEAR_FP_COND(cc, env->active_fpu);                    \
1789 }
1790 
1791 /*
1792  * NOTE: the comma operator will make "cond" to eval to false,
1793  * but float64_unordered_quiet() is still called.
1794  */
1795 FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
1796                                        &env->active_fpu.fp_status), 0))
1797 FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
1798                                        &env->active_fpu.fp_status))
1799 FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
1800                                        &env->active_fpu.fp_status))
1801 FOP_COND_D(ueq,  float64_unordered_quiet(fdt1, fdt0,
1802                                        &env->active_fpu.fp_status)
1803                  || float64_eq_quiet(fdt0, fdt1,
1804                                        &env->active_fpu.fp_status))
1805 FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
1806                                        &env->active_fpu.fp_status))
1807 FOP_COND_D(ult,  float64_unordered_quiet(fdt1, fdt0,
1808                                        &env->active_fpu.fp_status)
1809                  || float64_lt_quiet(fdt0, fdt1,
1810                                        &env->active_fpu.fp_status))
1811 FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
1812                                        &env->active_fpu.fp_status))
1813 FOP_COND_D(ule,  float64_unordered_quiet(fdt1, fdt0,
1814                                        &env->active_fpu.fp_status)
1815                  || float64_le_quiet(fdt0, fdt1,
1816                                        &env->active_fpu.fp_status))
1817 /*
1818  * NOTE: the comma operator will make "cond" to eval to false,
1819  * but float64_unordered() is still called.
1820  */
1821 FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
1822                                        &env->active_fpu.fp_status), 0))
1823 FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
1824                                        &env->active_fpu.fp_status))
1825 FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
1826                                        &env->active_fpu.fp_status))
1827 FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
1828                                        &env->active_fpu.fp_status)
1829                  || float64_eq(fdt0, fdt1,
1830                                        &env->active_fpu.fp_status))
1831 FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
1832                                        &env->active_fpu.fp_status))
1833 FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
1834                                        &env->active_fpu.fp_status)
1835                  || float64_lt(fdt0, fdt1,
1836                                        &env->active_fpu.fp_status))
1837 FOP_COND_D(le,   float64_le(fdt0, fdt1,
1838                                        &env->active_fpu.fp_status))
1839 FOP_COND_D(ngt,  float64_unordered(fdt1, fdt0,
1840                                        &env->active_fpu.fp_status)
1841                  || float64_le(fdt0, fdt1,
1842                                        &env->active_fpu.fp_status))
1843 
1844 #define FOP_COND_S(op, cond)                                   \
1845 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
1846                          uint32_t fst1, int cc)                \
1847 {                                                              \
1848     int c;                                                     \
1849     c = cond;                                                  \
1850     update_fcr31(env, GETPC());                                \
1851     if (c)                                                     \
1852         SET_FP_COND(cc, env->active_fpu);                      \
1853     else                                                       \
1854         CLEAR_FP_COND(cc, env->active_fpu);                    \
1855 }                                                              \
1856 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
1857                             uint32_t fst1, int cc)             \
1858 {                                                              \
1859     int c;                                                     \
1860     fst0 = float32_abs(fst0);                                  \
1861     fst1 = float32_abs(fst1);                                  \
1862     c = cond;                                                  \
1863     update_fcr31(env, GETPC());                                \
1864     if (c)                                                     \
1865         SET_FP_COND(cc, env->active_fpu);                      \
1866     else                                                       \
1867         CLEAR_FP_COND(cc, env->active_fpu);                    \
1868 }
1869 
1870 /*
1871  * NOTE: the comma operator will make "cond" to eval to false,
1872  * but float32_unordered_quiet() is still called.
1873  */
1874 FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
1875                                        &env->active_fpu.fp_status), 0))
1876 FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
1877                                        &env->active_fpu.fp_status))
1878 FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
1879                                        &env->active_fpu.fp_status))
1880 FOP_COND_S(ueq,  float32_unordered_quiet(fst1, fst0,
1881                                        &env->active_fpu.fp_status)
1882                  || float32_eq_quiet(fst0, fst1,
1883                                        &env->active_fpu.fp_status))
1884 FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
1885                                        &env->active_fpu.fp_status))
1886 FOP_COND_S(ult,  float32_unordered_quiet(fst1, fst0,
1887                                        &env->active_fpu.fp_status)
1888                  || float32_lt_quiet(fst0, fst1,
1889                                        &env->active_fpu.fp_status))
1890 FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
1891                                        &env->active_fpu.fp_status))
1892 FOP_COND_S(ule,  float32_unordered_quiet(fst1, fst0,
1893                                        &env->active_fpu.fp_status)
1894                  || float32_le_quiet(fst0, fst1,
1895                                        &env->active_fpu.fp_status))
1896 /*
1897  * NOTE: the comma operator will make "cond" to eval to false,
1898  * but float32_unordered() is still called.
1899  */
1900 FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
1901                                        &env->active_fpu.fp_status), 0))
1902 FOP_COND_S(ngle, float32_unordered(fst1, fst0,
1903                                        &env->active_fpu.fp_status))
1904 FOP_COND_S(seq,  float32_eq(fst0, fst1,
1905                                        &env->active_fpu.fp_status))
1906 FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
1907                                        &env->active_fpu.fp_status)
1908                  || float32_eq(fst0, fst1,
1909                                        &env->active_fpu.fp_status))
1910 FOP_COND_S(lt,   float32_lt(fst0, fst1,
1911                                        &env->active_fpu.fp_status))
1912 FOP_COND_S(nge,  float32_unordered(fst1, fst0,
1913                                        &env->active_fpu.fp_status)
1914                  || float32_lt(fst0, fst1,
1915                                        &env->active_fpu.fp_status))
1916 FOP_COND_S(le,   float32_le(fst0, fst1,
1917                                        &env->active_fpu.fp_status))
1918 FOP_COND_S(ngt,  float32_unordered(fst1, fst0,
1919                                        &env->active_fpu.fp_status)
1920                  || float32_le(fst0, fst1,
1921                                        &env->active_fpu.fp_status))
1922 
1923 #define FOP_COND_PS(op, condl, condh)                           \
1924 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
1925                           uint64_t fdt1, int cc)                \
1926 {                                                               \
1927     uint32_t fst0, fsth0, fst1, fsth1;                          \
1928     int ch, cl;                                                 \
1929     fst0 = fdt0 & 0XFFFFFFFF;                                   \
1930     fsth0 = fdt0 >> 32;                                         \
1931     fst1 = fdt1 & 0XFFFFFFFF;                                   \
1932     fsth1 = fdt1 >> 32;                                         \
1933     cl = condl;                                                 \
1934     ch = condh;                                                 \
1935     update_fcr31(env, GETPC());                                 \
1936     if (cl)                                                     \
1937         SET_FP_COND(cc, env->active_fpu);                       \
1938     else                                                        \
1939         CLEAR_FP_COND(cc, env->active_fpu);                     \
1940     if (ch)                                                     \
1941         SET_FP_COND(cc + 1, env->active_fpu);                   \
1942     else                                                        \
1943         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
1944 }                                                               \
1945 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
1946                              uint64_t fdt1, int cc)             \
1947 {                                                               \
1948     uint32_t fst0, fsth0, fst1, fsth1;                          \
1949     int ch, cl;                                                 \
1950     fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
1951     fsth0 = float32_abs(fdt0 >> 32);                            \
1952     fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
1953     fsth1 = float32_abs(fdt1 >> 32);                            \
1954     cl = condl;                                                 \
1955     ch = condh;                                                 \
1956     update_fcr31(env, GETPC());                                 \
1957     if (cl)                                                     \
1958         SET_FP_COND(cc, env->active_fpu);                       \
1959     else                                                        \
1960         CLEAR_FP_COND(cc, env->active_fpu);                     \
1961     if (ch)                                                     \
1962         SET_FP_COND(cc + 1, env->active_fpu);                   \
1963     else                                                        \
1964         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
1965 }
1966 
1967 /*
1968  * NOTE: the comma operator will make "cond" to eval to false,
1969  * but float32_unordered_quiet() is still called.
1970  */
1971 FOP_COND_PS(f,    (float32_unordered_quiet(fst1, fst0,
1972                                        &env->active_fpu.fp_status), 0),
1973                   (float32_unordered_quiet(fsth1, fsth0,
1974                                        &env->active_fpu.fp_status), 0))
1975 FOP_COND_PS(un,   float32_unordered_quiet(fst1, fst0,
1976                                        &env->active_fpu.fp_status),
1977                   float32_unordered_quiet(fsth1, fsth0,
1978                                        &env->active_fpu.fp_status))
1979 FOP_COND_PS(eq,   float32_eq_quiet(fst0, fst1,
1980                                        &env->active_fpu.fp_status),
1981                   float32_eq_quiet(fsth0, fsth1,
1982                                        &env->active_fpu.fp_status))
1983 FOP_COND_PS(ueq,  float32_unordered_quiet(fst1, fst0,
1984                                        &env->active_fpu.fp_status)
1985                   || float32_eq_quiet(fst0, fst1,
1986                                        &env->active_fpu.fp_status),
1987                   float32_unordered_quiet(fsth1, fsth0,
1988                                        &env->active_fpu.fp_status)
1989                   || float32_eq_quiet(fsth0, fsth1,
1990                                        &env->active_fpu.fp_status))
1991 FOP_COND_PS(olt,  float32_lt_quiet(fst0, fst1,
1992                                        &env->active_fpu.fp_status),
1993                   float32_lt_quiet(fsth0, fsth1,
1994                                        &env->active_fpu.fp_status))
1995 FOP_COND_PS(ult,  float32_unordered_quiet(fst1, fst0,
1996                                        &env->active_fpu.fp_status)
1997                   || float32_lt_quiet(fst0, fst1,
1998                                        &env->active_fpu.fp_status),
1999                   float32_unordered_quiet(fsth1, fsth0,
2000                                        &env->active_fpu.fp_status)
2001                   || float32_lt_quiet(fsth0, fsth1,
2002                                        &env->active_fpu.fp_status))
2003 FOP_COND_PS(ole,  float32_le_quiet(fst0, fst1,
2004                                        &env->active_fpu.fp_status),
2005                   float32_le_quiet(fsth0, fsth1,
2006                                        &env->active_fpu.fp_status))
2007 FOP_COND_PS(ule,  float32_unordered_quiet(fst1, fst0,
2008                                        &env->active_fpu.fp_status)
2009                   || float32_le_quiet(fst0, fst1,
2010                                        &env->active_fpu.fp_status),
2011                   float32_unordered_quiet(fsth1, fsth0,
2012                                        &env->active_fpu.fp_status)
2013                   || float32_le_quiet(fsth0, fsth1,
2014                                        &env->active_fpu.fp_status))
2015 /*
2016  * NOTE: the comma operator will make "cond" to eval to false,
2017  * but float32_unordered() is still called.
2018  */
2019 FOP_COND_PS(sf,   (float32_unordered(fst1, fst0,
2020                                        &env->active_fpu.fp_status), 0),
2021                   (float32_unordered(fsth1, fsth0,
2022                                        &env->active_fpu.fp_status), 0))
2023 FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
2024                                        &env->active_fpu.fp_status),
2025                   float32_unordered(fsth1, fsth0,
2026                                        &env->active_fpu.fp_status))
2027 FOP_COND_PS(seq,  float32_eq(fst0, fst1,
2028                                        &env->active_fpu.fp_status),
2029                   float32_eq(fsth0, fsth1,
2030                                        &env->active_fpu.fp_status))
2031 FOP_COND_PS(ngl,  float32_unordered(fst1, fst0,
2032                                        &env->active_fpu.fp_status)
2033                   || float32_eq(fst0, fst1,
2034                                        &env->active_fpu.fp_status),
2035                   float32_unordered(fsth1, fsth0,
2036                                        &env->active_fpu.fp_status)
2037                   || float32_eq(fsth0, fsth1,
2038                                        &env->active_fpu.fp_status))
2039 FOP_COND_PS(lt,   float32_lt(fst0, fst1,
2040                                        &env->active_fpu.fp_status),
2041                   float32_lt(fsth0, fsth1,
2042                                        &env->active_fpu.fp_status))
2043 FOP_COND_PS(nge,  float32_unordered(fst1, fst0,
2044                                        &env->active_fpu.fp_status)
2045                   || float32_lt(fst0, fst1,
2046                                        &env->active_fpu.fp_status),
2047                   float32_unordered(fsth1, fsth0,
2048                                        &env->active_fpu.fp_status)
2049                   || float32_lt(fsth0, fsth1,
2050                                        &env->active_fpu.fp_status))
2051 FOP_COND_PS(le,   float32_le(fst0, fst1,
2052                                        &env->active_fpu.fp_status),
2053                   float32_le(fsth0, fsth1,
2054                                        &env->active_fpu.fp_status))
2055 FOP_COND_PS(ngt,  float32_unordered(fst1, fst0,
2056                                        &env->active_fpu.fp_status)
2057                   || float32_le(fst0, fst1,
2058                                        &env->active_fpu.fp_status),
2059                   float32_unordered(fsth1, fsth0,
2060                                        &env->active_fpu.fp_status)
2061                   || float32_le(fsth0, fsth1,
2062                                        &env->active_fpu.fp_status))
2063 
2064 /* R6 compare operations */
2065 #define FOP_CONDN_D(op, cond)                                       \
2066 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,   \
2067                                 uint64_t fdt1)                      \
2068 {                                                                   \
2069     uint64_t c;                                                     \
2070     c = cond;                                                       \
2071     update_fcr31(env, GETPC());                                     \
2072     if (c) {                                                        \
2073         return -1;                                                  \
2074     } else {                                                        \
2075         return 0;                                                   \
2076     }                                                               \
2077 }
2078 
2079 /*
2080  * NOTE: the comma operator will make "cond" to eval to false,
2081  * but float64_unordered_quiet() is still called.
2082  */
2083 FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
2084                                        &env->active_fpu.fp_status), 0))
2085 FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
2086                                        &env->active_fpu.fp_status)))
2087 FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
2088                                        &env->active_fpu.fp_status)))
2089 FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
2090                                        &env->active_fpu.fp_status)
2091                  || float64_eq_quiet(fdt0, fdt1,
2092                                        &env->active_fpu.fp_status)))
2093 FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
2094                                        &env->active_fpu.fp_status)))
2095 FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
2096                                        &env->active_fpu.fp_status)
2097                  || float64_lt_quiet(fdt0, fdt1,
2098                                        &env->active_fpu.fp_status)))
2099 FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
2100                                        &env->active_fpu.fp_status)))
2101 FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
2102                                        &env->active_fpu.fp_status)
2103                  || float64_le_quiet(fdt0, fdt1,
2104                                        &env->active_fpu.fp_status)))
2105 /*
2106  * NOTE: the comma operator will make "cond" to eval to false,
2107  * but float64_unordered() is still called.\
2108  */
2109 FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
2110                                        &env->active_fpu.fp_status), 0))
2111 FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
2112                                        &env->active_fpu.fp_status)))
2113 FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
2114                                        &env->active_fpu.fp_status)))
2115 FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
2116                                        &env->active_fpu.fp_status)
2117                    || float64_eq(fdt0, fdt1,
2118                                        &env->active_fpu.fp_status)))
2119 FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
2120                                        &env->active_fpu.fp_status)))
2121 FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
2122                                        &env->active_fpu.fp_status)
2123                    || float64_lt(fdt0, fdt1,
2124                                        &env->active_fpu.fp_status)))
2125 FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
2126                                        &env->active_fpu.fp_status)))
2127 FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
2128                                        &env->active_fpu.fp_status)
2129                    || float64_le(fdt0, fdt1,
2130                                        &env->active_fpu.fp_status)))
2131 FOP_CONDN_D(or,   (float64_le_quiet(fdt1, fdt0,
2132                                        &env->active_fpu.fp_status)
2133                    || float64_le_quiet(fdt0, fdt1,
2134                                        &env->active_fpu.fp_status)))
2135 FOP_CONDN_D(une,  (float64_unordered_quiet(fdt1, fdt0,
2136                                        &env->active_fpu.fp_status)
2137                    || float64_lt_quiet(fdt1, fdt0,
2138                                        &env->active_fpu.fp_status)
2139                    || float64_lt_quiet(fdt0, fdt1,
2140                                        &env->active_fpu.fp_status)))
2141 FOP_CONDN_D(ne,   (float64_lt_quiet(fdt1, fdt0,
2142                                        &env->active_fpu.fp_status)
2143                    || float64_lt_quiet(fdt0, fdt1,
2144                                        &env->active_fpu.fp_status)))
2145 FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
2146                                        &env->active_fpu.fp_status)
2147                    || float64_le(fdt0, fdt1,
2148                                        &env->active_fpu.fp_status)))
2149 FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
2150                                        &env->active_fpu.fp_status)
2151                    || float64_lt(fdt1, fdt0,
2152                                        &env->active_fpu.fp_status)
2153                    || float64_lt(fdt0, fdt1,
2154                                        &env->active_fpu.fp_status)))
2155 FOP_CONDN_D(sne,  (float64_lt(fdt1, fdt0,
2156                                        &env->active_fpu.fp_status)
2157                    || float64_lt(fdt0, fdt1,
2158                                        &env->active_fpu.fp_status)))
2159 
2160 #define FOP_CONDN_S(op, cond)                                       \
2161 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,   \
2162                                 uint32_t fst1)                      \
2163 {                                                                   \
2164     uint64_t c;                                                     \
2165     c = cond;                                                       \
2166     update_fcr31(env, GETPC());                                     \
2167     if (c) {                                                        \
2168         return -1;                                                  \
2169     } else {                                                        \
2170         return 0;                                                   \
2171     }                                                               \
2172 }
2173 
2174 /*
2175  * NOTE: the comma operator will make "cond" to eval to false,
2176  * but float32_unordered_quiet() is still called.
2177  */
2178 FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
2179                                        &env->active_fpu.fp_status), 0))
2180 FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
2181                                        &env->active_fpu.fp_status)))
2182 FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
2183                                        &env->active_fpu.fp_status)))
2184 FOP_CONDN_S(ueq,  (float32_unordered_quiet(fst1, fst0,
2185                                        &env->active_fpu.fp_status)
2186                    || float32_eq_quiet(fst0, fst1,
2187                                        &env->active_fpu.fp_status)))
2188 FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
2189                                        &env->active_fpu.fp_status)))
2190 FOP_CONDN_S(ult,  (float32_unordered_quiet(fst1, fst0,
2191                                        &env->active_fpu.fp_status)
2192                    || float32_lt_quiet(fst0, fst1,
2193                                        &env->active_fpu.fp_status)))
2194 FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
2195                                        &env->active_fpu.fp_status)))
2196 FOP_CONDN_S(ule,  (float32_unordered_quiet(fst1, fst0,
2197                                        &env->active_fpu.fp_status)
2198                    || float32_le_quiet(fst0, fst1,
2199                                        &env->active_fpu.fp_status)))
2200 /*
2201  * NOTE: the comma operator will make "cond" to eval to false,
2202  * but float32_unordered() is still called.
2203  */
2204 FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
2205                                        &env->active_fpu.fp_status), 0))
2206 FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
2207                                        &env->active_fpu.fp_status)))
2208 FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
2209                                        &env->active_fpu.fp_status)))
2210 FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
2211                                        &env->active_fpu.fp_status)
2212                    || float32_eq(fst0, fst1,
2213                                        &env->active_fpu.fp_status)))
2214 FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
2215                                        &env->active_fpu.fp_status)))
2216 FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
2217                                        &env->active_fpu.fp_status)
2218                    || float32_lt(fst0, fst1,
2219                                        &env->active_fpu.fp_status)))
2220 FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
2221                                        &env->active_fpu.fp_status)))
2222 FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
2223                                        &env->active_fpu.fp_status)
2224                    || float32_le(fst0, fst1,
2225                                        &env->active_fpu.fp_status)))
2226 FOP_CONDN_S(or,   (float32_le_quiet(fst1, fst0,
2227                                        &env->active_fpu.fp_status)
2228                    || float32_le_quiet(fst0, fst1,
2229                                        &env->active_fpu.fp_status)))
2230 FOP_CONDN_S(une,  (float32_unordered_quiet(fst1, fst0,
2231                                        &env->active_fpu.fp_status)
2232                    || float32_lt_quiet(fst1, fst0,
2233                                        &env->active_fpu.fp_status)
2234                    || float32_lt_quiet(fst0, fst1,
2235                                        &env->active_fpu.fp_status)))
2236 FOP_CONDN_S(ne,   (float32_lt_quiet(fst1, fst0,
2237                                        &env->active_fpu.fp_status)
2238                    || float32_lt_quiet(fst0, fst1,
2239                                        &env->active_fpu.fp_status)))
2240 FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
2241                                        &env->active_fpu.fp_status)
2242                    || float32_le(fst0, fst1,
2243                                        &env->active_fpu.fp_status)))
2244 FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
2245                                        &env->active_fpu.fp_status)
2246                    || float32_lt(fst1, fst0,
2247                                        &env->active_fpu.fp_status)
2248                    || float32_lt(fst0, fst1,
2249                                        &env->active_fpu.fp_status)))
2250 FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
2251                                        &env->active_fpu.fp_status)
2252                    || float32_lt(fst0, fst1,
2253                                        &env->active_fpu.fp_status)))
2254