9p: null terminate fs driver options list
[qemu/ar7.git] / target / mips / fpu_helper.c
blob7a3a61cab37ac27dd6f3e73e6dfd192202e03a36
1 /*
2 * Helpers for emulation of FPU-related MIPS instructions.
4 * Copyright (C) 2004-2005 Jocelyn Mayer
5 * Copyright (C) 2020 Wave Computing, Inc.
6 * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
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 of the License, or (at your option) any later version.
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.
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/>.
23 #include "qemu/osdep.h"
24 #include "qemu/main-loop.h"
25 #include "cpu.h"
26 #include "internal.h"
27 #include "qemu/host-utils.h"
28 #include "exec/helper-proto.h"
29 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "exec/memop.h"
32 #include "sysemu/kvm.h"
33 #include "fpu/softfloat.h"
36 /* Complex FPU operations which may need stack space. */
38 #define FLOAT_TWO32 make_float32(1 << 30)
39 #define FLOAT_TWO64 make_float64(1ULL << 62)
41 #define FP_TO_INT32_OVERFLOW 0x7fffffff
42 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
44 /* convert MIPS rounding mode in FCR31 to IEEE library */
45 unsigned int ieee_rm[] = {
46 float_round_nearest_even,
47 float_round_to_zero,
48 float_round_up,
49 float_round_down
52 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
54 target_ulong arg1 = 0;
56 switch (reg) {
57 case 0:
58 arg1 = (int32_t)env->active_fpu.fcr0;
59 break;
60 case 1:
61 /* UFR Support - Read Status FR */
62 if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
63 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
64 arg1 = (int32_t)
65 ((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR);
66 } else {
67 do_raise_exception(env, EXCP_RI, GETPC());
70 break;
71 case 5:
72 /* FRE Support - read Config5.FRE bit */
73 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
74 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
75 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
76 } else {
77 helper_raise_exception(env, EXCP_RI);
80 break;
81 case 25:
82 arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
83 ((env->active_fpu.fcr31 >> 23) & 0x1);
84 break;
85 case 26:
86 arg1 = env->active_fpu.fcr31 & 0x0003f07c;
87 break;
88 case 28:
89 arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
90 ((env->active_fpu.fcr31 >> 22) & 0x4);
91 break;
92 default:
93 arg1 = (int32_t)env->active_fpu.fcr31;
94 break;
97 return arg1;
100 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
102 switch (fs) {
103 case 1:
104 /* UFR Alias - Reset Status FR */
105 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
106 return;
108 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
109 env->CP0_Status &= ~(1 << CP0St_FR);
110 compute_hflags(env);
111 } else {
112 do_raise_exception(env, EXCP_RI, GETPC());
114 break;
115 case 4:
116 /* UNFR Alias - Set Status FR */
117 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
118 return;
120 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
121 env->CP0_Status |= (1 << CP0St_FR);
122 compute_hflags(env);
123 } else {
124 do_raise_exception(env, EXCP_RI, GETPC());
126 break;
127 case 5:
128 /* FRE Support - clear Config5.FRE bit */
129 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
130 return;
132 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
133 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
134 compute_hflags(env);
135 } else {
136 helper_raise_exception(env, EXCP_RI);
138 break;
139 case 6:
140 /* FRE Support - set Config5.FRE bit */
141 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
142 return;
144 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
145 env->CP0_Config5 |= (1 << CP0C5_FRE);
146 compute_hflags(env);
147 } else {
148 helper_raise_exception(env, EXCP_RI);
150 break;
151 case 25:
152 if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
153 return;
155 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
156 ((arg1 & 0xfe) << 24) |
157 ((arg1 & 0x1) << 23);
158 break;
159 case 26:
160 if (arg1 & 0x007c0000) {
161 return;
163 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
164 (arg1 & 0x0003f07c);
165 break;
166 case 28:
167 if (arg1 & 0x007c0000) {
168 return;
170 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
171 (arg1 & 0x00000f83) |
172 ((arg1 & 0x4) << 22);
173 break;
174 case 31:
175 env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
176 (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
177 break;
178 default:
179 if (env->insn_flags & ISA_MIPS32R6) {
180 do_raise_exception(env, EXCP_RI, GETPC());
182 return;
184 restore_fp_status(env);
185 set_float_exception_flags(0, &env->active_fpu.fp_status);
186 if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
187 GET_FP_CAUSE(env->active_fpu.fcr31)) {
188 do_raise_exception(env, EXCP_FPE, GETPC());
192 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
194 int mips_xcpt = 0;
196 if (ieee_xcpt & float_flag_invalid) {
197 mips_xcpt |= FP_INVALID;
199 if (ieee_xcpt & float_flag_overflow) {
200 mips_xcpt |= FP_OVERFLOW;
202 if (ieee_xcpt & float_flag_underflow) {
203 mips_xcpt |= FP_UNDERFLOW;
205 if (ieee_xcpt & float_flag_divbyzero) {
206 mips_xcpt |= FP_DIV0;
208 if (ieee_xcpt & float_flag_inexact) {
209 mips_xcpt |= FP_INEXACT;
212 return mips_xcpt;
215 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
217 int ieee_exception_flags = get_float_exception_flags(
218 &env->active_fpu.fp_status);
219 int mips_exception_flags = 0;
221 if (ieee_exception_flags) {
222 mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
225 SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
227 if (mips_exception_flags) {
228 set_float_exception_flags(0, &env->active_fpu.fp_status);
230 if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
231 do_raise_exception(env, EXCP_FPE, pc);
232 } else {
233 UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
239 * Float support.
240 * Single precition routines have a "s" suffix, double precision a
241 * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
242 * paired single lower "pl", paired single upper "pu".
245 /* unary operations, modifying fp status */
246 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
248 fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
249 update_fcr31(env, GETPC());
250 return fdt0;
253 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
255 fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
256 update_fcr31(env, GETPC());
257 return fst0;
260 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
262 uint64_t fdt2;
264 fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
265 update_fcr31(env, GETPC());
266 return fdt2;
269 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
271 uint64_t fdt2;
273 fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
274 update_fcr31(env, GETPC());
275 return fdt2;
278 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
280 uint64_t fdt2;
282 fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
283 update_fcr31(env, GETPC());
284 return fdt2;
287 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
289 uint64_t dt2;
291 dt2 = float64_to_int64(fdt0, &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;
296 update_fcr31(env, GETPC());
297 return dt2;
300 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
302 uint64_t dt2;
304 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
305 if (get_float_exception_flags(&env->active_fpu.fp_status)
306 & (float_flag_invalid | float_flag_overflow)) {
307 dt2 = FP_TO_INT64_OVERFLOW;
309 update_fcr31(env, GETPC());
310 return dt2;
313 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
315 uint32_t fst2;
316 uint32_t fsth2;
318 fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
319 fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
320 update_fcr31(env, GETPC());
321 return ((uint64_t)fsth2 << 32) | fst2;
324 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
326 uint32_t wt2;
327 uint32_t wth2;
328 int excp, excph;
330 wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
331 excp = get_float_exception_flags(&env->active_fpu.fp_status);
332 if (excp & (float_flag_overflow | float_flag_invalid)) {
333 wt2 = FP_TO_INT32_OVERFLOW;
336 set_float_exception_flags(0, &env->active_fpu.fp_status);
337 wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
338 excph = get_float_exception_flags(&env->active_fpu.fp_status);
339 if (excph & (float_flag_overflow | float_flag_invalid)) {
340 wth2 = FP_TO_INT32_OVERFLOW;
343 set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
344 update_fcr31(env, GETPC());
346 return ((uint64_t)wth2 << 32) | wt2;
349 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
351 uint32_t fst2;
353 fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
354 update_fcr31(env, GETPC());
355 return fst2;
358 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
360 uint32_t fst2;
362 fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
363 update_fcr31(env, GETPC());
364 return fst2;
367 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
369 uint32_t fst2;
371 fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
372 update_fcr31(env, GETPC());
373 return fst2;
376 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
378 uint32_t wt2;
380 wt2 = wt0;
381 update_fcr31(env, GETPC());
382 return wt2;
385 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
387 uint32_t wt2;
389 wt2 = wth0;
390 update_fcr31(env, GETPC());
391 return wt2;
394 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
396 uint32_t wt2;
398 wt2 = float32_to_int32(fst0, &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;
403 update_fcr31(env, GETPC());
404 return wt2;
407 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
409 uint32_t wt2;
411 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
412 if (get_float_exception_flags(&env->active_fpu.fp_status)
413 & (float_flag_invalid | float_flag_overflow)) {
414 wt2 = FP_TO_INT32_OVERFLOW;
416 update_fcr31(env, GETPC());
417 return wt2;
420 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
422 uint64_t dt2;
424 set_float_rounding_mode(float_round_nearest_even,
425 &env->active_fpu.fp_status);
426 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
427 restore_rounding_mode(env);
428 if (get_float_exception_flags(&env->active_fpu.fp_status)
429 & (float_flag_invalid | float_flag_overflow)) {
430 dt2 = FP_TO_INT64_OVERFLOW;
432 update_fcr31(env, GETPC());
433 return dt2;
436 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
438 uint64_t dt2;
440 set_float_rounding_mode(float_round_nearest_even,
441 &env->active_fpu.fp_status);
442 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
443 restore_rounding_mode(env);
444 if (get_float_exception_flags(&env->active_fpu.fp_status)
445 & (float_flag_invalid | float_flag_overflow)) {
446 dt2 = FP_TO_INT64_OVERFLOW;
448 update_fcr31(env, GETPC());
449 return dt2;
452 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
454 uint32_t wt2;
456 set_float_rounding_mode(float_round_nearest_even,
457 &env->active_fpu.fp_status);
458 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
459 restore_rounding_mode(env);
460 if (get_float_exception_flags(&env->active_fpu.fp_status)
461 & (float_flag_invalid | float_flag_overflow)) {
462 wt2 = FP_TO_INT32_OVERFLOW;
464 update_fcr31(env, GETPC());
465 return wt2;
468 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
470 uint32_t wt2;
472 set_float_rounding_mode(float_round_nearest_even,
473 &env->active_fpu.fp_status);
474 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
475 restore_rounding_mode(env);
476 if (get_float_exception_flags(&env->active_fpu.fp_status)
477 & (float_flag_invalid | float_flag_overflow)) {
478 wt2 = FP_TO_INT32_OVERFLOW;
480 update_fcr31(env, GETPC());
481 return wt2;
484 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
486 uint64_t dt2;
488 dt2 = float64_to_int64_round_to_zero(fdt0,
489 &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;
494 update_fcr31(env, GETPC());
495 return dt2;
498 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
500 uint64_t dt2;
502 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
503 if (get_float_exception_flags(&env->active_fpu.fp_status)
504 & (float_flag_invalid | float_flag_overflow)) {
505 dt2 = FP_TO_INT64_OVERFLOW;
507 update_fcr31(env, GETPC());
508 return dt2;
511 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
513 uint32_t wt2;
515 wt2 = float64_to_int32_round_to_zero(fdt0, &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;
520 update_fcr31(env, GETPC());
521 return wt2;
524 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
526 uint32_t wt2;
528 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
529 if (get_float_exception_flags(&env->active_fpu.fp_status)
530 & (float_flag_invalid | float_flag_overflow)) {
531 wt2 = FP_TO_INT32_OVERFLOW;
533 update_fcr31(env, GETPC());
534 return wt2;
537 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
539 uint64_t dt2;
541 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
542 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
543 restore_rounding_mode(env);
544 if (get_float_exception_flags(&env->active_fpu.fp_status)
545 & (float_flag_invalid | float_flag_overflow)) {
546 dt2 = FP_TO_INT64_OVERFLOW;
548 update_fcr31(env, GETPC());
549 return dt2;
552 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
554 uint64_t dt2;
556 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
557 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
558 restore_rounding_mode(env);
559 if (get_float_exception_flags(&env->active_fpu.fp_status)
560 & (float_flag_invalid | float_flag_overflow)) {
561 dt2 = FP_TO_INT64_OVERFLOW;
563 update_fcr31(env, GETPC());
564 return dt2;
567 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
569 uint32_t wt2;
571 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
572 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
573 restore_rounding_mode(env);
574 if (get_float_exception_flags(&env->active_fpu.fp_status)
575 & (float_flag_invalid | float_flag_overflow)) {
576 wt2 = FP_TO_INT32_OVERFLOW;
578 update_fcr31(env, GETPC());
579 return wt2;
582 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
584 uint32_t wt2;
586 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
587 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
588 restore_rounding_mode(env);
589 if (get_float_exception_flags(&env->active_fpu.fp_status)
590 & (float_flag_invalid | float_flag_overflow)) {
591 wt2 = FP_TO_INT32_OVERFLOW;
593 update_fcr31(env, GETPC());
594 return wt2;
597 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
599 uint64_t dt2;
601 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
602 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
603 restore_rounding_mode(env);
604 if (get_float_exception_flags(&env->active_fpu.fp_status)
605 & (float_flag_invalid | float_flag_overflow)) {
606 dt2 = FP_TO_INT64_OVERFLOW;
608 update_fcr31(env, GETPC());
609 return dt2;
612 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
614 uint64_t dt2;
616 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
617 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
618 restore_rounding_mode(env);
619 if (get_float_exception_flags(&env->active_fpu.fp_status)
620 & (float_flag_invalid | float_flag_overflow)) {
621 dt2 = FP_TO_INT64_OVERFLOW;
623 update_fcr31(env, GETPC());
624 return dt2;
627 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
629 uint32_t wt2;
631 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
632 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
633 restore_rounding_mode(env);
634 if (get_float_exception_flags(&env->active_fpu.fp_status)
635 & (float_flag_invalid | float_flag_overflow)) {
636 wt2 = FP_TO_INT32_OVERFLOW;
638 update_fcr31(env, GETPC());
639 return wt2;
642 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
644 uint32_t wt2;
646 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
647 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
648 restore_rounding_mode(env);
649 if (get_float_exception_flags(&env->active_fpu.fp_status)
650 & (float_flag_invalid | float_flag_overflow)) {
651 wt2 = FP_TO_INT32_OVERFLOW;
653 update_fcr31(env, GETPC());
654 return wt2;
657 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
659 uint64_t dt2;
661 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
662 if (get_float_exception_flags(&env->active_fpu.fp_status)
663 & float_flag_invalid) {
664 if (float64_is_any_nan(fdt0)) {
665 dt2 = 0;
668 update_fcr31(env, GETPC());
669 return dt2;
672 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
674 uint64_t dt2;
676 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
677 if (get_float_exception_flags(&env->active_fpu.fp_status)
678 & float_flag_invalid) {
679 if (float32_is_any_nan(fst0)) {
680 dt2 = 0;
683 update_fcr31(env, GETPC());
684 return dt2;
687 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
689 uint32_t wt2;
691 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
692 if (get_float_exception_flags(&env->active_fpu.fp_status)
693 & float_flag_invalid) {
694 if (float64_is_any_nan(fdt0)) {
695 wt2 = 0;
698 update_fcr31(env, GETPC());
699 return wt2;
702 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
704 uint32_t wt2;
706 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
707 if (get_float_exception_flags(&env->active_fpu.fp_status)
708 & float_flag_invalid) {
709 if (float32_is_any_nan(fst0)) {
710 wt2 = 0;
713 update_fcr31(env, GETPC());
714 return wt2;
717 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
719 uint64_t dt2;
721 set_float_rounding_mode(float_round_nearest_even,
722 &env->active_fpu.fp_status);
723 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
724 restore_rounding_mode(env);
725 if (get_float_exception_flags(&env->active_fpu.fp_status)
726 & float_flag_invalid) {
727 if (float64_is_any_nan(fdt0)) {
728 dt2 = 0;
731 update_fcr31(env, GETPC());
732 return dt2;
735 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
737 uint64_t dt2;
739 set_float_rounding_mode(float_round_nearest_even,
740 &env->active_fpu.fp_status);
741 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
742 restore_rounding_mode(env);
743 if (get_float_exception_flags(&env->active_fpu.fp_status)
744 & float_flag_invalid) {
745 if (float32_is_any_nan(fst0)) {
746 dt2 = 0;
749 update_fcr31(env, GETPC());
750 return dt2;
753 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
755 uint32_t wt2;
757 set_float_rounding_mode(float_round_nearest_even,
758 &env->active_fpu.fp_status);
759 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
760 restore_rounding_mode(env);
761 if (get_float_exception_flags(&env->active_fpu.fp_status)
762 & float_flag_invalid) {
763 if (float64_is_any_nan(fdt0)) {
764 wt2 = 0;
767 update_fcr31(env, GETPC());
768 return wt2;
771 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
773 uint32_t wt2;
775 set_float_rounding_mode(float_round_nearest_even,
776 &env->active_fpu.fp_status);
777 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
778 restore_rounding_mode(env);
779 if (get_float_exception_flags(&env->active_fpu.fp_status)
780 & float_flag_invalid) {
781 if (float32_is_any_nan(fst0)) {
782 wt2 = 0;
785 update_fcr31(env, GETPC());
786 return wt2;
789 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
791 uint64_t dt2;
793 dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
794 if (get_float_exception_flags(&env->active_fpu.fp_status)
795 & float_flag_invalid) {
796 if (float64_is_any_nan(fdt0)) {
797 dt2 = 0;
800 update_fcr31(env, GETPC());
801 return dt2;
804 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
806 uint64_t dt2;
808 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
809 if (get_float_exception_flags(&env->active_fpu.fp_status)
810 & float_flag_invalid) {
811 if (float32_is_any_nan(fst0)) {
812 dt2 = 0;
815 update_fcr31(env, GETPC());
816 return dt2;
819 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
821 uint32_t wt2;
823 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
824 if (get_float_exception_flags(&env->active_fpu.fp_status)
825 & float_flag_invalid) {
826 if (float64_is_any_nan(fdt0)) {
827 wt2 = 0;
830 update_fcr31(env, GETPC());
831 return wt2;
834 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
836 uint32_t wt2;
838 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
839 if (get_float_exception_flags(&env->active_fpu.fp_status)
840 & float_flag_invalid) {
841 if (float32_is_any_nan(fst0)) {
842 wt2 = 0;
845 update_fcr31(env, GETPC());
846 return wt2;
849 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
851 uint64_t dt2;
853 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
854 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
855 restore_rounding_mode(env);
856 if (get_float_exception_flags(&env->active_fpu.fp_status)
857 & float_flag_invalid) {
858 if (float64_is_any_nan(fdt0)) {
859 dt2 = 0;
862 update_fcr31(env, GETPC());
863 return dt2;
866 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
868 uint64_t dt2;
870 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
871 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
872 restore_rounding_mode(env);
873 if (get_float_exception_flags(&env->active_fpu.fp_status)
874 & float_flag_invalid) {
875 if (float32_is_any_nan(fst0)) {
876 dt2 = 0;
879 update_fcr31(env, GETPC());
880 return dt2;
883 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
885 uint32_t wt2;
887 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
888 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
889 restore_rounding_mode(env);
890 if (get_float_exception_flags(&env->active_fpu.fp_status)
891 & float_flag_invalid) {
892 if (float64_is_any_nan(fdt0)) {
893 wt2 = 0;
896 update_fcr31(env, GETPC());
897 return wt2;
900 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
902 uint32_t wt2;
904 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
905 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
906 restore_rounding_mode(env);
907 if (get_float_exception_flags(&env->active_fpu.fp_status)
908 & float_flag_invalid) {
909 if (float32_is_any_nan(fst0)) {
910 wt2 = 0;
913 update_fcr31(env, GETPC());
914 return wt2;
917 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
919 uint64_t dt2;
921 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
922 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
923 restore_rounding_mode(env);
924 if (get_float_exception_flags(&env->active_fpu.fp_status)
925 & float_flag_invalid) {
926 if (float64_is_any_nan(fdt0)) {
927 dt2 = 0;
930 update_fcr31(env, GETPC());
931 return dt2;
934 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
936 uint64_t dt2;
938 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
939 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
940 restore_rounding_mode(env);
941 if (get_float_exception_flags(&env->active_fpu.fp_status)
942 & float_flag_invalid) {
943 if (float32_is_any_nan(fst0)) {
944 dt2 = 0;
947 update_fcr31(env, GETPC());
948 return dt2;
951 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
953 uint32_t wt2;
955 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
956 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
957 restore_rounding_mode(env);
958 if (get_float_exception_flags(&env->active_fpu.fp_status)
959 & float_flag_invalid) {
960 if (float64_is_any_nan(fdt0)) {
961 wt2 = 0;
964 update_fcr31(env, GETPC());
965 return wt2;
968 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
970 uint32_t wt2;
972 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
973 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
974 restore_rounding_mode(env);
975 if (get_float_exception_flags(&env->active_fpu.fp_status)
976 & float_flag_invalid) {
977 if (float32_is_any_nan(fst0)) {
978 wt2 = 0;
981 update_fcr31(env, GETPC());
982 return wt2;
985 /* unary operations, not modifying fp status */
986 #define FLOAT_UNOP(name) \
987 uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \
989 return float64_ ## name(fdt0); \
991 uint32_t helper_float_ ## name ## _s(uint32_t fst0) \
993 return float32_ ## name(fst0); \
995 uint64_t helper_float_ ## name ## _ps(uint64_t fdt0) \
997 uint32_t wt0; \
998 uint32_t wth0; \
1000 wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF); \
1001 wth0 = float32_ ## name(fdt0 >> 32); \
1002 return ((uint64_t)wth0 << 32) | wt0; \
1004 FLOAT_UNOP(abs)
1005 FLOAT_UNOP(chs)
1006 #undef FLOAT_UNOP
1008 /* MIPS specific unary operations */
1009 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1011 uint64_t fdt2;
1013 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1014 update_fcr31(env, GETPC());
1015 return fdt2;
1018 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1020 uint32_t fst2;
1022 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1023 update_fcr31(env, GETPC());
1024 return fst2;
1027 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1029 uint64_t fdt2;
1031 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1032 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1033 update_fcr31(env, GETPC());
1034 return fdt2;
1037 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1039 uint32_t fst2;
1041 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1042 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1043 update_fcr31(env, GETPC());
1044 return fst2;
1047 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1049 uint64_t fdt2;
1051 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1052 update_fcr31(env, GETPC());
1053 return fdt2;
1056 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1058 uint32_t fst2;
1060 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1061 update_fcr31(env, GETPC());
1062 return fst2;
1065 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1067 uint32_t fstl2;
1068 uint32_t fsth2;
1070 fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
1071 &env->active_fpu.fp_status);
1072 fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
1073 update_fcr31(env, GETPC());
1074 return ((uint64_t)fsth2 << 32) | fstl2;
1077 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1079 uint64_t fdt2;
1081 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1082 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1083 update_fcr31(env, GETPC());
1084 return fdt2;
1087 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1089 uint32_t fst2;
1091 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1092 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1093 update_fcr31(env, GETPC());
1094 return fst2;
1097 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1099 uint32_t fstl2;
1100 uint32_t fsth2;
1102 fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
1103 fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1104 fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
1105 fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
1106 update_fcr31(env, GETPC());
1107 return ((uint64_t)fsth2 << 32) | fstl2;
1110 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1112 uint64_t fdret;
1114 fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1115 update_fcr31(env, GETPC());
1116 return fdret;
1119 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1121 uint32_t fdret;
1123 fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1124 update_fcr31(env, GETPC());
1125 return fdret;
1128 #define FLOAT_CLASS_SIGNALING_NAN 0x001
1129 #define FLOAT_CLASS_QUIET_NAN 0x002
1130 #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1131 #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1132 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1133 #define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1134 #define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1135 #define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1136 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1137 #define FLOAT_CLASS_POSITIVE_ZERO 0x200
1139 uint64_t float_class_d(uint64_t arg, float_status *status)
1141 if (float64_is_signaling_nan(arg, status)) {
1142 return FLOAT_CLASS_SIGNALING_NAN;
1143 } else if (float64_is_quiet_nan(arg, status)) {
1144 return FLOAT_CLASS_QUIET_NAN;
1145 } else if (float64_is_neg(arg)) {
1146 if (float64_is_infinity(arg)) {
1147 return FLOAT_CLASS_NEGATIVE_INFINITY;
1148 } else if (float64_is_zero(arg)) {
1149 return FLOAT_CLASS_NEGATIVE_ZERO;
1150 } else if (float64_is_zero_or_denormal(arg)) {
1151 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1152 } else {
1153 return FLOAT_CLASS_NEGATIVE_NORMAL;
1155 } else {
1156 if (float64_is_infinity(arg)) {
1157 return FLOAT_CLASS_POSITIVE_INFINITY;
1158 } else if (float64_is_zero(arg)) {
1159 return FLOAT_CLASS_POSITIVE_ZERO;
1160 } else if (float64_is_zero_or_denormal(arg)) {
1161 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1162 } else {
1163 return FLOAT_CLASS_POSITIVE_NORMAL;
1168 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1170 return float_class_d(arg, &env->active_fpu.fp_status);
1173 uint32_t float_class_s(uint32_t arg, float_status *status)
1175 if (float32_is_signaling_nan(arg, status)) {
1176 return FLOAT_CLASS_SIGNALING_NAN;
1177 } else if (float32_is_quiet_nan(arg, status)) {
1178 return FLOAT_CLASS_QUIET_NAN;
1179 } else if (float32_is_neg(arg)) {
1180 if (float32_is_infinity(arg)) {
1181 return FLOAT_CLASS_NEGATIVE_INFINITY;
1182 } else if (float32_is_zero(arg)) {
1183 return FLOAT_CLASS_NEGATIVE_ZERO;
1184 } else if (float32_is_zero_or_denormal(arg)) {
1185 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1186 } else {
1187 return FLOAT_CLASS_NEGATIVE_NORMAL;
1189 } else {
1190 if (float32_is_infinity(arg)) {
1191 return FLOAT_CLASS_POSITIVE_INFINITY;
1192 } else if (float32_is_zero(arg)) {
1193 return FLOAT_CLASS_POSITIVE_ZERO;
1194 } else if (float32_is_zero_or_denormal(arg)) {
1195 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1196 } else {
1197 return FLOAT_CLASS_POSITIVE_NORMAL;
1202 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1204 return float_class_s(arg, &env->active_fpu.fp_status);
1207 /* binary operations */
1209 uint64_t helper_float_add_d(CPUMIPSState *env,
1210 uint64_t fdt0, uint64_t fdt1)
1212 uint64_t dt2;
1214 dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1215 update_fcr31(env, GETPC());
1216 return dt2;
1219 uint32_t helper_float_add_s(CPUMIPSState *env,
1220 uint32_t fst0, uint32_t fst1)
1222 uint32_t wt2;
1224 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1225 update_fcr31(env, GETPC());
1226 return wt2;
1229 uint64_t helper_float_add_ps(CPUMIPSState *env,
1230 uint64_t fdt0, uint64_t fdt1)
1232 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1233 uint32_t fsth0 = fdt0 >> 32;
1234 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1235 uint32_t fsth1 = fdt1 >> 32;
1236 uint32_t wtl2;
1237 uint32_t wth2;
1239 wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
1240 wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
1241 update_fcr31(env, GETPC());
1242 return ((uint64_t)wth2 << 32) | wtl2;
1245 uint64_t helper_float_sub_d(CPUMIPSState *env,
1246 uint64_t fdt0, uint64_t fdt1)
1248 uint64_t dt2;
1250 dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1251 update_fcr31(env, GETPC());
1252 return dt2;
1255 uint32_t helper_float_sub_s(CPUMIPSState *env,
1256 uint32_t fst0, uint32_t fst1)
1258 uint32_t wt2;
1260 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1261 update_fcr31(env, GETPC());
1262 return wt2;
1265 uint64_t helper_float_sub_ps(CPUMIPSState *env,
1266 uint64_t fdt0, uint64_t fdt1)
1268 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1269 uint32_t fsth0 = fdt0 >> 32;
1270 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1271 uint32_t fsth1 = fdt1 >> 32;
1272 uint32_t wtl2;
1273 uint32_t wth2;
1275 wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1276 wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1277 update_fcr31(env, GETPC());
1278 return ((uint64_t)wth2 << 32) | wtl2;
1281 uint64_t helper_float_mul_d(CPUMIPSState *env,
1282 uint64_t fdt0, uint64_t fdt1)
1284 uint64_t dt2;
1286 dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1287 update_fcr31(env, GETPC());
1288 return dt2;
1291 uint32_t helper_float_mul_s(CPUMIPSState *env,
1292 uint32_t fst0, uint32_t fst1)
1294 uint32_t wt2;
1296 wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1297 update_fcr31(env, GETPC());
1298 return wt2;
1301 uint64_t helper_float_mul_ps(CPUMIPSState *env,
1302 uint64_t fdt0, uint64_t fdt1)
1304 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1305 uint32_t fsth0 = fdt0 >> 32;
1306 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1307 uint32_t fsth1 = fdt1 >> 32;
1308 uint32_t wtl2;
1309 uint32_t wth2;
1311 wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1312 wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1313 update_fcr31(env, GETPC());
1314 return ((uint64_t)wth2 << 32) | wtl2;
1317 uint64_t helper_float_div_d(CPUMIPSState *env,
1318 uint64_t fdt0, uint64_t fdt1)
1320 uint64_t dt2;
1322 dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1323 update_fcr31(env, GETPC());
1324 return dt2;
1327 uint32_t helper_float_div_s(CPUMIPSState *env,
1328 uint32_t fst0, uint32_t fst1)
1330 uint32_t wt2;
1332 wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1333 update_fcr31(env, GETPC());
1334 return wt2;
1337 uint64_t helper_float_div_ps(CPUMIPSState *env,
1338 uint64_t fdt0, uint64_t fdt1)
1340 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1341 uint32_t fsth0 = fdt0 >> 32;
1342 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1343 uint32_t fsth1 = fdt1 >> 32;
1344 uint32_t wtl2;
1345 uint32_t wth2;
1347 wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1348 wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1349 update_fcr31(env, GETPC());
1350 return ((uint64_t)wth2 << 32) | wtl2;
1354 /* MIPS specific binary operations */
1355 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1357 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1358 fdt2 = float64_chs(float64_sub(fdt2, float64_one,
1359 &env->active_fpu.fp_status));
1360 update_fcr31(env, GETPC());
1361 return fdt2;
1364 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1366 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1367 fst2 = float32_chs(float32_sub(fst2, float32_one,
1368 &env->active_fpu.fp_status));
1369 update_fcr31(env, GETPC());
1370 return fst2;
1373 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1375 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1376 uint32_t fsth0 = fdt0 >> 32;
1377 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1378 uint32_t fsth2 = fdt2 >> 32;
1380 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1381 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1382 fstl2 = float32_chs(float32_sub(fstl2, float32_one,
1383 &env->active_fpu.fp_status));
1384 fsth2 = float32_chs(float32_sub(fsth2, float32_one,
1385 &env->active_fpu.fp_status));
1386 update_fcr31(env, GETPC());
1387 return ((uint64_t)fsth2 << 32) | fstl2;
1390 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1392 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1393 fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
1394 fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
1395 &env->active_fpu.fp_status));
1396 update_fcr31(env, GETPC());
1397 return fdt2;
1400 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1402 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1403 fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
1404 fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
1405 &env->active_fpu.fp_status));
1406 update_fcr31(env, GETPC());
1407 return fst2;
1410 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1412 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1413 uint32_t fsth0 = fdt0 >> 32;
1414 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1415 uint32_t fsth2 = fdt2 >> 32;
1417 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1418 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1419 fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
1420 fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1421 fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
1422 &env->active_fpu.fp_status));
1423 fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
1424 &env->active_fpu.fp_status));
1425 update_fcr31(env, GETPC());
1426 return ((uint64_t)fsth2 << 32) | fstl2;
1429 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1431 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1432 uint32_t fsth0 = fdt0 >> 32;
1433 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1434 uint32_t fsth1 = fdt1 >> 32;
1435 uint32_t fstl2;
1436 uint32_t fsth2;
1438 fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1439 fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
1440 update_fcr31(env, GETPC());
1441 return ((uint64_t)fsth2 << 32) | fstl2;
1444 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1446 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1447 uint32_t fsth0 = fdt0 >> 32;
1448 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1449 uint32_t fsth1 = fdt1 >> 32;
1450 uint32_t fstl2;
1451 uint32_t fsth2;
1453 fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1454 fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
1455 update_fcr31(env, GETPC());
1456 return ((uint64_t)fsth2 << 32) | fstl2;
1459 #define FLOAT_MINMAX(name, bits, minmaxfunc) \
1460 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
1461 uint ## bits ## _t fs, \
1462 uint ## bits ## _t ft) \
1464 uint ## bits ## _t fdret; \
1466 fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \
1467 &env->active_fpu.fp_status); \
1468 update_fcr31(env, GETPC()); \
1469 return fdret; \
1472 FLOAT_MINMAX(max_s, 32, maxnum)
1473 FLOAT_MINMAX(max_d, 64, maxnum)
1474 FLOAT_MINMAX(maxa_s, 32, maxnummag)
1475 FLOAT_MINMAX(maxa_d, 64, maxnummag)
1477 FLOAT_MINMAX(min_s, 32, minnum)
1478 FLOAT_MINMAX(min_d, 64, minnum)
1479 FLOAT_MINMAX(mina_s, 32, minnummag)
1480 FLOAT_MINMAX(mina_d, 64, minnummag)
1481 #undef FLOAT_MINMAX
1483 /* ternary operations */
1485 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1486 uint64_t fst1, uint64_t fst2)
1488 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1489 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1491 update_fcr31(env, GETPC());
1492 return fst0;
1495 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1496 uint32_t fst1, uint32_t fst2)
1498 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1499 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1501 update_fcr31(env, GETPC());
1502 return fst0;
1505 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1506 uint64_t fdt1, uint64_t fdt2)
1508 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1509 uint32_t fsth0 = fdt0 >> 32;
1510 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1511 uint32_t fsth1 = fdt1 >> 32;
1512 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1513 uint32_t fsth2 = fdt2 >> 32;
1515 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1516 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1517 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1518 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1520 update_fcr31(env, GETPC());
1521 return ((uint64_t)fsth0 << 32) | fstl0;
1524 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1525 uint64_t fst1, uint64_t fst2)
1527 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1528 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1530 update_fcr31(env, GETPC());
1531 return fst0;
1534 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1535 uint32_t fst1, uint32_t fst2)
1537 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1538 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1540 update_fcr31(env, GETPC());
1541 return fst0;
1544 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1545 uint64_t fdt1, uint64_t fdt2)
1547 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1548 uint32_t fsth0 = fdt0 >> 32;
1549 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1550 uint32_t fsth1 = fdt1 >> 32;
1551 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1552 uint32_t fsth2 = fdt2 >> 32;
1554 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1555 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1556 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1557 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1559 update_fcr31(env, GETPC());
1560 return ((uint64_t)fsth0 << 32) | fstl0;
1563 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1564 uint64_t fst1, uint64_t fst2)
1566 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1567 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1568 fst0 = float64_chs(fst0);
1570 update_fcr31(env, GETPC());
1571 return fst0;
1574 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1575 uint32_t fst1, uint32_t fst2)
1577 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1578 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1579 fst0 = float32_chs(fst0);
1581 update_fcr31(env, GETPC());
1582 return fst0;
1585 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1586 uint64_t fdt1, uint64_t fdt2)
1588 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1589 uint32_t fsth0 = fdt0 >> 32;
1590 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1591 uint32_t fsth1 = fdt1 >> 32;
1592 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1593 uint32_t fsth2 = fdt2 >> 32;
1595 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1596 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1597 fstl0 = float32_chs(fstl0);
1598 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1599 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1600 fsth0 = float32_chs(fsth0);
1602 update_fcr31(env, GETPC());
1603 return ((uint64_t)fsth0 << 32) | fstl0;
1606 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1607 uint64_t fst1, uint64_t fst2)
1609 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1610 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1611 fst0 = float64_chs(fst0);
1613 update_fcr31(env, GETPC());
1614 return fst0;
1617 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1618 uint32_t fst1, uint32_t fst2)
1620 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1621 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1622 fst0 = float32_chs(fst0);
1624 update_fcr31(env, GETPC());
1625 return fst0;
1628 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1629 uint64_t fdt1, uint64_t fdt2)
1631 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1632 uint32_t fsth0 = fdt0 >> 32;
1633 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1634 uint32_t fsth1 = fdt1 >> 32;
1635 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1636 uint32_t fsth2 = fdt2 >> 32;
1638 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1639 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1640 fstl0 = float32_chs(fstl0);
1641 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1642 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1643 fsth0 = float32_chs(fsth0);
1645 update_fcr31(env, GETPC());
1646 return ((uint64_t)fsth0 << 32) | fstl0;
1650 #define FLOAT_FMADDSUB(name, bits, muladd_arg) \
1651 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
1652 uint ## bits ## _t fs, \
1653 uint ## bits ## _t ft, \
1654 uint ## bits ## _t fd) \
1656 uint ## bits ## _t fdret; \
1658 fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \
1659 &env->active_fpu.fp_status); \
1660 update_fcr31(env, GETPC()); \
1661 return fdret; \
1664 FLOAT_FMADDSUB(maddf_s, 32, 0)
1665 FLOAT_FMADDSUB(maddf_d, 64, 0)
1666 FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
1667 FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
1668 #undef FLOAT_FMADDSUB
1670 /* compare operations */
1671 #define FOP_COND_D(op, cond) \
1672 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1673 uint64_t fdt1, int cc) \
1675 int c; \
1676 c = cond; \
1677 update_fcr31(env, GETPC()); \
1678 if (c) \
1679 SET_FP_COND(cc, env->active_fpu); \
1680 else \
1681 CLEAR_FP_COND(cc, env->active_fpu); \
1683 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1684 uint64_t fdt1, int cc) \
1686 int c; \
1687 fdt0 = float64_abs(fdt0); \
1688 fdt1 = float64_abs(fdt1); \
1689 c = cond; \
1690 update_fcr31(env, GETPC()); \
1691 if (c) \
1692 SET_FP_COND(cc, env->active_fpu); \
1693 else \
1694 CLEAR_FP_COND(cc, env->active_fpu); \
1698 * NOTE: the comma operator will make "cond" to eval to false,
1699 * but float64_unordered_quiet() is still called.
1701 FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0,
1702 &env->active_fpu.fp_status), 0))
1703 FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0,
1704 &env->active_fpu.fp_status))
1705 FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1,
1706 &env->active_fpu.fp_status))
1707 FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0,
1708 &env->active_fpu.fp_status)
1709 || float64_eq_quiet(fdt0, fdt1,
1710 &env->active_fpu.fp_status))
1711 FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1,
1712 &env->active_fpu.fp_status))
1713 FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0,
1714 &env->active_fpu.fp_status)
1715 || float64_lt_quiet(fdt0, fdt1,
1716 &env->active_fpu.fp_status))
1717 FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1,
1718 &env->active_fpu.fp_status))
1719 FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0,
1720 &env->active_fpu.fp_status)
1721 || float64_le_quiet(fdt0, fdt1,
1722 &env->active_fpu.fp_status))
1724 * NOTE: the comma operator will make "cond" to eval to false,
1725 * but float64_unordered() is still called.
1727 FOP_COND_D(sf, (float64_unordered(fdt1, fdt0,
1728 &env->active_fpu.fp_status), 0))
1729 FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
1730 &env->active_fpu.fp_status))
1731 FOP_COND_D(seq, float64_eq(fdt0, fdt1,
1732 &env->active_fpu.fp_status))
1733 FOP_COND_D(ngl, float64_unordered(fdt1, fdt0,
1734 &env->active_fpu.fp_status)
1735 || float64_eq(fdt0, fdt1,
1736 &env->active_fpu.fp_status))
1737 FOP_COND_D(lt, float64_lt(fdt0, fdt1,
1738 &env->active_fpu.fp_status))
1739 FOP_COND_D(nge, float64_unordered(fdt1, fdt0,
1740 &env->active_fpu.fp_status)
1741 || float64_lt(fdt0, fdt1,
1742 &env->active_fpu.fp_status))
1743 FOP_COND_D(le, float64_le(fdt0, fdt1,
1744 &env->active_fpu.fp_status))
1745 FOP_COND_D(ngt, float64_unordered(fdt1, fdt0,
1746 &env->active_fpu.fp_status)
1747 || float64_le(fdt0, fdt1,
1748 &env->active_fpu.fp_status))
1750 #define FOP_COND_S(op, cond) \
1751 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1752 uint32_t fst1, int cc) \
1754 int c; \
1755 c = cond; \
1756 update_fcr31(env, GETPC()); \
1757 if (c) \
1758 SET_FP_COND(cc, env->active_fpu); \
1759 else \
1760 CLEAR_FP_COND(cc, env->active_fpu); \
1762 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1763 uint32_t fst1, int cc) \
1765 int c; \
1766 fst0 = float32_abs(fst0); \
1767 fst1 = float32_abs(fst1); \
1768 c = cond; \
1769 update_fcr31(env, GETPC()); \
1770 if (c) \
1771 SET_FP_COND(cc, env->active_fpu); \
1772 else \
1773 CLEAR_FP_COND(cc, env->active_fpu); \
1777 * NOTE: the comma operator will make "cond" to eval to false,
1778 * but float32_unordered_quiet() is still called.
1780 FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0,
1781 &env->active_fpu.fp_status), 0))
1782 FOP_COND_S(un, float32_unordered_quiet(fst1, fst0,
1783 &env->active_fpu.fp_status))
1784 FOP_COND_S(eq, float32_eq_quiet(fst0, fst1,
1785 &env->active_fpu.fp_status))
1786 FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0,
1787 &env->active_fpu.fp_status)
1788 || float32_eq_quiet(fst0, fst1,
1789 &env->active_fpu.fp_status))
1790 FOP_COND_S(olt, float32_lt_quiet(fst0, fst1,
1791 &env->active_fpu.fp_status))
1792 FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0,
1793 &env->active_fpu.fp_status)
1794 || float32_lt_quiet(fst0, fst1,
1795 &env->active_fpu.fp_status))
1796 FOP_COND_S(ole, float32_le_quiet(fst0, fst1,
1797 &env->active_fpu.fp_status))
1798 FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0,
1799 &env->active_fpu.fp_status)
1800 || float32_le_quiet(fst0, fst1,
1801 &env->active_fpu.fp_status))
1803 * NOTE: the comma operator will make "cond" to eval to false,
1804 * but float32_unordered() is still called.
1806 FOP_COND_S(sf, (float32_unordered(fst1, fst0,
1807 &env->active_fpu.fp_status), 0))
1808 FOP_COND_S(ngle, float32_unordered(fst1, fst0,
1809 &env->active_fpu.fp_status))
1810 FOP_COND_S(seq, float32_eq(fst0, fst1,
1811 &env->active_fpu.fp_status))
1812 FOP_COND_S(ngl, float32_unordered(fst1, fst0,
1813 &env->active_fpu.fp_status)
1814 || float32_eq(fst0, fst1,
1815 &env->active_fpu.fp_status))
1816 FOP_COND_S(lt, float32_lt(fst0, fst1,
1817 &env->active_fpu.fp_status))
1818 FOP_COND_S(nge, float32_unordered(fst1, fst0,
1819 &env->active_fpu.fp_status)
1820 || float32_lt(fst0, fst1,
1821 &env->active_fpu.fp_status))
1822 FOP_COND_S(le, float32_le(fst0, fst1,
1823 &env->active_fpu.fp_status))
1824 FOP_COND_S(ngt, float32_unordered(fst1, fst0,
1825 &env->active_fpu.fp_status)
1826 || float32_le(fst0, fst1,
1827 &env->active_fpu.fp_status))
1829 #define FOP_COND_PS(op, condl, condh) \
1830 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1831 uint64_t fdt1, int cc) \
1833 uint32_t fst0, fsth0, fst1, fsth1; \
1834 int ch, cl; \
1835 fst0 = fdt0 & 0XFFFFFFFF; \
1836 fsth0 = fdt0 >> 32; \
1837 fst1 = fdt1 & 0XFFFFFFFF; \
1838 fsth1 = fdt1 >> 32; \
1839 cl = condl; \
1840 ch = condh; \
1841 update_fcr31(env, GETPC()); \
1842 if (cl) \
1843 SET_FP_COND(cc, env->active_fpu); \
1844 else \
1845 CLEAR_FP_COND(cc, env->active_fpu); \
1846 if (ch) \
1847 SET_FP_COND(cc + 1, env->active_fpu); \
1848 else \
1849 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1851 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1852 uint64_t fdt1, int cc) \
1854 uint32_t fst0, fsth0, fst1, fsth1; \
1855 int ch, cl; \
1856 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1857 fsth0 = float32_abs(fdt0 >> 32); \
1858 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1859 fsth1 = float32_abs(fdt1 >> 32); \
1860 cl = condl; \
1861 ch = condh; \
1862 update_fcr31(env, GETPC()); \
1863 if (cl) \
1864 SET_FP_COND(cc, env->active_fpu); \
1865 else \
1866 CLEAR_FP_COND(cc, env->active_fpu); \
1867 if (ch) \
1868 SET_FP_COND(cc + 1, env->active_fpu); \
1869 else \
1870 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1874 * NOTE: the comma operator will make "cond" to eval to false,
1875 * but float32_unordered_quiet() is still called.
1877 FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0,
1878 &env->active_fpu.fp_status), 0),
1879 (float32_unordered_quiet(fsth1, fsth0,
1880 &env->active_fpu.fp_status), 0))
1881 FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0,
1882 &env->active_fpu.fp_status),
1883 float32_unordered_quiet(fsth1, fsth0,
1884 &env->active_fpu.fp_status))
1885 FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1,
1886 &env->active_fpu.fp_status),
1887 float32_eq_quiet(fsth0, fsth1,
1888 &env->active_fpu.fp_status))
1889 FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0,
1890 &env->active_fpu.fp_status)
1891 || float32_eq_quiet(fst0, fst1,
1892 &env->active_fpu.fp_status),
1893 float32_unordered_quiet(fsth1, fsth0,
1894 &env->active_fpu.fp_status)
1895 || float32_eq_quiet(fsth0, fsth1,
1896 &env->active_fpu.fp_status))
1897 FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1,
1898 &env->active_fpu.fp_status),
1899 float32_lt_quiet(fsth0, fsth1,
1900 &env->active_fpu.fp_status))
1901 FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0,
1902 &env->active_fpu.fp_status)
1903 || float32_lt_quiet(fst0, fst1,
1904 &env->active_fpu.fp_status),
1905 float32_unordered_quiet(fsth1, fsth0,
1906 &env->active_fpu.fp_status)
1907 || float32_lt_quiet(fsth0, fsth1,
1908 &env->active_fpu.fp_status))
1909 FOP_COND_PS(ole, float32_le_quiet(fst0, fst1,
1910 &env->active_fpu.fp_status),
1911 float32_le_quiet(fsth0, fsth1,
1912 &env->active_fpu.fp_status))
1913 FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0,
1914 &env->active_fpu.fp_status)
1915 || float32_le_quiet(fst0, fst1,
1916 &env->active_fpu.fp_status),
1917 float32_unordered_quiet(fsth1, fsth0,
1918 &env->active_fpu.fp_status)
1919 || float32_le_quiet(fsth0, fsth1,
1920 &env->active_fpu.fp_status))
1922 * NOTE: the comma operator will make "cond" to eval to false,
1923 * but float32_unordered() is still called.
1925 FOP_COND_PS(sf, (float32_unordered(fst1, fst0,
1926 &env->active_fpu.fp_status), 0),
1927 (float32_unordered(fsth1, fsth0,
1928 &env->active_fpu.fp_status), 0))
1929 FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
1930 &env->active_fpu.fp_status),
1931 float32_unordered(fsth1, fsth0,
1932 &env->active_fpu.fp_status))
1933 FOP_COND_PS(seq, float32_eq(fst0, fst1,
1934 &env->active_fpu.fp_status),
1935 float32_eq(fsth0, fsth1,
1936 &env->active_fpu.fp_status))
1937 FOP_COND_PS(ngl, float32_unordered(fst1, fst0,
1938 &env->active_fpu.fp_status)
1939 || float32_eq(fst0, fst1,
1940 &env->active_fpu.fp_status),
1941 float32_unordered(fsth1, fsth0,
1942 &env->active_fpu.fp_status)
1943 || float32_eq(fsth0, fsth1,
1944 &env->active_fpu.fp_status))
1945 FOP_COND_PS(lt, float32_lt(fst0, fst1,
1946 &env->active_fpu.fp_status),
1947 float32_lt(fsth0, fsth1,
1948 &env->active_fpu.fp_status))
1949 FOP_COND_PS(nge, float32_unordered(fst1, fst0,
1950 &env->active_fpu.fp_status)
1951 || float32_lt(fst0, fst1,
1952 &env->active_fpu.fp_status),
1953 float32_unordered(fsth1, fsth0,
1954 &env->active_fpu.fp_status)
1955 || float32_lt(fsth0, fsth1,
1956 &env->active_fpu.fp_status))
1957 FOP_COND_PS(le, float32_le(fst0, fst1,
1958 &env->active_fpu.fp_status),
1959 float32_le(fsth0, fsth1,
1960 &env->active_fpu.fp_status))
1961 FOP_COND_PS(ngt, float32_unordered(fst1, fst0,
1962 &env->active_fpu.fp_status)
1963 || float32_le(fst0, fst1,
1964 &env->active_fpu.fp_status),
1965 float32_unordered(fsth1, fsth0,
1966 &env->active_fpu.fp_status)
1967 || float32_le(fsth0, fsth1,
1968 &env->active_fpu.fp_status))
1970 /* R6 compare operations */
1971 #define FOP_CONDN_D(op, cond) \
1972 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1973 uint64_t fdt1) \
1975 uint64_t c; \
1976 c = cond; \
1977 update_fcr31(env, GETPC()); \
1978 if (c) { \
1979 return -1; \
1980 } else { \
1981 return 0; \
1986 * NOTE: the comma operator will make "cond" to eval to false,
1987 * but float64_unordered_quiet() is still called.
1989 FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0,
1990 &env->active_fpu.fp_status), 0))
1991 FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0,
1992 &env->active_fpu.fp_status)))
1993 FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1,
1994 &env->active_fpu.fp_status)))
1995 FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
1996 &env->active_fpu.fp_status)
1997 || float64_eq_quiet(fdt0, fdt1,
1998 &env->active_fpu.fp_status)))
1999 FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1,
2000 &env->active_fpu.fp_status)))
2001 FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
2002 &env->active_fpu.fp_status)
2003 || float64_lt_quiet(fdt0, fdt1,
2004 &env->active_fpu.fp_status)))
2005 FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1,
2006 &env->active_fpu.fp_status)))
2007 FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
2008 &env->active_fpu.fp_status)
2009 || float64_le_quiet(fdt0, fdt1,
2010 &env->active_fpu.fp_status)))
2012 * NOTE: the comma operator will make "cond" to eval to false,
2013 * but float64_unordered() is still called.\
2015 FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0,
2016 &env->active_fpu.fp_status), 0))
2017 FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0,
2018 &env->active_fpu.fp_status)))
2019 FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1,
2020 &env->active_fpu.fp_status)))
2021 FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
2022 &env->active_fpu.fp_status)
2023 || float64_eq(fdt0, fdt1,
2024 &env->active_fpu.fp_status)))
2025 FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1,
2026 &env->active_fpu.fp_status)))
2027 FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
2028 &env->active_fpu.fp_status)
2029 || float64_lt(fdt0, fdt1,
2030 &env->active_fpu.fp_status)))
2031 FOP_CONDN_D(sle, (float64_le(fdt0, fdt1,
2032 &env->active_fpu.fp_status)))
2033 FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
2034 &env->active_fpu.fp_status)
2035 || float64_le(fdt0, fdt1,
2036 &env->active_fpu.fp_status)))
2037 FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0,
2038 &env->active_fpu.fp_status)
2039 || float64_le_quiet(fdt0, fdt1,
2040 &env->active_fpu.fp_status)))
2041 FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0,
2042 &env->active_fpu.fp_status)
2043 || float64_lt_quiet(fdt1, fdt0,
2044 &env->active_fpu.fp_status)
2045 || float64_lt_quiet(fdt0, fdt1,
2046 &env->active_fpu.fp_status)))
2047 FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0,
2048 &env->active_fpu.fp_status)
2049 || float64_lt_quiet(fdt0, fdt1,
2050 &env->active_fpu.fp_status)))
2051 FOP_CONDN_D(sor, (float64_le(fdt1, fdt0,
2052 &env->active_fpu.fp_status)
2053 || float64_le(fdt0, fdt1,
2054 &env->active_fpu.fp_status)))
2055 FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
2056 &env->active_fpu.fp_status)
2057 || float64_lt(fdt1, fdt0,
2058 &env->active_fpu.fp_status)
2059 || float64_lt(fdt0, fdt1,
2060 &env->active_fpu.fp_status)))
2061 FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0,
2062 &env->active_fpu.fp_status)
2063 || float64_lt(fdt0, fdt1,
2064 &env->active_fpu.fp_status)))
2066 #define FOP_CONDN_S(op, cond) \
2067 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2068 uint32_t fst1) \
2070 uint64_t c; \
2071 c = cond; \
2072 update_fcr31(env, GETPC()); \
2073 if (c) { \
2074 return -1; \
2075 } else { \
2076 return 0; \
2081 * NOTE: the comma operator will make "cond" to eval to false,
2082 * but float32_unordered_quiet() is still called.
2084 FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0,
2085 &env->active_fpu.fp_status), 0))
2086 FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0,
2087 &env->active_fpu.fp_status)))
2088 FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1,
2089 &env->active_fpu.fp_status)))
2090 FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0,
2091 &env->active_fpu.fp_status)
2092 || float32_eq_quiet(fst0, fst1,
2093 &env->active_fpu.fp_status)))
2094 FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1,
2095 &env->active_fpu.fp_status)))
2096 FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0,
2097 &env->active_fpu.fp_status)
2098 || float32_lt_quiet(fst0, fst1,
2099 &env->active_fpu.fp_status)))
2100 FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1,
2101 &env->active_fpu.fp_status)))
2102 FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0,
2103 &env->active_fpu.fp_status)
2104 || float32_le_quiet(fst0, fst1,
2105 &env->active_fpu.fp_status)))
2107 * NOTE: the comma operator will make "cond" to eval to false,
2108 * but float32_unordered() is still called.
2110 FOP_CONDN_S(saf, (float32_unordered(fst1, fst0,
2111 &env->active_fpu.fp_status), 0))
2112 FOP_CONDN_S(sun, (float32_unordered(fst1, fst0,
2113 &env->active_fpu.fp_status)))
2114 FOP_CONDN_S(seq, (float32_eq(fst0, fst1,
2115 &env->active_fpu.fp_status)))
2116 FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
2117 &env->active_fpu.fp_status)
2118 || float32_eq(fst0, fst1,
2119 &env->active_fpu.fp_status)))
2120 FOP_CONDN_S(slt, (float32_lt(fst0, fst1,
2121 &env->active_fpu.fp_status)))
2122 FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
2123 &env->active_fpu.fp_status)
2124 || float32_lt(fst0, fst1,
2125 &env->active_fpu.fp_status)))
2126 FOP_CONDN_S(sle, (float32_le(fst0, fst1,
2127 &env->active_fpu.fp_status)))
2128 FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
2129 &env->active_fpu.fp_status)
2130 || float32_le(fst0, fst1,
2131 &env->active_fpu.fp_status)))
2132 FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0,
2133 &env->active_fpu.fp_status)
2134 || float32_le_quiet(fst0, fst1,
2135 &env->active_fpu.fp_status)))
2136 FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0,
2137 &env->active_fpu.fp_status)
2138 || float32_lt_quiet(fst1, fst0,
2139 &env->active_fpu.fp_status)
2140 || float32_lt_quiet(fst0, fst1,
2141 &env->active_fpu.fp_status)))
2142 FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0,
2143 &env->active_fpu.fp_status)
2144 || float32_lt_quiet(fst0, fst1,
2145 &env->active_fpu.fp_status)))
2146 FOP_CONDN_S(sor, (float32_le(fst1, fst0,
2147 &env->active_fpu.fp_status)
2148 || float32_le(fst0, fst1,
2149 &env->active_fpu.fp_status)))
2150 FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
2151 &env->active_fpu.fp_status)
2152 || float32_lt(fst1, fst0,
2153 &env->active_fpu.fp_status)
2154 || float32_lt(fst0, fst1,
2155 &env->active_fpu.fp_status)))
2156 FOP_CONDN_S(sne, (float32_lt(fst1, fst0,
2157 &env->active_fpu.fp_status)
2158 || float32_lt(fst0, fst1,
2159 &env->active_fpu.fp_status)))