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