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